diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 80e231b..a15f9f8 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -2,11 +2,18 @@ name: Build Desktop Artifacts on: workflow_dispatch: + inputs: + tag_name: + description: Version tag to build and publish, for example v0.0.2 + required: true + type: string + release_name: + description: Optional release title override + required: false + type: string push: tags: - 'v*' - release: - types: [published] permissions: contents: write @@ -79,7 +86,7 @@ jobs: if-no-files-found: error publish: - if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' || github.event_name == 'release' + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' needs: build runs-on: ubuntu-latest steps: @@ -95,17 +102,18 @@ jobs: - name: Compute release tag id: release_meta run: | - if [[ "${GITHUB_EVENT_NAME}" == "release" ]]; then - TAG_NAME="${{ github.event.release.tag_name }}" + if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then + TAG_NAME="${{ github.event.inputs.tag_name }}" + RELEASE_NAME="${{ github.event.inputs.release_name }}" echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT" - echo "release_name=Docs Foundry ${TAG_NAME}" >> "$GITHUB_OUTPUT" + if [[ -n "${RELEASE_NAME}" ]]; then + echo "release_name=${RELEASE_NAME}" >> "$GITHUB_OUTPUT" + else + echo "release_name=Docs Foundry ${TAG_NAME}" >> "$GITHUB_OUTPUT" + fi elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then echo "tag_name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" echo "release_name=Docs Foundry ${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" - else - TAG_NAME="manual-${GITHUB_RUN_NUMBER}" - echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT" - echo "release_name=Docs Foundry ${TAG_NAME}" >> "$GITHUB_OUTPUT" fi - name: Delete existing release if present diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 20e9d4e..cf23a5f 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -40,7 +40,7 @@ This Code of Conduct is adapted from the [Contributor Covenant](https://www.cont
- Total views + Total views

Refresh Date: 2026-04-13

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8533149..7a46785 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -82,7 +82,7 @@ Open an issue on GitHub with reproduction steps. Include OS, app version, and an
- Total views + Total views

Refresh Date: 2026-04-13

diff --git a/README.md b/README.md index 51793e8..346f199 100644 --- a/README.md +++ b/README.md @@ -10,19 +10,96 @@ Last updated: 2026-02-25 > DocFoundry is an open-source **Electron** desktop app for writing and previewing Markdown documentation with a live split-pane editor, local folder tree, safe local saves, container-only development for contributors, and installable binaries for macOS, Windows, and Linux. + +
+Table of contents + +- [What's included](#whats-included) +- [Repository tree](#project-structure) +- [Roadmap](#roadmap) +- [Mode 1: Container-only development](#mode-1-container-only-development) +- [Mode 2: End-user desktop app install](#mode-2-end-user-desktop-app-install) +- [GitHub Pages](#github-pages) +- [Pipelines included](#pipelines-included) +- [Quality & Testing](#quality--testing) + +
+ ## What's included > DocFoundry ships multi-tab editing, split-pane live preview, a command palette, workspace-wide search, in-file find and replace, a document outline, file operations (create, rename, delete), auto-save, HTML export, zen mode, resizable panes, a keyboard shortcuts overlay, a status bar (word count, reading time, cursor position), breadcrumbs, and full Markdown rendering (headings, bold/italic, lists, task lists, tables, code blocks, blockquotes, images, links, horizontal rules, strikethrough, highlight, footnotes). The app includes unsaved-change protection on close, a file watcher for external changes, native menus with keyboard accelerators, and a secure architecture (contextIsolation, no nodeIntegration, validated file paths). For the full changelog and per-version details, see [Releases](https://github.com/Cloud2BR/docs-foundry/releases). +> [!NOTE] +> Desktop releases are published when you push a `v*` tag or when you manually run `.github/workflows/release-desktop.yml` with a `tag_name` input. + +
+Expand repository tree + +```text +DocFoundry/ +├── src/ +│ ├── main.js # Electron main process (IPC, menu, file watcher) +│ ├── preload.js # Secure IPC bridge (contextBridge) +│ ├── lib/ +│ │ └── workspace-path.js # Secure path validation +│ └── renderer/ +│ ├── index.html # Desktop app shell (welcome + workspace) +│ ├── styles.css # Full UI styling +│ ├── renderer.js # Tabs, palette, search, outline, editor logic +│ └── markdown.js # Shared Markdown→HTML parser (UMD) +├── build/ +│ ├── icon.svg # App icon source +│ └── generate-icons.sh # SVG to PNG/ICO/ICNS converter +├── docs/ +│ ├── .nojekyll +│ ├── index.html # GitHub Pages overview page +│ ├── downloads.html # Download/install guide backed by GitHub Releases +│ ├── roadmap.html # Public roadmap view on GitHub Pages +│ └── feedback.html # Public feedback page routed to a separate GitHub repo +├── tests/ +│ ├── smoke.test.mjs # Structure, security, and feature-surface tests +│ ├── markdown.test.mjs # Markdown parser tests +│ └── workspace-path.test.mjs # Path validation tests +├── scripts/ +│ └── setup.sh # OS detection and Docker validation +├── .github/ +│ ├── PULL_REQUEST_TEMPLATE.md +│ ├── ISSUE_TEMPLATE/ +│ │ ├── bug_report.md +│ │ └── feature_request.md +│ └── workflows/ +│ ├── deploy-pages.yml +│ ├── release-desktop.yml +│ ├── auto-fill-pr.yml +│ ├── update-md-date.yml +│ ├── update_date.py +│ ├── use-visitor-counter.yml +│ └── cleanup-pages-history.yml +├── Dockerfile.dev # Container dev image (node:20-bookworm) +├── Makefile # setup, dev, lint, format, test, package targets +├── vitest.config.mjs # Vitest configuration +├── eslint.config.mjs # ESLint flat config (v9+) +├── .prettierrc # Prettier configuration +├── CONTRIBUTING.md +├── CODE_OF_CONDUCT.md +├── SECURITY.md +├── LICENSE +└── README.md +``` + +
+ ## Roadmap -> Git change indicators and diff view, broken-link checks and link autocomplete, PDF export, scroll sync between editor and preview, drag-and-drop file and image support, Mermaid diagram rendering, spell check. +Live roadmap page: [Docs Foundry Roadmap](https://cloud2br.github.io/docs-foundry/roadmap.html) +Product feedback page: [Docs Foundry Feedback](https://cloud2br.github.io/docs-foundry/feedback.html) -## Two operating modes +> [!IMPORTANT] +> The feedback page prepopulates requests in the GitHub Pages UI and routes them into [Cloud2BR/docs-foundry-feedback](https://github.com/Cloud2BR/docs-foundry-feedback). The production flow opens a prefilled issue there and lets that repo process it with a GitHub Actions intake workflow after submission. -### Mode 1: Container-only development +## Mode 1: Container-only development > This mode is for maintainers and contributors who do not want local Node.js or npm installation. @@ -42,7 +119,7 @@ For the full changelog and per-version details, see [Releases](https://github.co - Builds the dev image. - Installs project dependencies only inside the container. -### Mode 2: End-user desktop app install +## Mode 2: End-user desktop app install > This mode is for users who just want to install and run DocFoundry. @@ -50,39 +127,15 @@ For the full changelog and per-version details, see [Releases](https://github.co - Windows outputs: `NSIS installer`, `.zip` - Linux outputs: `AppImage`, `.deb`, `.tar.gz` -Build artifacts go to `release/`. - -#### macOS — "damaged and can't be opened" (Gatekeeper) - -DocFoundry is unsigned (no Apple Developer certificate). Use the `.dmg` first when downloading from GitHub Releases. macOS quarantines apps downloaded from the internet. If you open the `.zip` build and macOS blocks it, run this once after downloading: - -```bash -xattr -cr /Applications/DocFoundry.app -``` - -Or if you extracted from the ZIP before moving to Applications: - -```bash -xattr -cr /path/to/DocFoundry.app -``` - -Then double-click the app normally. - -#### Windows — SmartScreen warning - -Click **More info → Run anyway** on the SmartScreen prompt. This appears because the installer is not signed with a code-signing certificate. +Build artifacts go to [`release/`](https://github.com/Cloud2BR/docs-foundry/releases) -## Build binaries +| Platform | Release files | Recommended install path | First-run notes | Build command | +|---|---|---|---|---| +| macOS | `.dmg`, `.zip` | Download the `.dmg` from GitHub Releases and drag `DocFoundry.app` into `Applications`. Use the `.zip` only as a fallback. | The app is unsigned, so Gatekeeper may block the ZIP build. If macOS says the app is damaged, run `xattr -cr /Applications/DocFoundry.app` after moving it to `Applications`, or run `xattr -cr /path/to/DocFoundry.app` on the extracted app bundle before opening it. | `make package-mac` | +| Windows | `NSIS installer`, `.zip` | Use the NSIS installer for the normal install flow. Use the ZIP when you want a manual or portable-style extraction. | Windows SmartScreen may show a warning because the installer is not code-signed. Click **More info → Run anyway** to continue. | `make package-win` | +| Linux | `AppImage`, `.deb`, `.tar.gz` | Use the package format that matches your environment: `AppImage` for portable use, `.deb` for Debian/Ubuntu installs, or `.tar.gz` for manual extraction. | `AppImage` usually needs `chmod +x` before running. For `.deb`, install with `sudo apt install ./DocFoundry.deb` or the generated filename in `release/`. Linux packaging is intended to run from the container workflow. | `make package-linux` | -### From host machine - -- make package -- make package-mac -- make package-win - -### Linux package build from container - -- make package-linux +For a local multi-platform packaging pass from a compatible host environment, use `make package`. ## GitHub Pages @@ -97,64 +150,14 @@ This repo includes a Pages workflow in `.github/workflows/deploy-pages.yml` and ## Pipelines included - `.github/workflows/deploy-pages.yml`: deploys GitHub Pages. -- `.github/workflows/release-desktop.yml`: builds desktop binaries on macOS, Windows, Linux and publishes on tags. +- `.github/workflows/release-desktop.yml`: builds desktop binaries on macOS, Windows, Linux and publishes a tagged GitHub Release on `v*` tags or manual dispatch with `tag_name`. - `.github/workflows/update-md-date.yml`: updates README date automatically. - `.github/workflows/use-visitor-counter.yml`: updates README visitor badge. - `.github/workflows/cleanup-pages-history.yml`: cleans old Pages workflow runs. -## Project structure - -``` -DocFoundry/ -├── src/ -│ ├── main.js # Electron main process (IPC, menu, file watcher) -│ ├── preload.js # Secure IPC bridge (contextBridge) -│ ├── lib/ -│ │ └── workspace-path.js # Secure path validation -│ └── renderer/ -│ ├── index.html # Desktop app shell (welcome + workspace) -│ ├── styles.css # Full UI styling -│ ├── renderer.js # Tabs, palette, search, outline, editor logic -│ └── markdown.js # Shared Markdown→HTML parser (UMD) -├── build/ -│ ├── icon.svg # App icon source -│ └── generate-icons.sh # SVG → PNG/ICO/ICNS converter -├── tests/ -│ ├── smoke.test.mjs # Structure, security & feature-surface tests -│ ├── markdown.test.mjs # Markdown parser tests -│ └── workspace-path.test.mjs # Path validation tests -├── docs/ -│ └── index.html # GitHub Pages landing & download page -├── scripts/ -│ └── setup.sh # OS detection & Docker validation -├── .github/ -│ ├── PULL_REQUEST_TEMPLATE.md -│ ├── ISSUE_TEMPLATE/ -│ │ ├── bug_report.md -│ │ └── feature_request.md -│ └── workflows/ -│ ├── deploy-pages.yml -│ ├── release-desktop.yml -│ ├── auto-fill-pr.yml -│ ├── update-md-date.yml -│ ├── update_date.py -│ ├── use-visitor-counter.yml -│ └── cleanup-pages-history.yml -├── Dockerfile.dev # Container dev image (node:20-bookworm) -├── Makefile # setup, dev, lint, format, test, package targets -├── vitest.config.mjs # Vitest configuration -├── eslint.config.mjs # ESLint flat config (v9+) -├── .prettierrc # Prettier configuration -├── CONTRIBUTING.md -├── CODE_OF_CONDUCT.md -├── SECURITY.md -├── LICENSE -└── README.md -``` - ## Quality & Testing -Run code quality checks and tests inside the container: +> Run code quality checks and tests inside the container: ``` make lint # ESLint @@ -164,7 +167,7 @@ make test # Vitest
- Total views + Total views

Refresh Date: 2026-04-13

diff --git a/SECURITY.md b/SECURITY.md index b8f7b8c..46c31be 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -37,7 +37,7 @@ If you discover a security vulnerability in DocFoundry, please report it respons
- Total views + Total views

Refresh Date: 2026-04-13

diff --git a/docs/downloads.html b/docs/downloads.html new file mode 100644 index 0000000..107d1d6 --- /dev/null +++ b/docs/downloads.html @@ -0,0 +1,729 @@ + + + + + + + + Docs Foundry Downloads + + + + + + + +
+
+
+
+

Docs Foundry downloads

+

Install and Use Docs Foundry

+

+ This page keeps the download flow inside GitHub Pages. It shows the latest + published release artifacts, explains how to install them, and gives the + first-run steps for macOS, Windows, and Linux. +

+ +
+ +
+
+
+ +
+
+
+ + +
+ +
+
+

Artifacts

+

Choose your platform

+

+ Each card shows the preferred download first, then the remaining release files + for that platform. Installation notes stay with the relevant operating system. +

+
+
+
+
+ +
+

macOS

+

DMG first, ZIP fallback

+
+
+

+ Best for end users who want the normal drag-to-Applications install flow. +

+
+

Waiting for release assets…

+
+

+ Gatekeeper: install from the .dmg when possible. + If the ZIP build is blocked, run xattr -cr /path/to/DocFoundry.app + once, then reopen it. +

+
+ +
+
+ +
+

Windows

+

NSIS installer first, ZIP fallback

+
+
+

+ Best for Windows users who want a standard installer or a portable ZIP option. +

+
+

Waiting for release assets…

+
+

+ SmartScreen: if Windows shows a warning, click + More info and then Run anyway because the + installer is not code-signed yet. +

+
+ +
+
+ +
+

Linux

+

AppImage, DEB, or TAR.GZ

+
+
+

+ Choose the package style that matches your distro and whether you want a portable build. +

+
+

Waiting for release assets…

+
+

+ Linux tip: AppImage builds usually need chmod +x + before running. DEB builds install cleanly with sudo apt install ./file.deb. +

+
+
+
+ +
+
+

Install guide

+

How to download, install, and use it

+
+
+
+

macOS

+
    +
  1. Download the latest DMG from the macOS card.
  2. +
  3. Open the disk image and drag DocFoundry.app into Applications.
  4. +
  5. If you used the ZIP build and macOS blocks it, run xattr -cr /path/to/DocFoundry.app.
  6. +
  7. Launch the app and open a local documentation folder to start writing.
  8. +
+
+
+

Windows

+
    +
  1. Download the Setup EXE from the Windows card.
  2. +
  3. Run the installer and continue through the normal install wizard.
  4. +
  5. If SmartScreen appears, choose More info and then Run anyway.
  6. +
  7. Start Docs Foundry and open your docs workspace from the sidebar.
  8. +
+
+
+

Linux

+
    +
  1. Choose the artifact that fits your system: AppImage, DEB, or TAR.GZ.
  2. +
  3. For AppImage, run chmod +x DocFoundry.AppImage and open it.
  4. +
  5. For DEB, install with sudo apt install ./file.deb.
  6. +
  7. Launch the app and select a local docs folder to begin editing.
  8. +
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/feedback.html b/docs/feedback.html new file mode 100644 index 0000000..04d0898 --- /dev/null +++ b/docs/feedback.html @@ -0,0 +1,648 @@ + + + + + + + + Docs Foundry Feedback + + + + + + + +
+
+
+
+

Docs Foundry feedback

+

Send requests without touching the main repo

+

+ This page routes feature requests and improvement ideas through the Docs Foundry feedback + flow backed by Cloud2BR/docs-foundry-feedback. + Submissions do not create commits, branches, or pull requests in the main Docs Foundry + repository, so product feedback stays organized without disrupting source or release work. +

+ +
+ +
+
+
+ +
+
+
+
+

Destination

+

Feedback is stored in one dedicated repo

+

+ All feedback from this page is routed into the Docs Foundry feedback flow backed by + Cloud2BR/docs-foundry-feedback. That keeps product + requests separate from the main source repository and avoids any code-branch or + pull-request disruption when people submit feedback. +

+
+
+

Configured destination

+
Feedback repo: https://github.com/Cloud2BR/docs-foundry-feedback/issues
+

Delivery mode: GitHub-native intake. Send feedback opens a prefilled issue in the feedback repo, and that repo processes it with an issues.opened GitHub Actions workflow.

+ +
+
+ +
+
+

Submit feedback

+

What do you want to add or improve?

+

+ Fill out the request here in the GitHub Pages UI. Send feedback opens a prefilled + issue in the feedback repo, and that repo runs its GitHub Actions intake workflow + as soon as the issue is submitted. +

+
+ +
+ +
+
+

Why this flow

+

What this setup solves

+
+
+
+

Main repo stays clean

+

Requests are stored as issues in a separate feedback repo instead of mixing product feedback into the source repository.

+
+
+

No source-repo conflicts

+

Submissions create records in the feedback flow only, so they do not create commits, branches, or pull requests in the main Docs Foundry repository.

+
+
+

Easy to review later

+

You can triage, label, close, or convert requests into roadmap items without cluttering the engineering branch history.

+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index c345cee..5231d9e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -129,6 +129,47 @@ height: 18px; border-radius: 999px; } + .hero-control-panel { + margin-top: 18px; + padding: 14px 16px; + border: 1px solid color-mix(in oklab, var(--hero-fg) 14%, transparent); + border-radius: var(--radius-lg); + background: color-mix(in oklab, var(--hero-fg) 8%, transparent); + } + .hero-control-label { + margin: 0 0 10px; + font-size: 0.74rem; + text-transform: uppercase; + letter-spacing: 0.14em; + color: var(--hero-muted); + } + .hero-control-links { + display: flex; + gap: 10px; + flex-wrap: wrap; + } + .hero-control-link { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 8px 14px; + border: 1px solid color-mix(in oklab, var(--hero-fg) 16%, transparent); + border-radius: var(--radius); + background: color-mix(in oklab, var(--hero-fg) 10%, transparent); + color: var(--hero-fg); + text-decoration: none; + font-weight: 500; + font-size: 0.85rem; + transition: border-color 140ms ease, background 140ms ease; + } + .hero-control-link:hover { + border-color: color-mix(in oklab, var(--hero-fg) 32%, transparent); + background: color-mix(in oklab, var(--hero-fg) 16%, transparent); + } + .hero-control-link:focus-visible { + outline: 2px solid #ffffff; + outline-offset: 3px; + } .theme-toggle { padding: 8px 12px; border: 1px solid var(--hero-border); @@ -172,42 +213,117 @@ } /* ── Capability list ── */ - .capability-list { + .story-shell { display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: 0; + grid-template-columns: minmax(0, 1.15fr) minmax(300px, 0.85fr); + gap: 24px; + align-items: start; + margin-bottom: 24px; } - .capability-item { - display: flex; + .story-intro { + border: 1px solid var(--border); + border-radius: var(--radius-lg); + background: linear-gradient(180deg, var(--card), color-mix(in oklab, var(--surface) 38%, var(--card))); + padding: 22px 24px; + } + .story-copy { + margin: 0; + max-width: none; + font-size: 1rem; + } + .story-emphasis { + margin: 18px 0 0; + padding-top: 18px; + border-top: 1px solid var(--border); + color: var(--fg); + font-size: 0.98rem; + line-height: 1.7; + } + .story-rail { + position: relative; + display: grid; + gap: 18px; + padding-left: 18px; + } + .story-rail::before { + content: ""; + position: absolute; + left: 4px; + top: 8px; + bottom: 8px; + width: 1px; + background: color-mix(in oklab, var(--link) 35%, var(--border)); + } + .story-step { + display: grid; + grid-template-columns: 52px minmax(0, 1fr); gap: 14px; - align-items: flex-start; - padding: 16px 0; - border-bottom: 1px solid var(--border); + align-items: start; + } + .story-step-number { + position: relative; + z-index: 1; + width: 40px; + height: 40px; + border-radius: 999px; + display: inline-flex; + align-items: center; + justify-content: center; + background: var(--card); + border: 1px solid color-mix(in oklab, var(--link) 18%, var(--border)); + color: var(--link); + font-weight: 700; + font-size: 0.88rem; + box-shadow: 0 8px 18px color-mix(in oklab, var(--link) 10%, transparent); } - .capability-item:nth-last-child(-n+2) { - border-bottom: none; + .story-step h3 { + margin: 2px 0 6px; + font-family: "Space Grotesk", sans-serif; + font-size: 1.02rem; } - /* Remove bottom border on last item in each column for even grids */ - @media (min-width: 640px) { - .capability-item:nth-last-child(-n+2) { border-bottom: none; } + .story-step p { + margin: 0; + color: var(--muted); + font-size: 0.92rem; + line-height: 1.58; } - .capability-icon { - font-size: 1.4rem; - flex-shrink: 0; - width: 28px; - text-align: center; - margin-top: 2px; + .capability-ledger { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + background: var(--card); + overflow: hidden; + } + .ledger-item { + padding: 20px 22px; + min-width: 0; + background: linear-gradient(180deg, color-mix(in oklab, var(--card) 96%, var(--surface)), var(--card)); + } + .ledger-item:nth-child(odd) { + border-right: 1px solid var(--border); } - .capability-text strong { + .ledger-item:nth-child(n+3) { + border-top: 1px solid var(--border); + } + .ledger-kicker { + display: inline-block; + margin-bottom: 8px; + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--muted); + } + .ledger-item strong { display: block; - font-size: 0.95rem; - margin-bottom: 3px; + font-size: 1rem; + margin-bottom: 6px; } - .capability-text p { + .ledger-item p { margin: 0; color: var(--muted); - font-size: 0.88rem; - line-height: 1.5; + font-size: 0.92rem; + line-height: 1.58; } /* ── Getting started steps ── */ @@ -279,10 +395,28 @@ outline-offset: 3px; } .platform-card .platform-icon { - font-size: 2.2rem; - margin-bottom: 10px; + width: 48px; + height: 48px; + margin: 0 auto 12px; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--fg); + } + .platform-card .platform-icon svg { + width: 100%; + height: 100%; display: block; } + .platform-icon--macos { + color: #111111; + } + .platform-icon--windows { + color: #0f6cbd; + } + .platform-icon--linux { + color: #111111; + } .platform-card h3 { margin: 0 0 4px; font-size: 1.05rem; @@ -305,37 +439,25 @@ font-size: 0.88rem; pointer-events: none; /* card itself is the link */ } - .download-row { - margin-top: 16px; - display: flex; - gap: 10px; - justify-content: center; - flex-wrap: wrap; + .platform-note { + margin: 14px 0 0; + padding: 10px 12px; + border-radius: 12px; + background: color-mix(in oklab, var(--surface) 72%, var(--card)); + color: var(--muted); + font-size: 0.8rem; + line-height: 1.5; + text-align: left; } - .download-link-secondary { - display: inline-flex; - align-items: center; - gap: 4px; - padding: 8px 14px; - border: 1px solid var(--border); - border-radius: var(--radius); - background: var(--surface2); + .platform-note strong { color: var(--fg); - text-decoration: none; - font-weight: 500; - font-size: 0.85rem; - cursor: pointer; - transition: border-color 140ms ease, background 140ms ease; } - .download-link-secondary:hover { - border-color: var(--link); - background: var(--surface); - } - .download-link-secondary:focus-visible { - outline: 2px solid var(--link); - outline-offset: 3px; + .platform-note code { + background: color-mix(in oklab, var(--surface2) 80%, var(--card)); + padding: 2px 6px; + border-radius: 6px; + font-size: 0.9em; } - /* ── Identity section (from Azure-Capacity-Overview) ── */ .identity-section { padding: 36px 0 42px; @@ -347,6 +469,20 @@ max-width: 70ch; margin: 6px 0 0; } + .identity-chip { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 6px 10px; + border-radius: 999px; + background: color-mix(in oklab, var(--link) 12%, var(--card)); + color: var(--link); + font-size: 0.76rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 10px; + } .identity-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); @@ -434,14 +570,23 @@ /* ── Responsive ── */ @media (max-width: 768px) { + .story-shell { grid-template-columns: 1fr; } + .capability-ledger { grid-template-columns: 1fr; } + .ledger-item:nth-child(odd) { border-right: 0; } + .ledger-item:nth-child(n+3) { border-top: 0; } + .ledger-item + .ledger-item { border-top: 1px solid var(--border); } .platform-grid { grid-template-columns: 1fr; } .identity-grid { grid-template-columns: 1fr; } .hero h1 { font-size: 1.8rem; } } + @media (min-width: 769px) and (max-width: 1040px) { + .story-shell { grid-template-columns: 1fr; } + } + @media (prefers-reduced-motion: reduce) { a.platform-card, - .download-link-secondary { transition: none; } + .hero-control-link { transition: none; } a.platform-card:hover { transform: none; } } @@ -469,10 +614,21 @@

Docs Foundry

Build Desktop Artifacts status - Total views + Total views +
+

Quick links

+ +
@@ -482,37 +638,135 @@

Docs Foundry

Getting started

What is Docs Foundry?

+
+
+

+ Docs Foundry is an open-source desktop application for writing, editing, and + previewing Markdown documentation. Think of it as a lightweight, local-first + docs workspace built specifically for documentation projects rather than a + general-purpose IDE. +

+

+ Built for documentation rather than IDE sprawl: open a docs folder, write in + Markdown, review the rendered result beside the editor, and package the same + project for distribution without extra local setup. +

+
+ +
+
+ 01 +
+

Bring your own docs

+

Work directly from your repository or documentation folder with a local-first workspace instead of a hosted editing surface.

+
+
+
+ 02 +
+

Write with immediate feedback

+

Draft in Markdown while the rendered preview stays beside the editor so structure, formatting, and content stay aligned.

+
+
+
+ 03 +
+

Distribute like a product

+

Package the same workspace into native installers for macOS, Windows, and Linux without reworking the project around a separate toolchain.

+
+
+
+
+ +
+
+ Authoring + Markdown editor +

Distraction-free monospace editing with fast save, unsaved-change tracking, and a workspace built around docs instead of code noise.

+
+
+ Preview + Live preview +

See Markdown render in real time with headings, lists, code blocks, tables, and the formatting details that matter while writing.

+
+
+ Navigation + Sidebar file tree +

Open a docs folder and move through its structure quickly, keeping related Markdown, assets, and project files in one place.

+
+
+ Contributing + Container-first development +

No local Node.js required. Run make setup and contributors get the same Docker-based environment with project dependencies inside the container.

+
+
+ Distribution + Cross-platform installers +

Ship native DMG, NSIS, AppImage, and DEB outputs so people can install the app without building from source.

+
+
+ Maintenance + Auto-update path +

Packaged builds can check GitHub Releases for updates through electron-updater, which keeps distributed installs easier to maintain.

+
+
+
+ + + +
+
+

For end users

+

Download Docs Foundry

- Docs Foundry is an open-source desktop application for writing, editing, and - previewing Markdown documentation. Think of it as a lightweight, local-first - docs workspace, purpose-built for documentation projects. + Grab the latest installer for your operating system. Builds are published + automatically to GitHub Releases when a new version tag is pushed or when + the release workflow is run manually with a tag name.

-
-
- 📝 -
Markdown editor

Distraction-free monospace editor with Ctrl+S save and unsaved-change tracking.

-
-
- 👁️ -
Live preview

Split-pane Markdown rendering in real time — headings, bold, code blocks, lists, and more.

-
-
- 📂 -
Sidebar file tree

Open any folder and navigate its full directory structure up to 8 levels deep.

-
-
- 🐳 -
Container-first dev

No local Node.js needed. Run make setup to build a Docker container with all deps.

-
-
- 📦 -
Cross-platform installers

Native DMG, NSIS, AppImage, and DEB packages built automatically via GitHub Actions.

-
-
- 🔄 -
Auto-update

Packaged builds silently check GitHub Releases for updates via electron-updater.

-
+
@@ -554,66 +808,21 @@

Quick start

- -
-
-

For end users

-

Download Docs Foundry

-

- Grab the latest installer for your operating system. Builds are published - automatically to GitHub Releases when a new version tag is pushed. -

- - - - - -

- On macOS, use the .dmg first. If you open the .zip - app bundle and macOS says the app is damaged, run - xattr -cr /path/to/DocFoundry.app once and reopen it. -

-
-
-

Project identity

-

Owner and organization

+

Owner / Organization

- Maintained by the founder and published under Cloud2BR as an open-source - GitHub Pages experience. + Docs Foundry v0.0.1 is presented as an open-source desktop release maintained + by the owner and published through the Cloud2BR organization.

-

Owner / Founder

+

Owner

Owner and organization Cloud2BR

- Open-source tools and community assets published under the Cloud2BR organization. + Cloud2BR is the publishing organization behind the site, release assets, and + open-source project distribution.

-
-

Project context

+
+ v0.0.1 release +

Release context

    -
  • Format: Electron desktop app (HTML, CSS, JS)
  • -
  • Hosting: GitHub Pages for this site, GitHub Releases for binaries
  • -
  • Dev workflow: Container-only (Docker + Makefile)
  • -
  • Purpose: Local-first Markdown documentation workspace
  • +
  • Product: Electron desktop documentation workspace
  • +
  • Release channel: GitHub Releases with tagged binaries and installers
  • +
  • Presentation: GitHub Pages landing site for downloads and project overview
  • +
  • Scope: Initial public release for macOS, Windows, and Linux
diff --git a/docs/roadmap.html b/docs/roadmap.html new file mode 100644 index 0000000..9fab718 --- /dev/null +++ b/docs/roadmap.html @@ -0,0 +1,401 @@ + + + + + + + + Docs Foundry Roadmap + + + + + + + +
+
+
+
+

Docs Foundry roadmap

+

v0.0.1 Roadmap and Release Progress

+

+ This GitHub Pages view keeps shipped work separate from upcoming work and presents + the forward plan with ETA-style product signals, similar to how many ISVs present a + public roadmap. +

+ +
+ +
+
+
+ +
+
+
+
+

Already in v0.0.1

+

Shipped and validated

+

+ These capabilities are now part of the current DocFoundry desktop experience and should + no longer be treated as roadmap-only items. +

+
+
+
+ Editor workflow + Git-aware writing flow +

Git change indicators, per-file diff view, synchronized preview scrolling, and drag-and-drop asset insertion now support the core editing workflow.

+
+
+ Docs intelligence + Safer link and content handling +

Broken-link checks, link autocomplete, and native spell check now help catch documentation issues earlier during authoring.

+
+
+ Output formats + Richer preview and export +

PDF export and locally bundled Mermaid rendering extend the app beyond plain Markdown preview into shareable and diagram-aware documentation workflows.

+
+
+
+ +
+
+

Product roadmap

+

ETA for upcoming features

+

+ This forward-looking roadmap keeps the shipped work above and uses ETA-style windows + for the next feature areas people can expect to see evolve. +

+
+
+
+ ETA: Apr-May 2026 +

Publishing workflow

+

These items extend DocFoundry beyond editing into fuller documentation publishing and release packaging flows.

+
    +
  • Export profiles for HTML, PDF, and release bundles
  • +
  • Customizable document templates
  • +
  • Release-ready packaging notes per output format
  • +
+
+
+ ETA: May 2026 +

Workspace intelligence

+

These features deepen the current authoring flow by helping users reason about structure, references, and document quality at scale.

+
    +
  • Document diagnostics panel with grouped issues
  • +
  • Reference explorer for links, images, and footnotes
  • +
  • Workspace-level content quality reports
  • +
+
+
+ ETA: Jun 2026 +

Team collaboration

+

These items move the product closer to shared documentation workflows without turning it into a full IDE.

+
    +
  • Shared review annotations
  • +
  • Comment-ready export output
  • +
  • Improved Git workflow summaries across a workspace
  • +
+
+
+ ETA: Ongoing +

Public roadmap maintenance

+

The roadmap should stay current, release-aware, and transparent as new features ship and priorities shift.

+
    +
  • Link roadmap items to future releases
  • +
  • Highlight recently shipped features
  • +
  • Group work by release milestone
  • +
+
+
+ +
+ +
+
+

Feedback channel

+

Tell us what to add or improve

+

+ The feedback flow is designed so requests can be saved as GitHub issues in a separate + feedback repo instead of landing in the main source repository. That keeps product + requests visible without blocking release work or protected branches. +

+
+
+
+ Features + Request something new +

Send a feature request for a capability, workflow, integration, or platform improvement.

+
+
+ Improvements + Refine what exists +

Submit improvements for current workflows such as exports, navigation, preview quality, or packaging.

+
+
+ Docs & roadmap + Improve communication +

Share onboarding gaps, documentation fixes, roadmap feedback, and prioritization suggestions.

+
+
+ +
+
+
+ + + + \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index b633a2f..bab2d4a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -14,6 +14,10 @@ export default [ localStorage: 'readonly', CSS: 'readonly', console: 'readonly', + setTimeout: 'readonly', + clearTimeout: 'readonly', + queueMicrotask: 'readonly', + URL: 'readonly', // node require: 'readonly', module: 'readonly', diff --git a/metrics.json b/metrics.json index 8963073..61c28be 100644 --- a/metrics.json +++ b/metrics.json @@ -66,12 +66,17 @@ }, { "date": "2026-04-11", - "count": 2, - "uniques": 2 + "count": 0, + "uniques": 0 }, { "date": "2026-04-12", - "count": 1, - "uniques": 1 + "count": 0, + "uniques": 0 + }, + { + "date": "2026-04-13", + "count": 0, + "uniques": 0 } ] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2772e41..2c251b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.1", "license": "MIT", "dependencies": { - "electron-updater": "^6.3.0" + "electron-updater": "^6.3.0", + "mermaid": "^10.9.1" }, "devDependencies": { "electron": "^35.0.0", @@ -20,6 +21,12 @@ "vitest": "^3.0.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==", + "license": "MIT" + }, "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -1606,11 +1613,31 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, "node_modules/@types/debug": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", - "dev": true, "license": "MIT", "dependencies": { "@types/ms": "*" @@ -1664,11 +1691,19 @@ "@types/node": "*" } }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, "license": "MIT" }, "node_modules/@types/node": { @@ -1703,6 +1738,19 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/@types/verror": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", @@ -2541,6 +2589,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/check-error": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", @@ -2798,6 +2856,15 @@ "dev": true, "license": "MIT" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", @@ -2853,222 +2920,749 @@ "node": ">= 8" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/cytoscape": { + "version": "3.33.2", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.2.tgz", + "integrity": "sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw==", "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=0.10" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", "license": "MIT", "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" + "cose-base": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "cytoscape": "^3.2.0" } }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=12" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "license": "MIT", + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "d3-path": "1 - 3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "license": "MIT", + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", "dependencies": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/dir-compare/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "dev": true, - "license": "MIT", + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "delaunator": "5" + }, + "engines": { + "node": ">=12" } }, - "node_modules/dir-compare/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "d3-dispatch": "1 - 3", + "d3-selection": "3" }, "engines": { - "node": "*" + "node": ">=12" } }, - "node_modules/dmg-builder": { - "version": "24.13.3", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz", - "integrity": "sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==", - "dev": true, - "license": "MIT", + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", "dependencies": { - "app-builder-lib": "24.13.3", - "builder-util": "24.13.1", - "builder-util-runtime": "9.2.4", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" }, - "optionalDependencies": { - "dmg-license": "^1.0.11" + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" } }, - "node_modules/dmg-builder/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "d3-dsv": "1 - 3" }, "engines": { "node": ">=12" } }, - "node_modules/dmg-builder/node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "dev": true, - "license": "MIT", + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", "dependencies": { - "universalify": "^2.0.0" + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=12" } }, - "node_modules/dmg-builder/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz", + "integrity": "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-compare": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal": "^1.0.0", + "minimatch": "^3.0.4" + } + }, + "node_modules/dir-compare/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dmg-builder": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz", + "integrity": "sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "24.13.3", + "builder-util": "24.13.1", + "builder-util-runtime": "9.2.4", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" + }, + "optionalDependencies": { + "dmg-license": "^1.0.11" + } + }, + "node_modules/dmg-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dmg-builder/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -3100,6 +3694,15 @@ "node": ">=8" } }, + "node_modules/dompurify": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz", + "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/dotenv": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", @@ -3434,6 +4037,12 @@ "node": ">= 10.0.0" } }, + "node_modules/elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==", + "license": "EPL-2.0" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4444,7 +5053,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -4530,6 +5138,15 @@ "dev": true, "license": "ISC" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4732,6 +5349,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.45", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.45.tgz", + "integrity": "sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -4742,6 +5384,26 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", @@ -4835,130 +5497,643 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true, "license": "MIT", - "peer": true + "peer": true + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mermaid": { + "version": "10.9.5", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.5.tgz", + "integrity": "sha512-eRlKEjzak4z1rcXeCd1OAlyawhrptClQDo8OuI8n6bSVqJ9oMfd5Lrf3Q+TdJHewi/9AIOc3UmEo8Fz+kNzzuQ==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.28.1", + "cytoscape-cose-bilkent": "^4.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.13", + "dayjs": "^1.11.7", + "dompurify": "^3.2.4", + "elkjs": "^0.9.0", + "katex": "^0.16.9", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", - "dev": true, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "peer": true + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } }, - "node_modules/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "license": "MIT" + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "peer": true + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "license": "MIT" + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "peer": true + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT" }, - "node_modules/lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT" }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "micromark-util-types": "^1.0.0" } }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "optional": true, "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/math-intrinsics": { + "node_modules/micromark-util-subtokenize": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" } }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -5078,6 +6253,15 @@ "node": ">=10" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5118,6 +6302,12 @@ "license": "MIT", "optional": true }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==", + "license": "MIT" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5603,6 +6793,12 @@ "node": ">=8.0" } }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "license": "Unlicense" + }, "node_modules/rollup": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", @@ -5648,6 +6844,24 @@ "fsevents": "~2.3.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5674,7 +6888,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT" }, "node_modules/sanitize-filename": { @@ -5986,6 +7199,12 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -6239,6 +7458,15 @@ "utf8-byte-length": "^1.0.1" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6287,6 +7515,19 @@ "dev": true, "license": "MIT" }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -6322,6 +7563,37 @@ "license": "MIT", "peer": true }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/verror": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", @@ -6553,6 +7825,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/web-worker": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", + "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", + "license": "Apache-2.0" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 2e0e922..50a41a1 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,8 @@ } }, "dependencies": { - "electron-updater": "^6.3.0" + "electron-updater": "^6.3.0", + "mermaid": "^10.9.1" }, "devDependencies": { "electron": "^35.0.0", diff --git a/src/lib/workspace-path.js b/src/lib/workspace-path.js index 12e7fb0..7746589 100644 --- a/src/lib/workspace-path.js +++ b/src/lib/workspace-path.js @@ -1,9 +1,19 @@ const path = require('path'); const fs = require('fs'); -const INVALID_NAME_CHARS = /[\x00-\x1f<>:"|?*]/; +const INVALID_NAME_CHARS = /[<>:"|?*]/; const WINDOWS_RESERVED = /^(con|prn|aux|nul|com\d|lpt\d)$/i; +function hasControlCharacters(value) { + for (const character of value) { + const codePoint = character.codePointAt(0); + if (typeof codePoint === 'number' && codePoint <= 31) { + return true; + } + } + return false; +} + function resolveWorkspacePath(workspaceRoot, candidatePath) { const resolvedPath = path.resolve(candidatePath); if (!workspaceRoot) return resolvedPath; @@ -53,7 +63,7 @@ function validateFileName(name) { if (trimmed !== name || trimmed.endsWith('.') || trimmed.endsWith(' ')) { throw new Error('File name has invalid leading/trailing characters'); } - if (INVALID_NAME_CHARS.test(trimmed)) { + if (hasControlCharacters(trimmed) || INVALID_NAME_CHARS.test(trimmed)) { throw new Error('File name contains invalid characters'); } if (trimmed.includes('/') || trimmed.includes('\\')) { diff --git a/src/main.js b/src/main.js index b65c1ea..eb78c75 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,8 @@ const { app, BrowserWindow, ipcMain, dialog, Menu } = require('electron'); const path = require('path'); const fs = require('fs'); +const os = require('os'); +const { execFileSync } = require('child_process'); const { resolveWorkspacePath, validateFileName } = require('./lib/workspace-path'); // Hot reload in development @@ -21,6 +23,16 @@ let hasUnsavedChanges = false; let allowWindowClose = false; let fileWatcher = null; +function hasControlCharacters(value) { + for (const character of value) { + const codePoint = character.codePointAt(0); + if (typeof codePoint === 'number' && codePoint <= 31) { + return true; + } + } + return false; +} + function createWindow() { allowWindowClose = false; hasUnsavedChanges = false; @@ -36,7 +48,8 @@ function createWindow() { webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, - nodeIntegration: false + nodeIntegration: false, + spellcheck: true } }); @@ -70,6 +83,7 @@ function buildAppMenu() { { type: 'separator' }, { label: 'Save', accelerator: 'CmdOrCtrl+S', click: () => mainWindow.webContents.send('menu-save') }, { label: 'Export HTML…', accelerator: 'CmdOrCtrl+Shift+E', click: () => mainWindow.webContents.send('menu-export-html') }, + { label: 'Export PDF…', accelerator: 'CmdOrCtrl+Shift+P', click: () => mainWindow.webContents.send('menu-export-pdf') }, { type: 'separator' }, isMac ? { role: 'close' } : { role: 'quit' } ] @@ -93,6 +107,8 @@ function buildAppMenu() { submenu: [ { label: 'Command Palette…', accelerator: 'CmdOrCtrl+P', click: () => mainWindow.webContents.send('menu-command-palette') }, { label: 'Workspace Search…', accelerator: 'CmdOrCtrl+Shift+F', click: () => mainWindow.webContents.send('menu-workspace-search') }, + { label: 'Git Diff…', accelerator: 'CmdOrCtrl+Shift+D', click: () => mainWindow.webContents.send('menu-git-diff') }, + { label: 'Check Broken Links…', accelerator: 'CmdOrCtrl+Shift+L', click: () => mainWindow.webContents.send('menu-check-links') }, { type: 'separator' }, { label: 'Toggle Sidebar', accelerator: 'CmdOrCtrl+B', click: () => mainWindow.webContents.send('menu-toggle-sidebar') }, { label: 'Toggle Outline', accelerator: 'CmdOrCtrl+Shift+O', click: () => mainWindow.webContents.send('menu-toggle-outline') }, @@ -366,6 +382,110 @@ ipcMain.handle('export-html', async (_event, htmlContent, suggestedName) => { return true; }); +ipcMain.handle('export-pdf', async (_event, htmlContent, suggestedName) => { + if (!mainWindow) return false; + + const result = await dialog.showSaveDialog(mainWindow, { + title: 'Export PDF', + defaultPath: suggestedName || 'document.pdf', + filters: [{ name: 'PDF Files', extensions: ['pdf'] }] + }); + if (result.canceled || !result.filePath) return false; + + const pdfWindow = new BrowserWindow({ + show: false, + webPreferences: { + sandbox: true, + contextIsolation: true, + nodeIntegration: false + } + }); + + const fullHtml = `${htmlContent}`; + + try { + await pdfWindow.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(fullHtml)}`); + const pdf = await pdfWindow.webContents.printToPDF({ printBackground: true, preferCSSPageSize: true }); + fs.writeFileSync(result.filePath, pdf); + return true; + } finally { + if (!pdfWindow.isDestroyed()) { + pdfWindow.destroy(); + } + } +}); + +ipcMain.handle('get-git-status', async () => { + const repoRoot = findGitRoot(currentFolder); + if (!repoRoot) return { available: false, repoRoot: null, entries: [] }; + + try { + const output = execFileSync('git', ['-C', repoRoot, 'status', '--porcelain', '--untracked-files=all'], { + encoding: 'utf-8' + }); + const entries = output + .split('\n') + .filter(Boolean) + .map(line => parseGitStatusLine(line, repoRoot)); + + return { available: true, repoRoot, entries }; + } catch (_) { + return { available: false, repoRoot, entries: [] }; + } +}); + +ipcMain.handle('get-git-diff', async (_event, filePath) => { + const repoRoot = findGitRoot(currentFolder); + if (!repoRoot || !filePath) return { available: false, diff: '', status: 'unavailable' }; + + const resolved = resolveWorkspacePath(currentFolder, filePath); + const relative = path.relative(repoRoot, resolved); + + try { + const statusOutput = execFileSync('git', ['-C', repoRoot, 'status', '--porcelain', '--', relative], { + encoding: 'utf-8' + }).trim(); + const status = statusOutput ? statusOutput.slice(0, 2).trim() || '?' : 'clean'; + + let diff = execFileSync('git', ['-C', repoRoot, 'diff', '--no-color', '--', relative], { + encoding: 'utf-8' + }); + + if (!diff.trim() && status === '??') { + const content = fs.readFileSync(resolved, 'utf-8'); + diff = `Untracked file: ${relative}${os.EOL}${os.EOL}${content}`; + } + + return { available: true, diff, status, repoRoot, relativePath: relative }; + } catch (error) { + return { available: false, diff: '', status: 'error', message: error.message }; + } +}); + +ipcMain.handle('import-files-into-workspace', async (_event, sources, targetDir) => { + if (!Array.isArray(sources) || sources.length === 0) return []; + const resolvedDir = resolveWorkspacePath(currentFolder, targetDir || currentFolder); + fs.mkdirSync(resolvedDir, { recursive: true }); + + return sources.map(sourcePath => { + const sourceName = path.basename(sourcePath); + const targetPath = createAvailablePath(resolvedDir, sourceName); + fs.copyFileSync(sourcePath, targetPath); + + return { + sourcePath, + path: targetPath, + name: path.basename(targetPath), + relativePath: currentFolder ? path.relative(currentFolder, targetPath) : path.basename(targetPath), + isImage: /\.(png|jpe?g|gif|webp|svg)$/i.test(targetPath) + }; + }); +}); + // ── IPC: prompt for new file/folder name ────────────────────────────────────── ipcMain.handle('prompt-new-file', async (_event, parentDir) => { @@ -387,13 +507,13 @@ function startFileWatcher(folderPath) { try { fileWatcher = fs.watch(folderPath, { recursive: true }, (eventType, fileName) => { if (!fileName) return; - // Sanitize: reject null bytes and control characters - if (/[\x00-\x1f]/.test(fileName)) return; + const normalizedFileName = String(fileName); + if (hasControlCharacters(normalizedFileName)) return; const IGNORE_PATTERNS = ['.git', 'node_modules', '.DS_Store']; - if (IGNORE_PATTERNS.some(p => fileName.includes(p))) return; + if (IGNORE_PATTERNS.some(p => normalizedFileName.includes(p))) return; if (mainWindow && !mainWindow.isDestroyed()) { - mainWindow.webContents.send('workspace-changed', { eventType, fileName: String(fileName) }); + mainWindow.webContents.send('workspace-changed', { eventType, fileName: normalizedFileName }); } }); } catch (_) { @@ -441,6 +561,40 @@ function readFolderTree(rootPath) { return { root: rootPath, name: path.basename(rootPath), children: walk(rootPath, 0) }; } +function findGitRoot(startPath) { + if (!startPath) return null; + try { + return execFileSync('git', ['-C', startPath, 'rev-parse', '--show-toplevel'], { + encoding: 'utf-8' + }).trim(); + } catch (_) { + return null; + } +} + +function parseGitStatusLine(line, repoRoot) { + const status = line.slice(0, 2); + const filePath = line.slice(3).trim(); + return { + status, + path: path.join(repoRoot, filePath), + relativePath: filePath + }; +} + +function createAvailablePath(dirPath, fileName) { + const parsed = path.parse(fileName); + let candidate = path.join(dirPath, fileName); + let counter = 1; + + while (fs.existsSync(candidate)) { + candidate = path.join(dirPath, `${parsed.name}-${counter}${parsed.ext}`); + counter += 1; + } + + return candidate; +} + // ── App lifecycle ───────────────────────────────────────────────────────────── app.whenReady().then(() => { diff --git a/src/preload.js b/src/preload.js index 5bf4d8f..5caeab8 100644 --- a/src/preload.js +++ b/src/preload.js @@ -26,6 +26,14 @@ contextBridge.exposeInMainWorld('docfoundry', { // Export exportHtml: (htmlContent, suggestedName) => ipcRenderer.invoke('export-html', htmlContent, suggestedName), + exportPdf: (htmlContent, suggestedName) => ipcRenderer.invoke('export-pdf', htmlContent, suggestedName), + + // Git + getGitStatus: () => ipcRenderer.invoke('get-git-status'), + getGitDiff: (filePath) => ipcRenderer.invoke('get-git-diff', filePath), + + // File import + importFilesIntoWorkspace: (sources, targetDir) => ipcRenderer.invoke('import-files-into-workspace', sources, targetDir), // Dirty state setDirtyState: (isDirty) => ipcRenderer.send('set-dirty-state', isDirty), @@ -38,6 +46,7 @@ contextBridge.exposeInMainWorld('docfoundry', { onMenuEvent: (channel, callback) => { const validChannels = [ 'menu-open-folder', 'menu-new-file', 'menu-save', 'menu-export-html', + 'menu-export-pdf', 'menu-git-diff', 'menu-check-links', 'menu-find', 'menu-replace', 'menu-command-palette', 'menu-workspace-search', 'menu-toggle-sidebar', 'menu-toggle-outline', 'menu-zen-mode', 'menu-shortcuts' ]; diff --git a/src/renderer/index.html b/src/renderer/index.html index b4fe136..6eb8b37 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -3,7 +3,7 @@ - + DocFoundry @@ -52,7 +52,7 @@

Organize

Export

-

Export your rendered documents to standalone HTML files.

+

Export your rendered documents to standalone HTML or PDF files.

@@ -126,7 +126,8 @@

Export

- + +
@@ -168,6 +169,26 @@

Export

+ + + +