diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..81f3ec3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 4 +tab_width = 4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..7748ceb --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,28 @@ +name: Node.js build + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x, 22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - run: npm ci + - run: npm run build --if-present + - run: npm run lint + diff --git a/.gitignore b/.gitignore index 5e6c0c6..386ac2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,22 @@ -node_modules/ +# vscode +.vscode + +# Intellij +*.iml +.idea + +# npm +node_modules + +# Don't include the compiled main.js file in the repo. +# They should be uploaded to GitHub releases instead. main.js -main.js.map -*.log + +# Exclude sourcemaps +*.map + +# obsidian +data.json + +# Exclude macOS Finder (System Explorer) View States .DS_Store -versions.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b973752 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +tag-version-prefix="" \ No newline at end of file diff --git a/.obsidian/plugins/vitepress-exporter/new_method.txt b/.obsidian/plugins/vitepress-exporter/new_method.txt deleted file mode 100644 index 0a2d42d..0000000 --- a/.obsidian/plugins/vitepress-exporter/new_method.txt +++ /dev/null @@ -1,134 +0,0 @@ - // 尝试捕获 Obsidian 原生 Canvas 渲染(通过临时调整视口大小) - async tryNativeCanvasCapture(canvasFile: TFile): Promise { - let uiStyleElement: HTMLStyleElement | null = null; - let sizeStyleElement: HTMLStyleElement | null = null; - let activeLeaf: any = null; - let canvasWrapper: HTMLElement | null = null; - let originalScrollLeft = 0; - let originalScrollTop = 0; - - try { - console.log('🔍 Step 1: Getting active workspace leaf...'); - - // 获取当前活动的 leaf(不创建新窗口) - activeLeaf = this.app.workspace.activeLeaf; - if (!activeLeaf) { - console.log('❌ No active leaf found'); - return null; - } - - console.log('🔍 Step 2: Opening canvas file...'); - await activeLeaf.openFile(canvasFile); - - console.log('⏳ Step 3: Waiting for canvas render...'); - await this.waitForCanvasRender(); - - console.log('🔍 Step 4: Finding canvas DOM...'); - const canvasDom = this.findCanvasDomElement(); - if (!canvasDom) { - console.log('❌ Could not find canvas DOM element'); - return null; - } - - console.log('✅ Found canvas DOM:', canvasDom.className, 'Size:', (canvasDom as any).offsetWidth, 'x', (canvasDom as any).offsetHeight); - - console.log('🎨 Step 5: Hiding Canvas UI elements...'); - uiStyleElement = this.hideCanvasUIElements(); - - console.log('📐 Step 6: Calculating canvas content size...'); - const contentSize = this.getCanvasContentSize(canvasDom); - - // 获取 canvasWrapper - if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) { - canvasWrapper = canvasDom as HTMLElement; - } else { - canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement; - } - - if (!canvasWrapper) { - console.log('❌ Could not find canvas wrapper'); - return null; - } - - // 保存原始滚动位置 - originalScrollLeft = canvasWrapper.scrollLeft; - originalScrollTop = canvasWrapper.scrollTop; - - console.log(`📏 Original wrapper size: ${(canvasDom as any).offsetWidth}x${(canvasDom as any).offsetHeight}`); - console.log(`📏 Content size: ${contentSize.width}x${contentSize.height}`); - - // 临时调整 canvas wrapper 大小以适应所有内容 - console.log('🔧 Temporarily resizing canvas wrapper to fit all content...'); - sizeStyleElement = document.createElement('style'); - sizeStyleElement.id = 'canvas-export-resize'; - sizeStyleElement.textContent = ` - /* 临时调整 canvas wrapper 大小 */ - .canvas-wrapper { - width: ${contentSize.width + 100}px !important; - height: ${contentSize.height + 100}px !important; - max-width: ${contentSize.width + 100}px !important; - max-height: ${contentSize.height + 100}px !important; - overflow: visible !important; - } - - /* 确保画布内容区域也扩展 */ - .canvas-view-content { - width: ${contentSize.width + 100}px !important; - height: ${contentSize.height + 100}px !important; - } - `; - document.head.appendChild(sizeStyleElement); - - // 等待样式应用 - await new Promise(resolve => setTimeout(resolve, 100)); - - // 重置滚动位置 - canvasWrapper.scrollLeft = 0; - canvasWrapper.scrollTop = 0; - - // 等待布局更新 - await new Promise(resolve => setTimeout(resolve, 200)); - - console.log('📸 Step 7: Capturing canvas...'); - // @ts-ignore - const domToImage = require('dom-to-image-more'); - - const dataUrl = await domToImage.toPng(canvasDom, { - backgroundColor: '#ffffff', - quality: 1, - width: contentSize.width, - height: contentSize.height, - cacheBust: true - }); - - const imageData = this.dataUrlToUint8Array(dataUrl); - - console.log('✅ Capture successful!'); - - return imageData; - - } catch (error) { - console.error('❌ Native canvas capture failed:', error); - return null; - } finally { - // 清理临时调整大小的样式 - if (sizeStyleElement && sizeStyleElement.parentNode) { - sizeStyleElement.parentNode.removeChild(sizeStyleElement); - console.log('🧹 Removed temporary resize styles'); - } - - if (uiStyleElement && uiStyleElement.parentNode) { - uiStyleElement.parentNode.removeChild(uiStyleElement); - console.log('🧹 Cleaned up UI hiding styles'); - } - - // 恢复滚动位置 - if (canvasWrapper) { - canvasWrapper.scrollLeft = originalScrollLeft; - canvasWrapper.scrollTop = originalScrollTop; - console.log('🔄 Restored original scroll position'); - } - - console.log('🧹 Cleanup complete'); - } - } diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..3f4274a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,251 @@ +# Obsidian community plugin + +## Project overview + +- Target: Obsidian Community Plugin (TypeScript → bundled JavaScript). +- Entry point: `main.ts` compiled to `main.js` and loaded by Obsidian. +- Required release artifacts: `main.js`, `manifest.json`, and optional `styles.css`. + +## Environment & tooling + +- Node.js: use current LTS (Node 18+ recommended). +- **Package manager: npm** (required for this sample - `package.json` defines npm scripts and dependencies). +- **Bundler: esbuild** (required for this sample - `esbuild.config.mjs` and build scripts depend on it). Alternative bundlers like Rollup or webpack are acceptable for other projects if they bundle all external dependencies into `main.js`. +- Types: `obsidian` type definitions. + +**Note**: This sample project has specific technical dependencies on npm and esbuild. If you're creating a plugin from scratch, you can choose different tools, but you'll need to replace the build configuration accordingly. + +### Install + +```bash +npm install +``` + +### Dev (watch) + +```bash +npm run dev +``` + +### Production build + +```bash +npm run build +``` + +## Linting + +- To use eslint install eslint from terminal: `npm install -g eslint` +- To use eslint to analyze this project use this command: `eslint main.ts` +- eslint will then create a report with suggestions for code improvement by file and line number. +- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder: `eslint ./src/` + +## File & folder conventions + +- **Organize code into multiple files**: Split functionality across separate modules rather than putting everything in `main.ts`. +- Source lives in `src/`. Keep `main.ts` small and focused on plugin lifecycle (loading, unloading, registering commands). +- **Example file structure**: + ``` + src/ + main.ts # Plugin entry point, lifecycle management + settings.ts # Settings interface and defaults + commands/ # Command implementations + command1.ts + command2.ts + ui/ # UI components, modals, views + modal.ts + view.ts + utils/ # Utility functions, helpers + helpers.ts + constants.ts + types.ts # TypeScript interfaces and types + ``` +- **Do not commit build artifacts**: Never commit `node_modules/`, `main.js`, or other generated files to version control. +- Keep the plugin small. Avoid large dependencies. Prefer browser-compatible packages. +- Generated output should be placed at the plugin root or `dist/` depending on your build setup. Release artifacts must end up at the top level of the plugin folder in the vault (`main.js`, `manifest.json`, `styles.css`). + +## Manifest rules (`manifest.json`) + +- Must include (non-exhaustive): + - `id` (plugin ID; for local dev it should match the folder name) + - `name` + - `version` (Semantic Versioning `x.y.z`) + - `minAppVersion` + - `description` + - `isDesktopOnly` (boolean) + - Optional: `author`, `authorUrl`, `fundingUrl` (string or map) +- Never change `id` after release. Treat it as stable API. +- Keep `minAppVersion` accurate when using newer APIs. +- Canonical requirements are coded here: https://github.com/obsidianmd/obsidian-releases/blob/master/.github/workflows/validate-plugin-entry.yml + +## Testing + +- Manual install for testing: copy `main.js`, `manifest.json`, `styles.css` (if any) to: + ``` + /.obsidian/plugins// + ``` +- Reload Obsidian and enable the plugin in **Settings → Community plugins**. + +## Commands & settings + +- Any user-facing commands should be added via `this.addCommand(...)`. +- If the plugin has configuration, provide a settings tab and sensible defaults. +- Persist settings using `this.loadData()` / `this.saveData()`. +- Use stable command IDs; avoid renaming once released. + +## Versioning & releases + +- Bump `version` in `manifest.json` (SemVer) and update `versions.json` to map plugin version → minimum app version. +- Create a GitHub release whose tag exactly matches `manifest.json`'s `version`. Do not use a leading `v`. +- Attach `manifest.json`, `main.js`, and `styles.css` (if present) to the release as individual assets. +- After the initial release, follow the process to add/update your plugin in the community catalog as required. + +## Security, privacy, and compliance + +Follow Obsidian's **Developer Policies** and **Plugin Guidelines**. In particular: + +- Default to local/offline operation. Only make network requests when essential to the feature. +- No hidden telemetry. If you collect optional analytics or call third-party services, require explicit opt-in and document clearly in `README.md` and in settings. +- Never execute remote code, fetch and eval scripts, or auto-update plugin code outside of normal releases. +- Minimize scope: read/write only what's necessary inside the vault. Do not access files outside the vault. +- Clearly disclose any external services used, data sent, and risks. +- Respect user privacy. Do not collect vault contents, filenames, or personal information unless absolutely necessary and explicitly consented. +- Avoid deceptive patterns, ads, or spammy notifications. +- Register and clean up all DOM, app, and interval listeners using the provided `register*` helpers so the plugin unloads safely. + +## UX & copy guidelines (for UI text, commands, settings) + +- Prefer sentence case for headings, buttons, and titles. +- Use clear, action-oriented imperatives in step-by-step copy. +- Use **bold** to indicate literal UI labels. Prefer "select" for interactions. +- Use arrow notation for navigation: **Settings → Community plugins**. +- Keep in-app strings short, consistent, and free of jargon. + +## Performance + +- Keep startup light. Defer heavy work until needed. +- Avoid long-running tasks during `onload`; use lazy initialization. +- Batch disk access and avoid excessive vault scans. +- Debounce/throttle expensive operations in response to file system events. + +## Coding conventions + +- TypeScript with `"strict": true` preferred. +- **Keep `main.ts` minimal**: Focus only on plugin lifecycle (onload, onunload, addCommand calls). Delegate all feature logic to separate modules. +- **Split large files**: If any file exceeds ~200-300 lines, consider breaking it into smaller, focused modules. +- **Use clear module boundaries**: Each file should have a single, well-defined responsibility. +- Bundle everything into `main.js` (no unbundled runtime deps). +- Avoid Node/Electron APIs if you want mobile compatibility; set `isDesktopOnly` accordingly. +- Prefer `async/await` over promise chains; handle errors gracefully. + +## Mobile + +- Where feasible, test on iOS and Android. +- Don't assume desktop-only behavior unless `isDesktopOnly` is `true`. +- Avoid large in-memory structures; be mindful of memory and storage constraints. + +## Agent do/don't + +**Do** +- Add commands with stable IDs (don't rename once released). +- Provide defaults and validation in settings. +- Write idempotent code paths so reload/unload doesn't leak listeners or intervals. +- Use `this.register*` helpers for everything that needs cleanup. + +**Don't** +- Introduce network calls without an obvious user-facing reason and documentation. +- Ship features that require cloud services without clear disclosure and explicit opt-in. +- Store or transmit vault contents unless essential and consented. + +## Common tasks + +### Organize code across multiple files + +**main.ts** (minimal, lifecycle only): +```ts +import { Plugin } from "obsidian"; +import { MySettings, DEFAULT_SETTINGS } from "./settings"; +import { registerCommands } from "./commands"; + +export default class MyPlugin extends Plugin { + settings: MySettings; + + async onload() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + registerCommands(this); + } +} +``` + +**settings.ts**: +```ts +export interface MySettings { + enabled: boolean; + apiKey: string; +} + +export const DEFAULT_SETTINGS: MySettings = { + enabled: true, + apiKey: "", +}; +``` + +**commands/index.ts**: +```ts +import { Plugin } from "obsidian"; +import { doSomething } from "./my-command"; + +export function registerCommands(plugin: Plugin) { + plugin.addCommand({ + id: "do-something", + name: "Do something", + callback: () => doSomething(plugin), + }); +} +``` + +### Add a command + +```ts +this.addCommand({ + id: "your-command-id", + name: "Do the thing", + callback: () => this.doTheThing(), +}); +``` + +### Persist settings + +```ts +interface MySettings { enabled: boolean } +const DEFAULT_SETTINGS: MySettings = { enabled: true }; + +async onload() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + await this.saveData(this.settings); +} +``` + +### Register listeners safely + +```ts +this.registerEvent(this.app.workspace.on("file-open", f => { /* ... */ })); +this.registerDomEvent(window, "resize", () => { /* ... */ }); +this.registerInterval(window.setInterval(() => { /* ... */ }, 1000)); +``` + +## Troubleshooting + +- Plugin doesn't load after build: ensure `main.js` and `manifest.json` are at the top level of the plugin folder under `/.obsidian/plugins//`. +- Build issues: if `main.js` is missing, run `npm run build` or `npm run dev` to compile your TypeScript source code. +- Commands not appearing: verify `addCommand` runs after `onload` and IDs are unique. +- Settings not persisting: ensure `loadData`/`saveData` are awaited and you re-render the UI after changes. +- Mobile-only issues: confirm you're not using desktop-only APIs; check `isDesktopOnly` and adjust. + +## References + +- Obsidian sample plugin: https://github.com/obsidianmd/obsidian-sample-plugin +- API documentation: https://docs.obsidian.md +- Developer policies: https://docs.obsidian.md/Developer+policies +- Plugin guidelines: https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines +- Style guide: https://help.obsidian.md/style-guide diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..287f37a --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +Copyright (C) 2020-2025 by Dynalist Inc. + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts deleted file mode 100644 index c97ba83..0000000 --- a/docs/.vuepress/config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { defaultTheme } from '@vuepress/theme-default'; -import type { DefaultThemeOptions } from '@vuepress/theme-default'; -import type { PluginOptions } from 'vuepress'; - -export default { - title: 'VitePress Demo', - description: 'Demo for VitePress with Canvas Viewer', - - theme: defaultTheme({ - navbar: [ - { - text: 'Home', - link: '/', - }, - ], - }), - - clientConfigFile: 'index.ts', -} satisfies PluginOptions; diff --git a/docs/index.ts b/docs/index.ts deleted file mode 100644 index c904e03..0000000 --- a/docs/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineClientConfig } from '@vuepress/client'; -import { CanvasViewerPlugin } from './plugins/canvas-viewer'; - -export default defineClientConfig({ - enhance({ app, router }) { - app.use(CanvasViewerPlugin); - } -}); diff --git a/docs/plugins/canvas-viewer.ts b/docs/plugins/canvas-viewer.ts deleted file mode 100644 index 5496c5b..0000000 --- a/docs/plugins/canvas-viewer.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { Plugin } from 'vue'; - -export const CanvasViewerPlugin: Plugin = { - install(app) { - app.component('CanvasViewer', () => import('./components/CanvasViewer.vue')); - } -}; diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 61114cf..1c74a14 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,6 +1,6 @@ import esbuild from "esbuild"; import process from "process"; -import builtins from "builtin-modules"; +import { builtinModules } from 'node:module'; const banner = `/* @@ -9,68 +9,41 @@ if you want to view the source, please visit the github repository of this plugi */ `; -const prod = (process.argv[2] === 'production'); +const prod = (process.argv[2] === "production"); + +const context = await esbuild.context({ + banner: { + js: banner, + }, + entryPoints: ["src/main.ts"], + bundle: true, + external: [ + "obsidian", + "electron", + "@codemirror/autocomplete", + "@codemirror/collab", + "@codemirror/commands", + "@codemirror/language", + "@codemirror/lint", + "@codemirror/search", + "@codemirror/state", + "@codemirror/view", + "@lezer/common", + "@lezer/highlight", + "@lezer/lr", + ...builtinModules], + format: "cjs", + target: "es2018", + logLevel: "info", + sourcemap: prod ? false : "inline", + treeShaking: true, + outfile: "main.js", + minify: prod, +}); if (prod) { - console.log('Building production bundle...'); - await esbuild.build({ - banner: { - js: banner, - }, - entryPoints: ['main.ts'], - bundle: true, - external: [ - 'obsidian', - 'electron', - '@codemirror/autocomplete', - '@codemirror/collab', - '@codemirror/commands', - '@codemirror/language', - '@codemirror/lint', - '@codemirror/search', - '@codemirror/state', - '@codemirror/view', - '@lezer/common', - '@lezer/highlight', - '@lezer/lr', - ...builtins], - format: 'cjs', - target: 'es2018', - logLevel: "info", - sourcemap: false, - treeShaking: true, - outfile: 'main.js', - }); - console.log('Production bundle built successfully!'); + await context.rebuild(); + process.exit(0); } else { - const ctx = await esbuild.context({ - banner: { - js: banner, - }, - entryPoints: ['main.ts'], - bundle: true, - external: [ - 'obsidian', - 'electron', - '@codemirror/autocomplete', - '@codemirror/collab', - '@codemirror/commands', - '@codemirror/language', - '@codemirror/lint', - '@codemirror/search', - '@codemirror/state', - '@codemirror/view', - '@lezer/common', - '@lezer/highlight', - '@lezer/lr', - ...builtins], - format: 'cjs', - target: 'es2018', - logLevel: "info", - sourcemap: 'inline', - treeShaking: true, - outfile: 'main.js', - }); - - await ctx.watch(); + await context.watch(); } diff --git a/eslint.config.mts b/eslint.config.mts new file mode 100644 index 0000000..3062c4a --- /dev/null +++ b/eslint.config.mts @@ -0,0 +1,34 @@ +import tseslint from 'typescript-eslint'; +import obsidianmd from "eslint-plugin-obsidianmd"; +import globals from "globals"; +import { globalIgnores } from "eslint/config"; + +export default tseslint.config( + { + languageOptions: { + globals: { + ...globals.browser, + }, + parserOptions: { + projectService: { + allowDefaultProject: [ + 'eslint.config.js', + 'manifest.json' + ] + }, + tsconfigRootDir: import.meta.dirname, + extraFileExtensions: ['.json'] + }, + }, + }, + ...obsidianmd.configs.recommended, + globalIgnores([ + "node_modules", + "dist", + "esbuild.config.mjs", + "eslint.config.js", + "version-bump.mjs", + "versions.json", + "main.js", + ]), +); diff --git a/main.ts b/main.ts deleted file mode 100644 index fcec775..0000000 --- a/main.ts +++ /dev/null @@ -1,1210 +0,0 @@ -import { App, Plugin, PluginSettingTab, Setting, TFile, Notice } from 'obsidian'; - -interface VitePressExporterSettings { - docsPath: string; - assetsPath: string; -} - -const DEFAULT_SETTINGS: VitePressExporterSettings = { - docsPath: 'docs', - assetsPath: 'docs/assets' -} - -export default class VitePressExporterPlugin extends Plugin { - settings: VitePressExporterSettings; - - async onload() { - await this.loadSettings(); - - // 添加导出命令 - this.addCommand({ - id: 'export-to-vitepress', - name: 'Export current note to VitePress', - callback: () => { - this.exportCurrentNote(); - } - }); - - // 添加功能区按钮 - this.addRibbonIcon('upload', 'Export to VitePress', () => { - this.exportCurrentNote(); - }); - - // 添加设置面板 - this.addSettingTab(new VitePressExporterSettingTab(this.app, this)); - - console.log('VitePress Exporter plugin loaded'); - } - - onunload() { - console.log('VitePress Exporter plugin unloaded'); - } - - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } - - async saveSettings() { - await this.saveData(this.settings); - } - - // 导出当前笔记 - async exportCurrentNote() { - const activeFile = this.app.workspace.getActiveFile(); - - if (!activeFile) { - new Notice('No active file found'); - return; - } - - if (activeFile.extension !== 'md') { - new Notice('Current file is not a markdown file'); - return; - } - - new Notice(`Exporting ${activeFile.name} to VitePress...`); - - try { - await this.exportNote(activeFile); - new Notice(`Successfully exported ${activeFile.name} to VitePress`); - } catch (error) { - console.error('Export failed:', error); - new Notice(`Export failed: ${error.message}`); - } - } - - // 导出单个笔记 - async exportNote(file: TFile) { - const { vault } = this.app; - - // 使用 binary 模式读取文件以保留原始格式(包括行尾空格) - const contentBuffer = await vault.readBinary(file); - const content = new TextDecoder().decode(contentBuffer); - - // 1. 扫描并复制所有资源文件(传入文件对象用于路径解析) - const updatedContent = await this.processAssets(content, file); - - // 2. 处理 canvas 引用(暂时保留,后续实现) - // const finalContent = await this.processCanvases(updatedContent); - - // 3. 写入到 docs 目录(使用 binary 模式保留原始格式) - const docsPath = `${this.settings.docsPath}/${file.name}`; - const updatedBuffer = new TextEncoder().encode(updatedContent); - await vault.adapter.writeBinary(docsPath, updatedBuffer); - - console.log(`Exported ${file.name} to ${docsPath}`); - } - - // 处理资源文件 - async processAssets(content: string, sourceFile: TFile): Promise { - const { vault, metadataCache } = this.app; - - console.log('Processing assets for file:', sourceFile.path); - - // 使用 Obsidian API 获取文件的所有嵌入和链接 - const cache = metadataCache.getCache(sourceFile.path); - - console.log('Cache:', cache); - console.log('Embeds:', cache?.embeds); - console.log('Links:', cache?.links); - - if (!cache) { - console.log('No cache found for file'); - return content; - } - - const assetsToCopy = new Set(); - const canvasFiles = new Set(); - - // 收集嵌入文件(图片等) - if (cache.embeds) { - for (const embed of cache.embeds) { - console.log('Processing embed:', embed); - const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); - console.log('Resolved link for embed:', resolvedLink?.path); - if (resolvedLink) { - // 检查是否是 canvas 文件 - if (resolvedLink.extension === 'canvas') { - canvasFiles.add(resolvedLink.path); - } else { - assetsToCopy.add(resolvedLink.path); - } - } - } - } - - // 收集普通链接(可选,如果也想复制链接的文件) - if (cache.links) { - for (const link of cache.links) { - const resolvedLink = metadataCache.getFirstLinkpathDest(link.link, sourceFile.path); - // 只复制本地文件链接,不包括其他 md 文件 - if (resolvedLink && resolvedLink.extension !== 'md') { - assetsToCopy.add(resolvedLink.path); - } - } - } - - console.log('Assets to copy:', Array.from(assetsToCopy)); - console.log('Canvas files to render:', Array.from(canvasFiles)); - - // 处理 Canvas 文件:渲染为图片 - for (const canvasPath of canvasFiles) { - try { - const canvasFile = vault.getAbstractFileByPath(canvasPath); - if (canvasFile instanceof TFile) { - const renderedImage = await this.renderCanvasToImage(canvasFile); - if (renderedImage) { - const imageFileName = canvasFile.name.replace('.canvas', '.png'); - // 图片保存到 docs/assets/ - const imagePath = `${this.settings.assetsPath}/${imageFileName}`; - - // 确保目标目录存在 - await vault.adapter.mkdir(this.settings.assetsPath); - - // 写入渲染的图片 - await vault.adapter.writeBinary(imagePath, renderedImage); - - // 更新内容中的 canvas 引用,使用相对路径 assets/xxx.png - content = this.updateCanvasLinksInContent(content, canvasFile, canvasPath, imageFileName); - - console.log(`Successfully rendered canvas: ${canvasPath} -> ${imagePath}`); - } - } - } catch (error) { - console.error(`Failed to render canvas ${canvasPath}:`, error); - } - } - - // 复制资源文件到 docs/assets - for (const assetPath of assetsToCopy) { - try { - const sourceFile = vault.getAbstractFileByPath(assetPath); - console.log('Source file for asset:', sourceFile); - - if (sourceFile instanceof TFile) { - // 使用 binary 读取模式来保留文件原始内容 - const assetContent = await vault.readBinary(sourceFile); - const fileName = sourceFile.name; - const destPath = `${this.settings.assetsPath}/${fileName}`; - - console.log('Copying asset:', assetPath, '->', destPath); - - // 确保目标目录存在 - await vault.adapter.mkdir(this.settings.assetsPath); - - // 写入资源文件(使用 binary 模式) - await vault.adapter.writeBinary(destPath, assetContent); - - // 更新内容中的资源路径(使用更智能的替换) - content = this.updateLinksInContent(content, sourceFile, assetPath, fileName); - - console.log(`Successfully copied asset: ${assetPath} -> ${destPath}`); - } - } catch (error) { - console.error(`Failed to copy asset ${assetPath}:`, error); - } - } - - return content; - } - - // 获取原始链接文本 - getOriginalLink(content: string, targetPath: string, sourcePath: string): string | null { - const { metadataCache } = this.app; - - // 尝试多种可能的链接格式 - const possibleFormats = [ - // Wikilink 格式 - new RegExp(`!\\[\\[${this.escapeRegExp(targetPath)}(\\|[^\\]]*)?\\]\\]`, 'g'), - new RegExp(`\\[\\[${this.escapeRegExp(targetPath)}(\\|[^\\]]*)?\\]\\]`, 'g'), - // Markdown 格式 - new RegExp(`!\\[.*?\\]\\(${this.escapeRegExp(targetPath)}\\)`, 'g'), - new RegExp(`\\[.*?\\]\\(${this.escapeRegExp(targetPath)}\\)`, 'g'), - // 相对路径格式 - new RegExp(`!\\[\\[${this.escapeRegExp(this.getRelativePath(targetPath, sourcePath))}(\\|[^\\]]*)?\\]\\]`, 'g'), - ]; - - for (const regex of possibleFormats) { - const match = content.match(regex); - if (match) { - return match[0]; - } - } - - return null; - } - - // 更新内容中的链接 - updateLinksInContent(content: string, sourceFile: TFile, assetPath: string, newFileName: string): string { - // 获取源文件的目录路径 - const sourceDir = sourceFile.path.substring(0, sourceFile.path.lastIndexOf('/')); - if (!sourceDir) return content; - - // 尝试多种可能的路径格式 - const possiblePaths = [ - // 完整路径 - assetPath, - // 相对于源文件的路径 - assetPath.substring(sourceDir.length + 1), - // URL 编码版本 - encodeURI(assetPath), - encodeURI(assetPath.substring(sourceDir.length + 1)), - // 文件名 - sourceFile.name, - encodeURI(sourceFile.name) - ]; - - console.log('Trying to replace links for paths:', possiblePaths); - - // 替换 markdown 格式: ![](path) -> ![](assets/newfile.png) - const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; - content = content.replace(markdownRegex, (match, alt, path) => { - // 检查这个路径是否匹配我们的目标文件 - for (const testPath of possiblePaths) { - if (path === testPath || path === testPath.replace(/^\//, '')) { - console.log(`Found matching link: ${path} -> ${this.settings.assetsPath}/${newFileName}`); - return `![](${this.settings.assetsPath}/${newFileName})`; - } - } - return match; - }); - - // 替换 wikilink 格式: ![[path]] -> ![[assets/newfile.png]] - const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; - content = content.replace(wikilinkRegex, (match, link) => { - // 移除可能的别名字段 - const cleanLink = link.split('|')[0].trim(); - - for (const testPath of possiblePaths) { - if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { - console.log(`Found matching wikilink: ${cleanLink} -> ${this.settings.assetsPath}/${newFileName}`); - return `![[${this.settings.assetsPath}/${newFileName}]]`; - } - } - return match; - }); - - return content; - } - - // 辅助函数:转义正则表达式特殊字符 - escapeRegExp(string: string): string { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - } - - // 辅助函数:获取相对路径 - getRelativePath(targetPath: string, sourcePath: string): string { - // 简化的相对路径计算 - const targetParts = targetPath.split('/'); - const sourceParts = sourcePath.split('/'); - - // 移除文件名 - sourceParts.pop(); - - let commonIndex = 0; - while (commonIndex < Math.min(targetParts.length - 1, sourceParts.length) && - targetParts[commonIndex] === sourceParts[commonIndex]) { - commonIndex++; - } - - const relativeParts = []; - for (let i = commonIndex; i < sourceParts.length; i++) { - relativeParts.push('..'); - } - - return [...relativeParts, ...targetParts.slice(commonIndex)].join('/'); - } - - // 渲染 Canvas 为图片(使用 Obsidian 原生渲染) - async renderCanvasToImage(canvasFile: TFile): Promise { - try { - console.log('🎯 Attempting to render canvas using Obsidian native rendering:', canvasFile.path); - - // 使用 Workspace API 打开 Canvas 并捕获原生渲染 - const nativeImage = await this.tryNativeCanvasCapture(canvasFile); - if (nativeImage) { - console.log('✅ Successfully captured native Obsidian canvas rendering'); - return nativeImage; - } - - console.log('⚠️ Native capture failed, using placeholder'); - // 降级方案:生成占位图 - return this.generatePlaceholderImage(canvasFile); - - } catch (error) { - console.error('❌ Error rendering canvas:', error); - return this.generatePlaceholderImage(canvasFile); - } - } - - - // 隐藏 Canvas UI 元素(用于导出时) - hideCanvasUIElements(): HTMLStyleElement { - const styleElement = document.createElement('style'); - styleElement.id = 'canvas-export-hide-ui'; - styleElement.textContent = ` - /* 隐藏 Canvas 控制按钮 */ - .canvas-control-menu, - .canvas-card-menu, - .canvas-node-menu-button, - .canvas-node:hover .canvas-node-menu-button, - .canvas-controls, - .canvas-help-button { - display: none !important; - } - - /* 移除选中状态的高亮 */ - .canvas-node.is-selected, - .canvas-node.is-focused, - .canvas-edge.is-selected { - box-shadow: none !important; - outline: none !important; - } - - /* 隐藏工具提示和弹出菜单 */ - .tooltip, - .popover, - .modal { - display: none !important; - } - - /* 隐藏滚动条但保留滚动功能 */ - .canvas-view-content::-webkit-scrollbar { - display: none !important; - } - - /* 确保内容不被裁切 */ - .canvas-view-content { - overflow: visible !important; - } - - /* Privacy Mode: 防止卡片内容因缩放被隐藏 */ - .canvas-node-content-hidden { - display: block !important; - opacity: 1 !important; - } - - /* 确保所有卡片内容始终可见 */ - .canvas-node-content { - display: block !important; - opacity: 1 !important; - } - - /* 防止卡片被折叠 */ - .canvas-node .canvas-node-content { - display: block !important; - } - `; - document.head.appendChild(styleElement); - console.log('✅ Canvas UI elements hidden for export (privacy mode enabled)'); - return styleElement; - } - - // 计算实际的 Canvas 内容尺寸和偏移 - getCanvasContentSize(canvasDom: Element): { width: number; height: number; offsetX: number; offsetY: number } { - const nodes = canvasDom.querySelectorAll('.canvas-node'); - console.log(`📐 Found ${nodes.length} canvas nodes`); - - if (nodes.length === 0) { - // 降级方案:使用容器尺寸 - return { - width: (canvasDom as any).offsetWidth || 800, - height: (canvasDom as any).offsetHeight || 600, - offsetX: 0, - offsetY: 0 - }; - } - - // 计算所有节点的边界框 - let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - - nodes.forEach(node => { - const rect = node.getBoundingClientRect(); - const canvasRect = canvasDom.getBoundingClientRect(); - - // 计算相对于 Canvas 的位置 - const relativeX = rect.left - canvasRect.left; - const relativeY = rect.top - canvasRect.top; - - minX = Math.min(minX, relativeX); - minY = Math.min(minY, relativeY); - maxX = Math.max(maxX, relativeX + rect.width); - maxY = Math.max(maxY, relativeY + rect.height); - }); - - // 添加 padding - const padding = 50; - const offsetX = Math.max(0, minX - padding); - const offsetY = Math.max(0, minY - padding); - const contentWidth = maxX - minX + padding * 2; - const contentHeight = maxY - minY + padding * 2; - - console.log(`📐 Canvas: ${contentWidth}x${contentHeight}, offset: (${offsetX}, ${offsetY})`); - - return { width: contentWidth, height: contentHeight, offsetX, offsetY }; - } - - - // 通过滚动拼接捕获完整 Canvas - async captureCanvasByScrolling( - canvasDom: Element, - contentSize: { width: number; height: number; offsetX: number; offsetY: number } - ): Promise { - try { - // 检查 canvasDom 本身是否就是 wrapper,或者 wrapper 是其子元素 - let canvasWrapper: HTMLElement | null = null; - if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) { - console.log('📦 canvasDom itself is the wrapper'); - canvasWrapper = canvasDom as HTMLElement; - } else { - canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement; - if (!canvasWrapper) { - console.log('❌ No canvas wrapper found'); - return null; - } - } - - // 使用 canvasWrapper 获取视口尺寸 - const viewportWidth = canvasWrapper.offsetWidth; - const viewportHeight = canvasWrapper.offsetHeight; - const totalWidth = contentSize.width; - const totalHeight = contentSize.height; - - console.log(`📐 Viewport: ${viewportWidth}x${viewportHeight}, Total: ${totalWidth}x${totalHeight}`); - - // 如果内容小于视口,直接捕获 - if (totalWidth <= viewportWidth && totalHeight <= viewportHeight) { - console.log('📸 Content fits in viewport, single capture'); - return null; // 让降级处理 - } - - // 计算需要分块的数量 - const cols = Math.ceil(totalWidth / viewportWidth); - const rows = Math.ceil(totalHeight / viewportHeight); - console.log(`🧩 Will capture ${cols}x${rows} = ${cols * rows} tiles`); - console.log(`📍 Content offset: (${contentSize.offsetX}, ${contentSize.offsetY})`); - - // 保存原始滚动位置 - const originalScrollLeft = canvasWrapper.scrollLeft; - const originalScrollTop = canvasWrapper.scrollTop; - - // 创建最终拼接的 Canvas - const finalCanvas = document.createElement('canvas'); - finalCanvas.width = totalWidth; - finalCanvas.height = totalHeight; - const ctx = finalCanvas.getContext('2d'); - if (!ctx) { - console.log('❌ Failed to get canvas context'); - return null; - } - - // 填充白色背景 - ctx.fillStyle = '#ffffff'; - ctx.fillRect(0, 0, totalWidth, totalHeight); - - // @ts-ignore - const domToImage = require('dom-to-image-more'); - - // 分块捕获并拼接 - for (let row = 0; row < rows; row++) { - for (let col = 0; col < cols; col++) { - const x = col * viewportWidth; - const y = row * viewportHeight; - - // 滚动到对应位置 (确保从内容起始位置开始) - const targetScrollLeft = Math.max(0, contentSize.offsetX + x); - const targetScrollTop = Math.max(0, contentSize.offsetY + y); - canvasWrapper.scrollLeft = targetScrollLeft; - canvasWrapper.scrollTop = targetScrollTop; - console.log(`🔄 Scrolled to (${targetScrollLeft}, ${targetScrollTop})`); - - // 等待渲染 - await new Promise(resolve => setTimeout(resolve, 150)); - - // 捕获当前视口 - // @ts-ignore - const domToImage = require('dom-to-image-more'); - const tileDataUrl = await domToImage.toPng(canvasWrapper, { - backgroundColor: '#ffffff', - quality: 1, - width: viewportWidth, - height: viewportHeight - }); - - // 加载图片并绘制到最终 Canvas - const img = await this.loadImage(tileDataUrl); - if (img) { - const drawWidth = Math.min(viewportWidth, totalWidth - x); - const drawHeight = Math.min(viewportHeight, totalHeight - y); - ctx.drawImage(img, 0, 0, drawWidth, drawHeight, x, y, drawWidth, drawHeight); - console.log(`✅ Tile [${row},${col}] at (${x},${y}) size ${drawWidth}x${drawHeight}`); - } - if (img) { - const drawWidth = Math.min(viewportWidth, totalWidth - x); - const drawHeight = Math.min(viewportHeight, totalHeight - y); - ctx.drawImage(img, 0, 0, drawWidth, drawHeight, x, y, drawWidth, drawHeight); - console.log(`✅ Tile [${row},${col}] at (${x},${y}) size ${drawWidth}x${drawHeight}`); - } - } - } - - // 恢复滚动位置 - canvasWrapper.scrollLeft = originalScrollLeft; - canvasWrapper.scrollTop = originalScrollTop; - - // 转换为 Uint8Array - const finalDataUrl = finalCanvas.toDataURL('image/png'); - const base64Data = finalDataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - console.log('✅ Stitched canvas complete'); - return bytes; - - } catch (error) { - console.error('❌ Scroll and stitch failed:', error); - return null; - } - } - - // 加载图片 - async loadImage(dataUrl: string): Promise { - return new Promise((resolve) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = () => resolve(null); - img.src = dataUrl; - }); - } - - // 将 DataURL 转换为 Uint8Array - dataUrlToUint8Array(dataUrl: string): Uint8Array { - const base64Data = dataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - return bytes; - } - - // 尝试捕获 Obsidian 原生 Canvas 渲染(通过临时调整视口大小) - async tryNativeCanvasCapture(canvasFile: TFile): Promise { - let uiStyleElement: HTMLStyleElement | null = null; - let sizeStyleElement: HTMLStyleElement | null = null; - let activeLeaf: any = null; - let canvasWrapper: HTMLElement | null = null; - let originalScrollLeft = 0; - let originalScrollTop = 0; - - try { - console.log('🔍 Step 1: Getting active workspace leaf...'); - - // 获取当前活动的 leaf(不创建新窗口) - activeLeaf = this.app.workspace.activeLeaf; - if (!activeLeaf) { - console.log('❌ No active leaf found'); - return null; - } - - console.log('🔍 Step 2: Opening canvas file...'); - await activeLeaf.openFile(canvasFile); - - console.log('⏳ Step 3: Waiting for canvas render...'); - await this.waitForCanvasRender(); - - console.log('🔍 Step 4: Finding canvas DOM...'); - const canvasDom = this.findCanvasDomElement(); - if (!canvasDom) { - console.log('❌ Could not find canvas DOM element'); - return null; - } - - console.log('✅ Found canvas DOM:', canvasDom.className, 'Size:', (canvasDom as any).offsetWidth, 'x', (canvasDom as any).offsetHeight); - - console.log('🎨 Step 5: Hiding Canvas UI elements...'); - uiStyleElement = this.hideCanvasUIElements(); - - console.log('📐 Step 6: Calculating canvas content size...'); - const contentSize = this.getCanvasContentSize(canvasDom); - - // 获取 canvasWrapper - if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) { - canvasWrapper = canvasDom as HTMLElement; - } else { - canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement; - } - - if (!canvasWrapper) { - console.log('❌ Could not find canvas wrapper'); - return null; - } - - // 保存原始滚动位置 - originalScrollLeft = canvasWrapper.scrollLeft; - originalScrollTop = canvasWrapper.scrollTop; - - console.log(`📏 Original wrapper size: ${(canvasDom as any).offsetWidth}x${(canvasDom as any).offsetHeight}`); - console.log(`📏 Content size: ${contentSize.width}x${contentSize.height}`); - - // 临时调整 canvas wrapper 大小以适应所有内容 - console.log('🔧 Temporarily resizing canvas wrapper to fit all content...'); - sizeStyleElement = document.createElement('style'); - sizeStyleElement.id = 'canvas-export-resize'; - sizeStyleElement.textContent = ` - /* 临时调整 canvas wrapper 大小 */ - .canvas-wrapper { - width: ${contentSize.width + 100}px !important; - height: ${contentSize.height + 100}px !important; - max-width: ${contentSize.width + 100}px !important; - max-height: ${contentSize.height + 100}px !important; - overflow: visible !important; - } - - /* 确保画布内容区域也扩展 */ - .canvas-view-content { - width: ${contentSize.width + 100}px !important; - height: ${contentSize.height + 100}px !important; - } - `; - document.head.appendChild(sizeStyleElement); - - // 等待样式应用 - await new Promise(resolve => setTimeout(resolve, 100)); - - // 重置滚动位置 - canvasWrapper.scrollLeft = 0; - canvasWrapper.scrollTop = 0; - - // 等待布局更新 - await new Promise(resolve => setTimeout(resolve, 200)); - - console.log('📸 Step 7: Capturing canvas...'); - // @ts-ignore - const domToImage = require('dom-to-image-more'); - - const dataUrl = await domToImage.toPng(canvasDom, { - backgroundColor: '#ffffff', - quality: 1, - width: contentSize.width, - height: contentSize.height, - cacheBust: true - }); - - const imageData = this.dataUrlToUint8Array(dataUrl); - - console.log('✅ Capture successful!'); - - return imageData; - - } catch (error) { - console.error('❌ Native canvas capture failed:', error); - return null; - } finally { - // 清理临时调整大小的样式 - if (sizeStyleElement && sizeStyleElement.parentNode) { - sizeStyleElement.parentNode.removeChild(sizeStyleElement); - console.log('🧹 Removed temporary resize styles'); - } - - if (uiStyleElement && uiStyleElement.parentNode) { - uiStyleElement.parentNode.removeChild(uiStyleElement); - console.log('🧹 Cleaned up UI hiding styles'); - } - - // 恢复滚动位置 - if (canvasWrapper) { - canvasWrapper.scrollLeft = originalScrollLeft; - canvasWrapper.scrollTop = originalScrollTop; - console.log('🔄 Restored original scroll position'); - } - - console.log('🧹 Cleanup complete'); - } - } - - - // 在指定的 leaf 中查找 Canvas DOM 元素 - async findCanvasDomInLeaf(leaf: any): Promise { - console.log('🔍 Searching for canvas DOM in leaf...'); - - // 获取 leaf 的容器 - const container = leaf.containerEl; - if (!container) { - console.log('❌ Leaf has no container'); - return null; - } - - console.log('📦 Leaf container:', container); - - // 在 leaf 容器中查找 Canvas(最多等待 20 秒) - const maxWait = 20000; - const startTime = Date.now(); - - return new Promise(resolve => { - const checkCanvas = () => { - const elapsed = Date.now() - startTime; - - if (elapsed > maxWait) { - console.log('⏰ Canvas render timeout after', maxWait, 'ms'); - resolve(null); - return; - } - - // 尝试多种可能的选择器(在 leaf 容器内搜索) - const selectors = [ - '.canvas-view-content', - '.canvas-wrapper', - '.canvas-container', - '[data-type="canvas"]', - '.canvas-view' - ]; - - for (const selector of selectors) { - const canvas = container.querySelector(selector); - if (canvas) { - const nodes = canvas.querySelectorAll('.canvas-node'); - if (nodes.length > 0) { - console.log(`✅ Found canvas with selector: ${selector} (${elapsed}ms) with ${nodes.length} nodes`); - setTimeout(() => resolve(canvas), 500); - return; - } - } - } - - // 继续等待 - setTimeout(checkCanvas, 100); - }; - - console.log('⏳ Starting to wait for canvas render in leaf...'); - checkCanvas(); - }); - } - // 等待 Canvas 渲染完成 - async waitForCanvasRender(): Promise { - return new Promise(resolve => { - const maxWait = 20000; // 增加到 20 秒(新窗口需要更多时间) - const startTime = Date.now(); - - const checkCanvas = () => { - const elapsed = Date.now() - startTime; - - if (elapsed > maxWait) { - console.log('⏰ Canvas render timeout after', maxWait, 'ms'); - resolve(); - return; - } - - // 尝试多种可能的选择器 - const selectors = [ - '.canvas-view-content', - '.canvas-wrapper', - '.canvas-container', - '[data-type="canvas"]', - '.workspace-leaf-content .canvas-view' - ]; - - for (const selector of selectors) { - const canvas = document.querySelector(selector); - if (canvas) { - // 检查是否有节点 - const nodes = canvas.querySelectorAll('.canvas-node'); - if (nodes.length > 0) { - console.log(`✅ Canvas rendered using selector: ${selector} (${elapsed}ms) with ${nodes.length} nodes`); - // 额外等待确保渲染完全完成 - setTimeout(resolve, 1000); - return; - } - } - // 继续等待 - } - setTimeout(checkCanvas, 100); - }; - - console.log('⏳ Starting to wait for canvas render...'); - checkCanvas(); - }); - } - - // 查找 Canvas DOM 元素 - findCanvasDomElement(): Element | null { - console.log('🔍 Searching for canvas DOM elements...'); - - // 尝试多种可能的选择器 - const selectors = [ - '.canvas-view-content', - '.canvas-wrapper', - '.canvas-container', - '[data-type="canvas"]', - '.workspace-leaf-content .canvas-view', - '.canvas-view' - ]; - - for (const selector of selectors) { - const element = document.querySelector(selector); - if (element) { - console.log('✅ Found canvas element with selector: "' + selector + '"'); - console.log(' Element:', element.tagName, element.className); - // @ts-ignore - HTMLElement 类型扩展 - console.log(' Size:', element.offsetWidth, 'x', element.offsetHeight); - console.log(' Children:', element.children.length); - return element; - } - } - - console.log('❌ No canvas element found'); - return null; - } - - // 从 Canvas JSON 渲染图片 - async renderCanvasFromJSON(canvasFile: TFile): Promise { - try { - console.log('📖 Reading canvas JSON...'); - const { vault } = this.app; - - // 读取 Canvas JSON - const content = await vault.read(canvasFile); - const canvasData = JSON.parse(content); - - console.log('📊 Canvas data:', canvasData); - - // 解析节点和边 - const nodes = canvasData.nodes || []; - const edges = canvasData.edges || []; - - console.log(`📦 Found ${nodes.length} nodes and ${edges.length} edges`); - - if (nodes.length === 0) { - console.log('⚠️ No nodes found in canvas'); - return null; - } - - // 计算画布边界 - let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - - for (const node of nodes) { - const x = node.x || 0; - const y = node.y || 0; - const width = node.width || 200; - const height = node.height || 100; - - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x + width); - maxY = Math.max(maxY, y + height); - } - - // 添加 padding - const padding = 50; - minX -= padding; - minY -= padding; - maxX += padding; - maxY += padding; - - const canvasWidth = maxX - minX; - const canvasHeight = maxY - minY; - - console.log(`📐 Canvas size: ${canvasWidth} x ${canvasHeight}`); - - // 创建 Canvas - const canvas = document.createElement('canvas'); - canvas.width = canvasWidth; - canvas.height = canvasHeight; - const ctx = canvas.getContext('2d'); - - if (!ctx) { - console.log('❌ Failed to get canvas context'); - return null; - } - - // 填充背景 - ctx.fillStyle = '#ffffff'; - ctx.fillRect(0, 0, canvasWidth, canvasHeight); - - // 绘制边(连接线) - console.log('🔗 Drawing edges...'); - ctx.strokeStyle = '#999999'; - ctx.lineWidth = 2; - - for (const edge of edges) { - const fromNode = nodes.find((n: any) => n.id === edge.fromNode || n.id === edge.from); - const toNode = nodes.find((n: any) => n.id === edge.toNode || n.id === edge.to); - - if (fromNode && toNode) { - const fromX = fromNode.x + (fromNode.width || 200) / 2 - minX; - const fromY = fromNode.y + (fromNode.height || 100) / 2 - minY; - const toX = toNode.x + (toNode.width || 200) / 2 - minX; - const toY = toNode.y + (toNode.height || 100) / 2 - minY; - - ctx.beginPath(); - ctx.moveTo(fromX, fromY); - ctx.lineTo(toX, toY); - ctx.stroke(); - } - } - - // 绘制节点 - console.log('🎨 Drawing nodes...'); - for (const node of nodes) { - await this.drawCanvasNode(ctx, node, minX, minY); - } - - console.log('💾 Converting to Uint8Array...'); - - // 转换为 Uint8Array - const dataUrl = canvas.toDataURL('image/png'); - const base64Data = dataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - return bytes; - - } catch (error) { - console.error('❌ Error rendering canvas from JSON:', error); - return null; - } - } - - // 绘制单个 Canvas 节点 - async drawCanvasNode(ctx: CanvasRenderingContext2D, node: any, offsetX: number, offsetY: number): Promise { - const x = (node.x || 0) - offsetX; - const y = (node.y || 0) - offsetY; - const width = node.width || 200; - const height = node.height || 100; - - console.log(` Drawing node "${node.id}" at (${x}, ${y})`); - - // 设置背景颜色 - let bgColor = '#f0f0f0'; - if (node.color) { - const colorMap: Record = { - '1': '#ff6b6b', - '2': '#4ecdc4', - '3': '#45b7d1', - '4': '#96ceb4', - '5': '#ffeaa7', - '6': '#dfe6e9' - }; - bgColor = colorMap[node.color] || node.color; - } - - // 绘制节点背景 - ctx.fillStyle = bgColor; - ctx.fillRect(x, y, width, height); - - // 绘制边框 - ctx.strokeStyle = '#cccccc'; - ctx.lineWidth = 2; - ctx.strokeRect(x, y, width, height); - - // 绘制文本内容 - if (node.type === 'text' && node.text) { - ctx.fillStyle = '#333333'; - ctx.font = '14px sans-serif'; - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - - // 简单的文本换行处理 - const padding = 10; - const maxWidth = width - padding * 2; - const lineHeight = 20; - - this.wrapText(ctx, node.text, x + padding, y + padding, maxWidth, lineHeight); - } else if (node.type === 'file' && node.file) { - ctx.fillStyle = '#333333'; - ctx.font = 'bold 14px sans-serif'; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - - // 显示文件名 - const fileName = node.file.split('/').pop(); - ctx.fillText(fileName || node.file, x + width / 2, y + height / 2); - } else if (node.label) { - ctx.fillStyle = '#333333'; - ctx.font = 'bold 16px sans-serif'; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillText(node.label, x + width / 2, y + height / 2); - } - } - - // 文本换行辅助函数 - wrapText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number): void { - const words = text.split(' '); - let line = ''; - let currentY = y; - - for (let i = 0; i < words.length; i++) { - const testLine = line + words[i] + ' '; - const metrics = ctx.measureText(testLine); - const testWidth = metrics.width; - - if (testWidth > maxWidth && i > 0) { - ctx.fillText(line, x, currentY); - line = words[i] + ' '; - currentY += lineHeight; - } else { - line = testLine; - } - } - - ctx.fillText(line, x, currentY); - } - - // 生成占位图 - generatePlaceholderImage(canvasFile: TFile): Uint8Array | null { - try { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - - if (!ctx) return null; - - // 设置占位图尺寸 - canvas.width = 800; - canvas.height = 600; - - // 绘制背景 - ctx.fillStyle = '#f0f0f0'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // 绘制边框 - ctx.strokeStyle = '#ccc'; - ctx.lineWidth = 2; - ctx.strokeRect(10, 10, canvas.width - 20, canvas.height - 20); - - // 绘制文字 - ctx.fillStyle = '#666'; - ctx.font = '24px Arial'; - ctx.textAlign = 'center'; - ctx.fillText('Canvas 占位图', canvas.width / 2, canvas.height / 2 - 20); - - ctx.font = '16px Arial'; - ctx.fillText(canvasFile.name, canvas.width / 2, canvas.height / 2 + 20); - ctx.font = '14px Arial'; - ctx.fillText('(需要手动导出或等待原生渲染支持)', canvas.width / 2, canvas.height / 2 + 50); - - // 转换为 Uint8Array - const dataUrl = canvas.toDataURL('image/png'); - const base64Data = dataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - return bytes; - - } catch (error) { - console.error('Error generating placeholder image:', error); - return null; - } - } - - // 更新内容中的 Canvas 链接 - updateCanvasLinksInContent(content: string, canvasFile: TFile, canvasPath: string, imageFileName: string): string { - // 获取源文件的目录路径 - const sourceDir = canvasFile.path.substring(0, canvasFile.path.lastIndexOf('/')); - if (!sourceDir) return content; - - // 尝试多种可能的路径格式 - const possiblePaths = [ - // 完整路径 - canvasPath, - // 相对于源文件的路径 - canvasPath.substring(sourceDir.length + 1), - // URL 编码版本 - encodeURI(canvasPath), - encodeURI(canvasPath.substring(sourceDir.length + 1)), - // 文件名(包括和不包括 .canvas 扩展名) - canvasFile.name, - canvasFile.name.replace('.canvas', ''), - encodeURI(canvasFile.name), - encodeURI(canvasFile.name.replace('.canvas', '')) - ]; - - console.log('Trying to replace canvas links for paths:', possiblePaths); - - // 替换 markdown 格式: !(canvas) -> - const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; - content = content.replace(markdownRegex, (match, alt, path) => { - // 检查这个路径是否匹配我们的 canvas 文件 - for (const testPath of possiblePaths) { - if (path === testPath || path === testPath.replace(/^\//, '')) { - const relativePath = this.settings.assetsPath.replace('docs/', ''); - console.log(`Found matching canvas link: ${path} -> `); - return ``; - } - } - return match; - }); - - // 替换 wikilink 格式: ![[canvas]] -> - const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; - content = content.replace(wikilinkRegex, (match, link) => { - // 移除可能的别名字段 - const cleanLink = link.split('|')[0].trim(); - - for (const testPath of possiblePaths) { - if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { - const relativePath = this.settings.assetsPath.replace('docs/', ''); - console.log(`Found matching canvas wikilink: ${cleanLink} -> `); - return ``; - } - } - return match; - }); - - return content; - } -} - -// 设置面板 -class VitePressExporterSettingTab extends PluginSettingTab { - plugin: VitePressExporterPlugin; - - constructor(app: App, plugin: VitePressExporterPlugin) { - super(app, plugin); - this.plugin = plugin; - } - - display(): void { - const { containerEl } = this; - - containerEl.empty(); - - containerEl.createEl('h2', { text: 'VitePress Exporter Settings' }); - - new Setting(containerEl) - .setName('Docs path') - .setDesc('Path to the docs directory (relative to vault root)') - .addText(text => text - .setPlaceholder('docs') - .setValue(this.plugin.settings.docsPath) - .onChange(async (value) => { - this.plugin.settings.docsPath = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName('Assets path') - .setDesc('Path to the assets directory (relative to vault root)') - .addText(text => text - .setPlaceholder('docs/assets') - .setValue(this.plugin.settings.assetsPath) - .onChange(async (value) => { - this.plugin.settings.assetsPath = value; - await this.plugin.saveSettings(); - })); - } -} diff --git a/main.ts.backup b/main.ts.backup deleted file mode 100644 index b40f6d1..0000000 --- a/main.ts.backup +++ /dev/null @@ -1,1145 +0,0 @@ -import { App, Plugin, PluginSettingTab, Setting, TFile, Notice } from 'obsidian'; - -interface VitePressExporterSettings { - docsPath: string; - assetsPath: string; -} - -const DEFAULT_SETTINGS: VitePressExporterSettings = { - docsPath: 'docs', - assetsPath: 'docs/assets' -} - -export default class VitePressExporterPlugin extends Plugin { - settings: VitePressExporterSettings; - - async onload() { - await this.loadSettings(); - - // 添加导出命令 - this.addCommand({ - id: 'export-to-vitepress', - name: 'Export current note to VitePress', - callback: () => { - this.exportCurrentNote(); - } - }); - - // 添加功能区按钮 - this.addRibbonIcon('upload', 'Export to VitePress', () => { - this.exportCurrentNote(); - }); - - // 添加设置面板 - this.addSettingTab(new VitePressExporterSettingTab(this.app, this)); - - console.log('VitePress Exporter plugin loaded'); - } - - onunload() { - console.log('VitePress Exporter plugin unloaded'); - } - - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } - - async saveSettings() { - await this.saveData(this.settings); - } - - // 导出当前笔记 - async exportCurrentNote() { - const activeFile = this.app.workspace.getActiveFile(); - - if (!activeFile) { - new Notice('No active file found'); - return; - } - - if (activeFile.extension !== 'md') { - new Notice('Current file is not a markdown file'); - return; - } - - new Notice(`Exporting ${activeFile.name} to VitePress...`); - - try { - await this.exportNote(activeFile); - new Notice(`Successfully exported ${activeFile.name} to VitePress`); - } catch (error) { - console.error('Export failed:', error); - new Notice(`Export failed: ${error.message}`); - } - } - - // 导出单个笔记 - async exportNote(file: TFile) { - const { vault } = this.app; - - // 使用 binary 模式读取文件以保留原始格式(包括行尾空格) - const contentBuffer = await vault.readBinary(file); - const content = new TextDecoder().decode(contentBuffer); - - // 1. 扫描并复制所有资源文件(传入文件对象用于路径解析) - const updatedContent = await this.processAssets(content, file); - - // 2. 处理 canvas 引用(暂时保留,后续实现) - // const finalContent = await this.processCanvases(updatedContent); - - // 3. 写入到 docs 目录(使用 binary 模式保留原始格式) - const docsPath = `${this.settings.docsPath}/${file.name}`; - const updatedBuffer = new TextEncoder().encode(updatedContent); - await vault.adapter.writeBinary(docsPath, updatedBuffer); - - console.log(`Exported ${file.name} to ${docsPath}`); - } - - // 处理资源文件 - async processAssets(content: string, sourceFile: TFile): Promise { - const { vault, metadataCache } = this.app; - - console.log('Processing assets for file:', sourceFile.path); - - // 使用 Obsidian API 获取文件的所有嵌入和链接 - const cache = metadataCache.getCache(sourceFile.path); - - console.log('Cache:', cache); - console.log('Embeds:', cache?.embeds); - console.log('Links:', cache?.links); - - if (!cache) { - console.log('No cache found for file'); - return content; - } - - const assetsToCopy = new Set(); - const canvasFiles = new Set(); - - // 收集嵌入文件(图片等) - if (cache.embeds) { - for (const embed of cache.embeds) { - console.log('Processing embed:', embed); - const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); - console.log('Resolved link for embed:', resolvedLink?.path); - if (resolvedLink) { - // 检查是否是 canvas 文件 - if (resolvedLink.extension === 'canvas') { - canvasFiles.add(resolvedLink.path); - } else { - assetsToCopy.add(resolvedLink.path); - } - } - } - } - - // 收集普通链接(可选,如果也想复制链接的文件) - if (cache.links) { - for (const link of cache.links) { - const resolvedLink = metadataCache.getFirstLinkpathDest(link.link, sourceFile.path); - // 只复制本地文件链接,不包括其他 md 文件 - if (resolvedLink && resolvedLink.extension !== 'md') { - assetsToCopy.add(resolvedLink.path); - } - } - } - - console.log('Assets to copy:', Array.from(assetsToCopy)); - console.log('Canvas files to render:', Array.from(canvasFiles)); - - // 处理 Canvas 文件:渲染为图片 - for (const canvasPath of canvasFiles) { - try { - const canvasFile = vault.getAbstractFileByPath(canvasPath); - if (canvasFile instanceof TFile) { - const renderedImage = await this.renderCanvasToImage(canvasFile); - if (renderedImage) { - const imageFileName = canvasFile.name.replace('.canvas', '.png'); - // 图片保存到 docs/assets/ - const imagePath = `${this.settings.assetsPath}/${imageFileName}`; - - // 确保目标目录存在 - await vault.adapter.mkdir(this.settings.assetsPath); - - // 写入渲染的图片 - await vault.adapter.writeBinary(imagePath, renderedImage); - - // 更新内容中的 canvas 引用,使用相对路径 assets/xxx.png - content = this.updateCanvasLinksInContent(content, canvasFile, canvasPath, imageFileName); - - console.log(`Successfully rendered canvas: ${canvasPath} -> ${imagePath}`); - } - } - } catch (error) { - console.error(`Failed to render canvas ${canvasPath}:`, error); - } - } - - // 复制资源文件到 docs/assets - for (const assetPath of assetsToCopy) { - try { - const sourceFile = vault.getAbstractFileByPath(assetPath); - console.log('Source file for asset:', sourceFile); - - if (sourceFile instanceof TFile) { - // 使用 binary 读取模式来保留文件原始内容 - const assetContent = await vault.readBinary(sourceFile); - const fileName = sourceFile.name; - const destPath = `${this.settings.assetsPath}/${fileName}`; - - console.log('Copying asset:', assetPath, '->', destPath); - - // 确保目标目录存在 - await vault.adapter.mkdir(this.settings.assetsPath); - - // 写入资源文件(使用 binary 模式) - await vault.adapter.writeBinary(destPath, assetContent); - - // 更新内容中的资源路径(使用更智能的替换) - content = this.updateLinksInContent(content, sourceFile, assetPath, fileName); - - console.log(`Successfully copied asset: ${assetPath} -> ${destPath}`); - } - } catch (error) { - console.error(`Failed to copy asset ${assetPath}:`, error); - } - } - - return content; - } - - // 获取原始链接文本 - getOriginalLink(content: string, targetPath: string, sourcePath: string): string | null { - const { metadataCache } = this.app; - - // 尝试多种可能的链接格式 - const possibleFormats = [ - // Wikilink 格式 - new RegExp(`!\\[\\[${this.escapeRegExp(targetPath)}(\\|[^\\]]*)?\\]\\]`, 'g'), - new RegExp(`\\[\\[${this.escapeRegExp(targetPath)}(\\|[^\\]]*)?\\]\\]`, 'g'), - // Markdown 格式 - new RegExp(`!\\[.*?\\]\\(${this.escapeRegExp(targetPath)}\\)`, 'g'), - new RegExp(`\\[.*?\\]\\(${this.escapeRegExp(targetPath)}\\)`, 'g'), - // 相对路径格式 - new RegExp(`!\\[\\[${this.escapeRegExp(this.getRelativePath(targetPath, sourcePath))}(\\|[^\\]]*)?\\]\\]`, 'g'), - ]; - - for (const regex of possibleFormats) { - const match = content.match(regex); - if (match) { - return match[0]; - } - } - - return null; - } - - // 更新内容中的链接 - updateLinksInContent(content: string, sourceFile: TFile, assetPath: string, newFileName: string): string { - // 获取源文件的目录路径 - const sourceDir = sourceFile.path.substring(0, sourceFile.path.lastIndexOf('/')); - if (!sourceDir) return content; - - // 尝试多种可能的路径格式 - const possiblePaths = [ - // 完整路径 - assetPath, - // 相对于源文件的路径 - assetPath.substring(sourceDir.length + 1), - // URL 编码版本 - encodeURI(assetPath), - encodeURI(assetPath.substring(sourceDir.length + 1)), - // 文件名 - sourceFile.name, - encodeURI(sourceFile.name) - ]; - - console.log('Trying to replace links for paths:', possiblePaths); - - // 替换 markdown 格式: ![](path) -> ![](assets/newfile.png) - const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; - content = content.replace(markdownRegex, (match, alt, path) => { - // 检查这个路径是否匹配我们的目标文件 - for (const testPath of possiblePaths) { - if (path === testPath || path === testPath.replace(/^\//, '')) { - console.log(`Found matching link: ${path} -> ${this.settings.assetsPath}/${newFileName}`); - return `![](${this.settings.assetsPath}/${newFileName})`; - } - } - return match; - }); - - // 替换 wikilink 格式: ![[path]] -> ![[assets/newfile.png]] - const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; - content = content.replace(wikilinkRegex, (match, link) => { - // 移除可能的别名字段 - const cleanLink = link.split('|')[0].trim(); - - for (const testPath of possiblePaths) { - if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { - console.log(`Found matching wikilink: ${cleanLink} -> ${this.settings.assetsPath}/${newFileName}`); - return `![[${this.settings.assetsPath}/${newFileName}]]`; - } - } - return match; - }); - - return content; - } - - // 辅助函数:转义正则表达式特殊字符 - escapeRegExp(string: string): string { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - } - - // 辅助函数:获取相对路径 - getRelativePath(targetPath: string, sourcePath: string): string { - // 简化的相对路径计算 - const targetParts = targetPath.split('/'); - const sourceParts = sourcePath.split('/'); - - // 移除文件名 - sourceParts.pop(); - - let commonIndex = 0; - while (commonIndex < Math.min(targetParts.length - 1, sourceParts.length) && - targetParts[commonIndex] === sourceParts[commonIndex]) { - commonIndex++; - } - - const relativeParts = []; - for (let i = commonIndex; i < sourceParts.length; i++) { - relativeParts.push('..'); - } - - return [...relativeParts, ...targetParts.slice(commonIndex)].join('/'); - } - - // 渲染 Canvas 为图片(使用 Obsidian 原生渲染) - async renderCanvasToImage(canvasFile: TFile): Promise { - try { - console.log('🎯 Attempting to render canvas using Obsidian native rendering:', canvasFile.path); - - // 使用 Workspace API 打开 Canvas 并捕获原生渲染 - const nativeImage = await this.tryNativeCanvasCapture(canvasFile); - if (nativeImage) { - console.log('✅ Successfully captured native Obsidian canvas rendering'); - return nativeImage; - } - - console.log('⚠️ Native capture failed, using placeholder'); - // 降级方案:生成占位图 - return this.generatePlaceholderImage(canvasFile); - - } catch (error) { - console.error('❌ Error rendering canvas:', error); - return this.generatePlaceholderImage(canvasFile); - } - } - - - // 隐藏 Canvas UI 元素(用于导出时) - hideCanvasUIElements(): HTMLStyleElement { - const styleElement = document.createElement('style'); - styleElement.id = 'canvas-export-hide-ui'; - styleElement.textContent = ` - /* 隐藏 Canvas 控制按钮 */ - .canvas-control-menu, - .canvas-card-menu, - .canvas-node-menu-button, - .canvas-node:hover .canvas-node-menu-button, - .canvas-controls, - .canvas-help-button { - display: none !important; - } - - /* 移除选中状态的高亮 */ - .canvas-node.is-selected, - .canvas-node.is-focused, - .canvas-edge.is-selected { - box-shadow: none !important; - outline: none !important; - } - - /* 隐藏工具提示和弹出菜单 */ - .tooltip, - .popover, - .modal { - display: none !important; - } - - /* 隐藏滚动条但保留滚动功能 */ - .canvas-view-content::-webkit-scrollbar { - display: none !important; - } - - /* 确保内容不被裁切 */ - .canvas-view-content { - overflow: visible !important; - } - - /* Privacy Mode: 防止卡片内容因缩放被隐藏 */ - .canvas-node-content-hidden { - display: block !important; - opacity: 1 !important; - } - - /* 确保所有卡片内容始终可见 */ - .canvas-node-content { - display: block !important; - opacity: 1 !important; - } - - /* 防止卡片被折叠 */ - .canvas-node .canvas-node-content { - display: block !important; - } - `; - document.head.appendChild(styleElement); - console.log('✅ Canvas UI elements hidden for export (privacy mode enabled)'); - return styleElement; - } - - // 计算实际的 Canvas 内容尺寸和偏移 - getCanvasContentSize(canvasDom: Element): { width: number; height: number; offsetX: number; offsetY: number } { - const nodes = canvasDom.querySelectorAll('.canvas-node'); - console.log(`📐 Found ${nodes.length} canvas nodes`); - - if (nodes.length === 0) { - // 降级方案:使用容器尺寸 - return { - width: (canvasDom as any).offsetWidth || 800, - height: (canvasDom as any).offsetHeight || 600, - offsetX: 0, - offsetY: 0 - }; - } - - // 计算所有节点的边界框 - let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - - nodes.forEach(node => { - const rect = node.getBoundingClientRect(); - const canvasRect = canvasDom.getBoundingClientRect(); - - // 计算相对于 Canvas 的位置 - const relativeX = rect.left - canvasRect.left; - const relativeY = rect.top - canvasRect.top; - - minX = Math.min(minX, relativeX); - minY = Math.min(minY, relativeY); - maxX = Math.max(maxX, relativeX + rect.width); - maxY = Math.max(maxY, relativeY + rect.height); - }); - - // 添加 padding - const padding = 50; - const offsetX = Math.max(0, minX - padding); - const offsetY = Math.max(0, minY - padding); - const contentWidth = maxX - minX + padding * 2; - const contentHeight = maxY - minY + padding * 2; - - console.log(`📐 Canvas: ${contentWidth}x${contentHeight}, offset: (${offsetX}, ${offsetY})`); - - return { width: contentWidth, height: contentHeight, offsetX, offsetY }; - } - - - // 通过滚动拼接捕获完整 Canvas - async captureCanvasByScrolling( - canvasDom: Element, - contentSize: { width: number; height: number; offsetX: number; offsetY: number } - ): Promise { - try { - // 检查 canvasDom 本身是否就是 wrapper,或者 wrapper 是其子元素 - let canvasWrapper: HTMLElement | null = null; - if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) { - console.log('📦 canvasDom itself is the wrapper'); - canvasWrapper = canvasDom as HTMLElement; - } else { - canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement; - if (!canvasWrapper) { - console.log('❌ No canvas wrapper found'); - return null; - } - } - - // 使用 canvasWrapper 获取视口尺寸 - const viewportWidth = canvasWrapper.offsetWidth; - const viewportHeight = canvasWrapper.offsetHeight; - const totalWidth = contentSize.width; - const totalHeight = contentSize.height; - - console.log(`📐 Viewport: ${viewportWidth}x${viewportHeight}, Total: ${totalWidth}x${totalHeight}`); - - // 如果内容小于视口,直接捕获 - if (totalWidth <= viewportWidth && totalHeight <= viewportHeight) { - console.log('📸 Content fits in viewport, single capture'); - return null; // 让降级处理 - } - - // 计算需要分块的数量 - const cols = Math.ceil(totalWidth / viewportWidth); - const rows = Math.ceil(totalHeight / viewportHeight); - console.log(`🧩 Will capture ${cols}x${rows} = ${cols * rows} tiles`); - console.log(`📍 Content offset: (${contentSize.offsetX}, ${contentSize.offsetY})`); - - // 保存原始滚动位置 - const originalScrollLeft = canvasWrapper.scrollLeft; - const originalScrollTop = canvasWrapper.scrollTop; - - // 创建最终拼接的 Canvas - const finalCanvas = document.createElement('canvas'); - finalCanvas.width = totalWidth; - finalCanvas.height = totalHeight; - const ctx = finalCanvas.getContext('2d'); - if (!ctx) { - console.log('❌ Failed to get canvas context'); - return null; - } - - // 填充白色背景 - ctx.fillStyle = '#ffffff'; - ctx.fillRect(0, 0, totalWidth, totalHeight); - - // @ts-ignore - const domToImage = require('dom-to-image-more'); - - // 分块捕获并拼接 - for (let row = 0; row < rows; row++) { - for (let col = 0; col < cols; col++) { - const x = col * viewportWidth; - const y = row * viewportHeight; - - // 滚动到对应位置 (确保从内容起始位置开始) - const targetScrollLeft = Math.max(0, contentSize.offsetX + x); - const targetScrollTop = Math.max(0, contentSize.offsetY + y); - canvasWrapper.scrollLeft = targetScrollLeft; - canvasWrapper.scrollTop = targetScrollTop; - console.log(`🔄 Scrolled to (${targetScrollLeft}, ${targetScrollTop})`); - - // 等待渲染 - await new Promise(resolve => setTimeout(resolve, 150)); - - // 捕获当前视口 - const tileDataUrl = await domToImage.toPng(canvasDom, { - backgroundColor: '#ffffff', - quality: 1, - width: viewportWidth, - height: viewportHeight - }); - - // 加载图片并绘制到最终 Canvas - const img = await this.loadImage(tileDataUrl); - if (img) { - const drawWidth = Math.min(viewportWidth, totalWidth - x); - const drawHeight = Math.min(viewportHeight, totalHeight - y); - ctx.drawImage(img, 0, 0, drawWidth, drawHeight, x, y, drawWidth, drawHeight); - console.log(`✅ Tile [${row},${col}] at (${x},${y}) size ${drawWidth}x${drawHeight}`); - } - } - } - - // 恢复滚动位置 - canvasWrapper.scrollLeft = originalScrollLeft; - canvasWrapper.scrollTop = originalScrollTop; - - // 转换为 Uint8Array - const finalDataUrl = finalCanvas.toDataURL('image/png'); - const base64Data = finalDataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - console.log('✅ Stitched canvas complete'); - return bytes; - - } catch (error) { - console.error('❌ Scroll and stitch failed:', error); - return null; - } - } - - // 加载图片 - async loadImage(dataUrl: string): Promise { - return new Promise((resolve) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = () => resolve(null); - img.src = dataUrl; - }); - } - - // 将 DataURL 转换为 Uint8Array - dataUrlToUint8Array(dataUrl: string): Uint8Array { - const base64Data = dataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - return bytes; - } - - // 尝试捕获 Obsidian 原生 Canvas 渲染 - async tryNativeCanvasCapture(canvasFile: TFile): Promise { - let uiStyleElement: HTMLStyleElement | null = null; - let tempLeaf: any = null; - - try { - console.log('🔍 Step 1: Creating independent hidden window for rendering...'); - - // 创建一个新的分割窗口用于渲染(不影响用户当前视图) - // @ts-ignore - 使用 Obsidian 的 splitActiveLeaf API - tempLeaf = this.app.workspace.splitActiveLeaf('vertical'); - if (!tempLeaf) { - console.log('⚠️ Could not create split leaf, using active leaf'); - tempLeaf = this.app.workspace.activeLeaf; - } - - console.log('🔍 Step 2: Opening canvas file in independent window...'); - await tempLeaf.openFile(canvasFile); - - console.log('⏳ Step 3: Waiting for canvas render...'); - await this.waitForCanvasRender(); - - console.log('🔍 Step 4: Finding canvas DOM...'); - const canvasDom = this.findCanvasDomElement(); - if (!canvasDom) { - console.log('❌ Could not find canvas DOM element'); - return null; - } - - console.log('✅ Found canvas DOM:', canvasDom.className, 'Size:', (canvasDom as any).offsetWidth, 'x', (canvasDom as any).offsetHeight); - - console.log('🎨 Step 4.5: Hiding Canvas UI elements...'); - uiStyleElement = this.hideCanvasUIElements(); - - console.log('📐 Step 4.6: Calculating canvas content size...'); - const contentSize = this.getCanvasContentSize(canvasDom); - - console.log('📸 Step 5: Determining capture strategy...'); - - // 获取视口尺寸 - const viewportWidth = (canvasDom as any).offsetWidth || 800; - const viewportHeight = (canvasDom as any).offsetHeight || 600; - - console.log(` Viewport: ${viewportWidth}x${viewportHeight}, Content: ${contentSize.width}x${contentSize.height}`); - console.log(` Offset: (${contentSize.offsetX}, ${contentSize.offsetY})`); - - let imageData: Uint8Array | null = null; - - // 判断是否需要滚动拼接 - if (contentSize.width > viewportWidth || contentSize.height > viewportHeight) { - // 大画布:使用滚动拼接方法 - console.log('🧩 Using scroll-and-stitch for large canvas...'); - imageData = await this.captureCanvasByScrolling(canvasDom, contentSize); - } else { - // 小画布:使用单次捕获,但需要调整 offset - console.log('📸 Using single capture for small canvas...'); - - // 滚动到正确位置以确保内容在视野中 - // 获取 canvasWrapper(处理 canvasDom 本身就是 wrapper 的情况) - let canvasWrapper: HTMLElement | null = null; - if ((canvasDom as HTMLElement).classList.contains('canvas-wrapper')) { - canvasWrapper = canvasDom as HTMLElement; - } else { - canvasWrapper = canvasDom.querySelector('.canvas-wrapper') as HTMLElement; - } - if (canvasWrapper) { - const originalScrollLeft = canvasWrapper.scrollLeft; - const originalScrollTop = canvasWrapper.scrollTop; - - // 滚动到内容起始位置 - canvasWrapper.scrollLeft = contentSize.offsetX; - canvasWrapper.scrollTop = contentSize.offsetY; - - // 等待滚动完成 - await new Promise(resolve => setTimeout(resolve, 200)); - - // @ts-ignore - const domToImage = require('dom-to-image-more'); - - const dataUrl = await domToImage.toPng(canvasDom, { - backgroundColor: '#ffffff', - quality: 1, - width: contentSize.width, - height: contentSize.height - }); - - imageData = this.dataUrlToUint8Array(dataUrl); - - // 恢复滚动位置 - canvasWrapper.scrollLeft = originalScrollLeft; - canvasWrapper.scrollTop = originalScrollTop; - } else { - // 降级方案:直接捕获整个 DOM - // @ts-ignore - const domToImage = require('dom-to-image-more'); - - const dataUrl = await domToImage.toPng(canvasDom, { - backgroundColor: '#ffffff', - quality: 1, - width: contentSize.width, - height: contentSize.height - }); - - imageData = this.dataUrlToUint8Array(dataUrl); - } - } - - if (imageData) { - console.log('✅ Successfully captured canvas! Size:', imageData.length, 'bytes'); - return imageData; - } - - console.log('❌ Capture failed, returning null'); - return null; - - } catch (error) { - console.error('❌ Native canvas capture failed:', error); - return null; - } finally { - if (uiStyleElement && uiStyleElement.parentNode) { - uiStyleElement.parentNode.removeChild(uiStyleElement); - console.log('🧹 Cleaned up UI hiding styles'); - } - - // 关闭临时窗口 - if (tempLeaf && tempLeaf !== this.app.workspace.activeLeaf) { - try { - // @ts-ignore - tempLeaf.detach(); - console.log('🧹 Closed temporary render window'); - } catch (e) { - console.log('⚠️ Could not close temporary leaf:', e); - } - } - } - } - - - // 等待 Canvas 渲染完成 - async waitForCanvasRender(): Promise { - return new Promise(resolve => { - const maxWait = 8000; // 最多等待 8 秒 - const startTime = Date.now(); - - const checkCanvas = () => { - const elapsed = Date.now() - startTime; - - if (elapsed > maxWait) { - console.log('⏰ Canvas render timeout after', maxWait, 'ms'); - resolve(); - return; - } - - // 尝试多种可能的选择器 - const selectors = [ - '.canvas-view-content', - '.canvas-wrapper', - '.canvas-container', - '[data-type="canvas"]', - '.workspace-leaf-content .canvas-view' - ]; - - for (const selector of selectors) { - const canvas = document.querySelector(selector); - if (canvas && canvas.childElementCount > 0) { - console.log(`✅ Canvas rendered using selector: ${selector} (${elapsed}ms)`); - // 额外等待确保渲染完全完成 - setTimeout(resolve, 500); - return; - } - } - - // 继续等待 - setTimeout(checkCanvas, 100); - }; - - console.log('⏳ Starting to wait for canvas render...'); - checkCanvas(); - }); - } - - // 查找 Canvas DOM 元素 - findCanvasDomElement(): Element | null { - console.log('🔍 Searching for canvas DOM elements...'); - - // 尝试多种可能的选择器 - const selectors = [ - '.canvas-view-content', - '.canvas-wrapper', - '.canvas-container', - '[data-type="canvas"]', - '.workspace-leaf-content .canvas-view', - '.canvas-view' - ]; - - for (const selector of selectors) { - const element = document.querySelector(selector); - if (element) { - console.log('✅ Found canvas element with selector: "' + selector + '"'); - console.log(' Element:', element.tagName, element.className); - // @ts-ignore - HTMLElement 类型扩展 - console.log(' Size:', element.offsetWidth, 'x', element.offsetHeight); - console.log(' Children:', element.children.length); - return element; - } - } - - console.log('❌ No canvas element found'); - return null; - } - - // 从 Canvas JSON 渲染图片 - async renderCanvasFromJSON(canvasFile: TFile): Promise { - try { - console.log('📖 Reading canvas JSON...'); - const { vault } = this.app; - - // 读取 Canvas JSON - const content = await vault.read(canvasFile); - const canvasData = JSON.parse(content); - - console.log('📊 Canvas data:', canvasData); - - // 解析节点和边 - const nodes = canvasData.nodes || []; - const edges = canvasData.edges || []; - - console.log(`📦 Found ${nodes.length} nodes and ${edges.length} edges`); - - if (nodes.length === 0) { - console.log('⚠️ No nodes found in canvas'); - return null; - } - - // 计算画布边界 - let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - - for (const node of nodes) { - const x = node.x || 0; - const y = node.y || 0; - const width = node.width || 200; - const height = node.height || 100; - - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x + width); - maxY = Math.max(maxY, y + height); - } - - // 添加 padding - const padding = 50; - minX -= padding; - minY -= padding; - maxX += padding; - maxY += padding; - - const canvasWidth = maxX - minX; - const canvasHeight = maxY - minY; - - console.log(`📐 Canvas size: ${canvasWidth} x ${canvasHeight}`); - - // 创建 Canvas - const canvas = document.createElement('canvas'); - canvas.width = canvasWidth; - canvas.height = canvasHeight; - const ctx = canvas.getContext('2d'); - - if (!ctx) { - console.log('❌ Failed to get canvas context'); - return null; - } - - // 填充背景 - ctx.fillStyle = '#ffffff'; - ctx.fillRect(0, 0, canvasWidth, canvasHeight); - - // 绘制边(连接线) - console.log('🔗 Drawing edges...'); - ctx.strokeStyle = '#999999'; - ctx.lineWidth = 2; - - for (const edge of edges) { - const fromNode = nodes.find((n: any) => n.id === edge.fromNode || n.id === edge.from); - const toNode = nodes.find((n: any) => n.id === edge.toNode || n.id === edge.to); - - if (fromNode && toNode) { - const fromX = fromNode.x + (fromNode.width || 200) / 2 - minX; - const fromY = fromNode.y + (fromNode.height || 100) / 2 - minY; - const toX = toNode.x + (toNode.width || 200) / 2 - minX; - const toY = toNode.y + (toNode.height || 100) / 2 - minY; - - ctx.beginPath(); - ctx.moveTo(fromX, fromY); - ctx.lineTo(toX, toY); - ctx.stroke(); - } - } - - // 绘制节点 - console.log('🎨 Drawing nodes...'); - for (const node of nodes) { - await this.drawCanvasNode(ctx, node, minX, minY); - } - - console.log('💾 Converting to Uint8Array...'); - - // 转换为 Uint8Array - const dataUrl = canvas.toDataURL('image/png'); - const base64Data = dataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - return bytes; - - } catch (error) { - console.error('❌ Error rendering canvas from JSON:', error); - return null; - } - } - - // 绘制单个 Canvas 节点 - async drawCanvasNode(ctx: CanvasRenderingContext2D, node: any, offsetX: number, offsetY: number): Promise { - const x = (node.x || 0) - offsetX; - const y = (node.y || 0) - offsetY; - const width = node.width || 200; - const height = node.height || 100; - - console.log(` Drawing node "${node.id}" at (${x}, ${y})`); - - // 设置背景颜色 - let bgColor = '#f0f0f0'; - if (node.color) { - const colorMap: Record = { - '1': '#ff6b6b', - '2': '#4ecdc4', - '3': '#45b7d1', - '4': '#96ceb4', - '5': '#ffeaa7', - '6': '#dfe6e9' - }; - bgColor = colorMap[node.color] || node.color; - } - - // 绘制节点背景 - ctx.fillStyle = bgColor; - ctx.fillRect(x, y, width, height); - - // 绘制边框 - ctx.strokeStyle = '#cccccc'; - ctx.lineWidth = 2; - ctx.strokeRect(x, y, width, height); - - // 绘制文本内容 - if (node.type === 'text' && node.text) { - ctx.fillStyle = '#333333'; - ctx.font = '14px sans-serif'; - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - - // 简单的文本换行处理 - const padding = 10; - const maxWidth = width - padding * 2; - const lineHeight = 20; - - this.wrapText(ctx, node.text, x + padding, y + padding, maxWidth, lineHeight); - } else if (node.type === 'file' && node.file) { - ctx.fillStyle = '#333333'; - ctx.font = 'bold 14px sans-serif'; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - - // 显示文件名 - const fileName = node.file.split('/').pop(); - ctx.fillText(fileName || node.file, x + width / 2, y + height / 2); - } else if (node.label) { - ctx.fillStyle = '#333333'; - ctx.font = 'bold 16px sans-serif'; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillText(node.label, x + width / 2, y + height / 2); - } - } - - // 文本换行辅助函数 - wrapText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number): void { - const words = text.split(' '); - let line = ''; - let currentY = y; - - for (let i = 0; i < words.length; i++) { - const testLine = line + words[i] + ' '; - const metrics = ctx.measureText(testLine); - const testWidth = metrics.width; - - if (testWidth > maxWidth && i > 0) { - ctx.fillText(line, x, currentY); - line = words[i] + ' '; - currentY += lineHeight; - } else { - line = testLine; - } - } - - ctx.fillText(line, x, currentY); - } - - // 生成占位图 - generatePlaceholderImage(canvasFile: TFile): Uint8Array | null { - try { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - - if (!ctx) return null; - - // 设置占位图尺寸 - canvas.width = 800; - canvas.height = 600; - - // 绘制背景 - ctx.fillStyle = '#f0f0f0'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // 绘制边框 - ctx.strokeStyle = '#ccc'; - ctx.lineWidth = 2; - ctx.strokeRect(10, 10, canvas.width - 20, canvas.height - 20); - - // 绘制文字 - ctx.fillStyle = '#666'; - ctx.font = '24px Arial'; - ctx.textAlign = 'center'; - ctx.fillText('Canvas 占位图', canvas.width / 2, canvas.height / 2 - 20); - - ctx.font = '16px Arial'; - ctx.fillText(canvasFile.name, canvas.width / 2, canvas.height / 2 + 20); - ctx.font = '14px Arial'; - ctx.fillText('(需要手动导出或等待原生渲染支持)', canvas.width / 2, canvas.height / 2 + 50); - - // 转换为 Uint8Array - const dataUrl = canvas.toDataURL('image/png'); - const base64Data = dataUrl.split(',')[1]; - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - - return bytes; - - } catch (error) { - console.error('Error generating placeholder image:', error); - return null; - } - } - - // 更新内容中的 Canvas 链接 - updateCanvasLinksInContent(content: string, canvasFile: TFile, canvasPath: string, imageFileName: string): string { - // 获取源文件的目录路径 - const sourceDir = canvasFile.path.substring(0, canvasFile.path.lastIndexOf('/')); - if (!sourceDir) return content; - - // 尝试多种可能的路径格式 - const possiblePaths = [ - // 完整路径 - canvasPath, - // 相对于源文件的路径 - canvasPath.substring(sourceDir.length + 1), - // URL 编码版本 - encodeURI(canvasPath), - encodeURI(canvasPath.substring(sourceDir.length + 1)), - // 文件名(包括和不包括 .canvas 扩展名) - canvasFile.name, - canvasFile.name.replace('.canvas', ''), - encodeURI(canvasFile.name), - encodeURI(canvasFile.name.replace('.canvas', '')) - ]; - - console.log('Trying to replace canvas links for paths:', possiblePaths); - - // 替换 markdown 格式: !(canvas) -> - const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; - content = content.replace(markdownRegex, (match, alt, path) => { - // 检查这个路径是否匹配我们的 canvas 文件 - for (const testPath of possiblePaths) { - if (path === testPath || path === testPath.replace(/^\//, '')) { - const relativePath = this.settings.assetsPath.replace('docs/', ''); - console.log(`Found matching canvas link: ${path} -> `); - return ``; - } - } - return match; - }); - - // 替换 wikilink 格式: ![[canvas]] -> - const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; - content = content.replace(wikilinkRegex, (match, link) => { - // 移除可能的别名字段 - const cleanLink = link.split('|')[0].trim(); - - for (const testPath of possiblePaths) { - if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { - const relativePath = this.settings.assetsPath.replace('docs/', ''); - console.log(`Found matching canvas wikilink: ${cleanLink} -> `); - return ``; - } - } - return match; - }); - - return content; - } -} - -// 设置面板 -class VitePressExporterSettingTab extends PluginSettingTab { - plugin: VitePressExporterPlugin; - - constructor(app: App, plugin: VitePressExporterPlugin) { - super(app, plugin); - this.plugin = plugin; - } - - display(): void { - const { containerEl } = this; - - containerEl.empty(); - - containerEl.createEl('h2', { text: 'VitePress Exporter Settings' }); - - new Setting(containerEl) - .setName('Docs path') - .setDesc('Path to the docs directory (relative to vault root)') - .addText(text => text - .setPlaceholder('docs') - .setValue(this.plugin.settings.docsPath) - .onChange(async (value) => { - this.plugin.settings.docsPath = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName('Assets path') - .setDesc('Path to the assets directory (relative to vault root)') - .addText(text => text - .setPlaceholder('docs/assets') - .setValue(this.plugin.settings.assetsPath) - .onChange(async (value) => { - this.plugin.settings.assetsPath = value; - await this.plugin.saveSettings(); - })); - } -} diff --git a/notes/architecture.md b/notes/architecture.md new file mode 100644 index 0000000..f2d9837 --- /dev/null +++ b/notes/architecture.md @@ -0,0 +1,424 @@ +# VitePress Exporter 架构设计 + +## 概述 + +VitePress Exporter 是一个 Obsidian 插件,用于将笔记和资源导出到 VitePress 格式。核心功能包括: +- 导出 Markdown 文件到 `docs/` 目录 +- 复制图片等资源到 `docs/assets/` 目录 +- 将 Obsidian Canvas 渲染为图片 + +## 技术栈 + +- **语言**: TypeScript +- **构建工具**: esbuild +- **包管理器**: pnpm +- **Obsidian API**: Plugin, Workspace, TFile, Vault, MetadataCache + +## 核心架构 + +### 1. 导出流程 + +``` +用户触发导出 + ↓ +exportCurrentNote() + ↓ +exportNote(file) + ↓ +processAssets(content, file) + ├─→ 扫描嵌入和链接(使用 MetadataCache) + ├─→ 处理 Canvas 文件 (captureCanvas) + │ ├─→ 打开 Canvas 文件 + │ ├─→ 获取 Canvas 对象 + │ └─→ exportCanvasWithInternalAPI + │ ├─→ 设置 zoom = 0 (100%) + │ ├─→ 调用 takeScreenshot + │ └─→ 保存图片 + └─→ 复制资源文件 + ├─→ 使用 binary 模式读取 + └─→ 写入到 docs/assets/ + ↓ +updateLinksInContent() / updateCanvasLinksInContent() + ↓ +写入 docs/ 目录(使用 binary 模式) +``` + +### 2. 文件结构 + +``` +vitepress-exporter/ +├── src/ +│ ├── main.ts # 主插件源代码 +│ └── settings.ts # 设置相关代码 +├── manifest.json # 插件清单 +├── package.json # 项目配置 +├── esbuild.config.mjs # 构建配置 +├── tsconfig.json # TypeScript 配置 +└── notes/ # 开发文档 + ├── architecture.md # 本文档 + ├── canvas-rendering.md # Canvas 渲染详细说明 + └── flowchart.md # 流程图 +``` + +### 3. 关键类和方法 + +#### VitePressExporterPlugin + +主插件类,继承自 `Plugin`: + +```typescript +class VitePressExporterPlugin extends Plugin { + settings: VitePressExporterSettings; + + // 生命周期 + async onload() // 插件加载,注册命令和菜单 + onunload() // 插件卸载 + + // 设置管理 + async loadSettings() // 加载设置 + async saveSettings() // 保存设置 + + // 导出功能 + async exportCurrentNote() // 导出当前笔记 + async exportNote(file) // 导出单个笔记 + + // 资源处理 + async processAssets(content, file) // 处理资源文件和 Canvas + + // Canvas 渲染 + async captureCanvas(canvasFile) // 捕获 Canvas 为图片 + async exportCanvasWithInternalAPI(canvas, canvasFile) // 使用内部 API + + // 链接更新 + updateLinksInContent(content, sourceFile, assetPath, newFileName) // 更新资源链接 + updateCanvasLinksInContent(content, canvasFile, canvasPath, imageFileName) // 更新 Canvas 链接 +} +``` + +## Canvas 渲染架构 + +### 核心决策 + +**使用 Obsidian Canvas 内部 API**,而不是自己实现渲染逻辑: + +- ✅ `canvas.takeScreenshot()` - 直接截图 +- ✅ `canvas.getViewportBBox()` - 获取边界框 +- ✅ `canvas.zoom` - 控制缩放(对数刻度) +- ✅ `canvas.requestFrame()` - 触发重绘 + +**为什么不使用第三方库**: +- ❌ `html-to-image` - 需要滑动窗口,代码复杂 +- ❌ `dom-to-image-more` - 维护不活跃 +- ✅ Obsidian 内部 API - 兼容性好,代码简洁 + +### Zoom 对数刻度 + +**关键发现**:`canvas.zoom` 使用对数刻度(base 2) + +```typescript +zoom = 0 → scale = 2^0 = 1.0 (100%) +zoom = 1 → scale = 2^1 = 2.0 (200%) +zoom = -1 → scale = 2^-1 = 0.5 (50%) +``` + +**重要**:设置 `zoom = 0` 获得准确的 100% 缩放,不要设置 `zoom = 1.0`! + +### 文件路径处理 + +`takeScreenshot` 需要绝对文件系统路径: + +```typescript +// 1. 获取 vault 的完整路径 +const vaultBasePath = vault.adapter.basePath; + +// 2. 构建临时文件的绝对路径 +const tempFullPath = `${vaultBasePath}/temp_canvas_${Date.now()}.png`; + +// 3. 调用 takeScreenshot(需要绝对路径) +await canvas.takeScreenshot(tempFullPath, false); + +// 4. 使用相对路径读取(vault API) +const imageBuffer = await vault.adapter.readBinary(tempFileName); + +// 5. 删除临时文件 +await vault.adapter.remove(tempFileName); + +// 6. 写入到正确位置(相对路径) +await vault.adapter.writeBinary(finalPath, imageBuffer); +``` + +## 资源处理 + +### 资源类型 + +1. **嵌入资源** (`![[image.png]]`) + - 图片、PDF 等非 Markdown 文件 + - 自动复制到 `docs/assets/` + - 使用 binary 模式保留原始内容 + +2. **Canvas 文件** (`![[diagram.canvas]]`) + - 使用内部 API 渲染为 PNG 图片 + - 替换为 `` + +3. **普通链接** (`[[other-file]]`) + - Markdown 文件不复制 + - 其他资源文件会被复制 + +### 资源扫描机制 + +使用 Obsidian 的 `MetadataCache` API: + +```typescript +const cache = metadataCache.getCache(sourceFile.path); + +// 嵌入文件 +if (cache.embeds) { + for (const embed of cache.embeds) { + const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); + // 检查是否是 Canvas 或其他资源 + } +} + +// 普通链接 +if (cache.links) { + for (const link of cache.links) { + const resolvedLink = metadataCache.getFirstLinkpathDest(link.link, sourceFile.path); + // 只复制非 Markdown 文件 + } +} +``` + +### 路径更新 + +资源链接会自动更新为相对于 `docs/` 的路径: + +**Markdown 格式**: +```markdown +之前: ![](images/screenshot.png) +之后: ![](assets/screenshot.png) +``` + +**Wikilink 格式**: +```markdown +之前: ![[images/screenshot.png]] +之后: ![[assets/screenshot.png]] +``` + +**Canvas 特殊处理**: +```markdown +之前: ![[diagram.canvas]] +之后: +``` + +### 路径解析策略 + +支持多种路径格式的智能匹配: + +```typescript +const possiblePaths = [ + assetPath, // 完整路径 + assetPath.substring(sourceDir.length + 1), // 相对路径 + encodeURI(assetPath), // URL 编码 + encodeURI(assetPath.substring(sourceDir.length + 1)), + sourceFile.name, // 文件名 + encodeURI(sourceFile.name) +]; +``` + +## 配置 + +### 插件设置 + +```typescript +interface VitePressExporterSettings { + docsPath: string; // 默认: 'docs' + assetsPath: string; // 默认: 'docs/assets' +} +``` + +### Obsidian 配置 + +插件通过 Obsidian 的设置界面配置: + +1. 设置 → 社区插件 → VitePress Exporter → 选项 +2. 配置 `Docs path` 和 `Assets path` +3. 保存设置 + +## 文件读写 + +### Binary 模式 + +所有文件操作都使用 binary 模式,以保留原始格式: + +```typescript +// 读取文件 +const contentBuffer = await vault.readBinary(file); +const content = new TextDecoder().decode(contentBuffer); + +// 写入文件 +const updatedBuffer = new TextEncoder().encode(updatedContent); +await vault.adapter.writeBinary(docsPath, updatedBuffer.buffer); +``` + +**优势**: +- 保留行尾空格 +- 保留特殊字符 +- 不修改原始格式 + +## 错误处理 + +### Canvas 渲染失败 + +当 Canvas 渲染失败时,会在控制台输出错误信息,但不会中断整个导出流程: + +```typescript +try { + const renderedImage = await this.captureCanvas(canvasFile); + if (renderedImage) { + // 成功处理 + } +} catch (error) { + console.error(`Failed to render canvas ${canvasPath}:`, error); +} +// 继续处理其他文件 +``` + +### 资源复制失败 + +单个资源文件复制失败不会影响其他文件: + +```typescript +try { + // 复制资源 +} catch (error) { + console.error(`Failed to copy asset ${assetPath}:`, error); +} +// 继续处理下一个资源 +``` + +## 性能考虑 + +### 优化策略 + +1. **使用 MetadataCache** + - 快速获取文件的嵌入和链接信息 + - 避免手动解析 Markdown + +2. **批量处理** + - 一次性收集所有需要处理的文件 + - 批量复制和更新 + +3. **异步操作** + - 所有文件操作都是异步的 + - 不阻塞 UI 线程 + +4. **Binary 模式** + - 减少字符串转换开销 + - 直接操作二进制数据 + +### 预期性能 + +- 小笔记(< 10 个资源):< 1 秒 +- 中等笔记(10-50 个资源):< 3 秒 +- 大笔记(> 50 个资源或多个 Canvas):< 10 秒 + +## 触发方式 + +插件提供三种导出触发方式: + +1. **命令面板** + - `Export current note to VitePress` + +2. **文件菜单** + - 右键点击文件 → `Export to VitePress` + +3. **编辑器菜单** + - 右键点击编辑器 → `Export to VitePress` + +## 未来扩展 + +### 可能的功能 + +1. **批量导出** + - 导出整个文件夹 + - 导出所有笔记 + +2. **高级配置** + - 自定义图片格式(PNG/JPEG/WebP) + - 图片质量控制 + - 自定义链接替换规则 + +3. **VitePress 集成** + - 自动生成 frontmatter + - 自动创建索引页面 + - 集成 VitePress 构建流程 + +4. **更多资源类型** + - 支持视频嵌入 + - 支持音频文件 + - 支持其他特殊格式 + +## 维护指南 + +### 修改导出逻辑 + +主要导出逻辑在 `exportNote()` 方法中: + +```typescript +async exportNote(file: TFile) { + // 1. 读取文件(binary 模式) + const contentBuffer = await vault.readBinary(file); + const content = new TextDecoder().decode(contentBuffer); + + // 2. 处理资源 + const updatedContent = await this.processAssets(content, file); + + // 3. 写入文件(binary 模式) + const updatedBuffer = new TextEncoder().encode(updatedContent); + await vault.adapter.writeBinary(docsPath, updatedBuffer.buffer); +} +``` + +### 添加新的资源类型 + +在 `processAssets()` 方法中添加: + +```typescript +if (cache.embeds) { + for (const embed of cache.embeds) { + const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); + if (resolvedLink) { + if (resolvedLink.extension === 'canvas') { + // Canvas 处理 + } else if (resolvedLink.extension === 'newtype') { + // 处理新类型 + } else { + // 普通资源 + } + } + } +} +``` + +### 调试技巧 + +1. **启用详细日志** + ```typescript + console.log('Processing assets for file:', sourceFile.path); + console.log('Cache:', cache); + console.log('Assets to copy:', Array.from(assetsToCopy)); + ``` + +2. **使用 Obsidian 开发者工具** + - `Ctrl+Shift+I` 打开控制台 + - 查看日志输出 + +3. **测试单个功能** + - 创建最小测试用例 + - 逐步验证每个步骤 + +## 相关文档 + +- [Canvas 渲染详细说明](./canvas-rendering.md) - Canvas 渲染的实现细节 +- [执行流程图](./flowchart.md) - 完整的导出流程图 +- [Obsidian API 文档](https://github.com/obsidianmd/obsidian-api) - 官方 API diff --git a/notes/flowchart.md b/notes/flowchart.md new file mode 100644 index 0000000..7dffd0c --- /dev/null +++ b/notes/flowchart.md @@ -0,0 +1,411 @@ +# VitePress Exporter 执行流程 + +## 插件概述 + +VitePress Exporter 是一个 Obsidian 插件,用于将当前笔记导出到 VitePress 文档系统,包括资源文件管理和 Canvas 渲染功能。 + +## 完整执行流程图 + +```mermaid +flowchart TD + Start([用户触发导出]) --> CheckActiveFile{检查当前文件} + CheckActiveFile -->|没有活动文件| ShowError1[显示错误提示] + CheckActiveFile -->|不是 md 文件| ShowError2[显示错误提示] + CheckActiveFile -->|是 md 文件| ReadFile[读取文件内容
使用 binary 模式] + + ReadFile --> ProcessAssets[处理资源文件
processAssets] + ProcessAssets --> GetCache[获取文件元数据缓存
metadataCache.getCache] + + GetCache --> CheckCache{缓存是否存在} + CheckCache -->|否| ReturnContent[返回原内容] + CheckCache -->|是| InitializeSets[初始化集合
assetsToCopy, canvasFiles] + + InitializeSets --> ScanEmbeds[扫描嵌入文件
cache.embeds] + ScanEmbeds --> CheckEmbed{有嵌入文件?} + CheckEmbed -->|否| ScanLinks + CheckEmbed -->|是| ResolveEmbed[解析嵌入路径
getFirstLinkpathDest] + + ResolveEmbed --> CheckCanvas{是 canvas 文件?} + CheckCanvas -->|是| AddToCanvasSet[添加到 canvasFiles] + CheckCanvas -->|否| AddToAssetsSet[添加到 assetsToCopy] + AddToCanvasSet --> ScanEmbeds + AddToAssetsSet --> ScanEmbeds + + ScanEmbeds --> ScanLinks[扫描链接文件
cache.links] + ScanLinks --> CheckLink{有链接文件?} + CheckLink -->|否| ProcessCanvasFiles + CheckLink -->|是| ResolveLink[解析链接路径
getFirstLinkpathDest] + + ResolveLink --> CheckMD{是 md 文件?} + CheckMD -->|是| SkipLink[跳过] + CheckMD -->|否| AddToAssetsSet + SkipLink --> ScanLinks + AddToAssetsSet --> ScanLinks + + ScanLinks --> ProcessCanvasFiles[处理 Canvas 文件] + ProcessCanvasFiles --> CheckCanvasEmpty{有 Canvas 文件?} + + CheckCanvasEmpty -->|否| ProcessAssetFiles + CheckCanvasEmpty -->|是| GetCanvasFile[获取 Canvas 文件对象] + + GetCanvasFile --> CaptureCanvas[captureCanvas] + CaptureCanvas --> OpenFile[打开 Canvas 文件
activeLeaf.openFile] + + OpenFile --> GetCanvas[获取 Canvas 对象
activeLeaf.view.canvas] + GetCanvas --> CheckCanvasObj{Canvas 对象存在?} + + CheckCanvasObj -->|否| NextCanvas + CheckCanvasObj -->|是| ExportInternalAPI[exportCanvasWithInternalAPI] + + ExportInternalAPI --> GetBBox[获取视口边界框
getViewportBBox] + GetBBox --> SetZoom[设置 zoom = 0
100% 缩放] + + SetZoom --> RequestFrame[请求重绘
requestFrame] + RequestFrame --> WaitRender[等待渲染
100ms + rAF] + + WaitRender --> TakeScreenshot[调用 takeScreenshot
使用绝对路径] + TakeScreenshot --> WaitWrite[等待文件写入
100ms] + + WaitWrite --> ReadTemp[读取临时文件
readBinary] + ReadTemp --> CheckBuffer{读取成功?} + + CheckBuffer -->|否| LogError1[记录错误] + CheckBuffer -->|是| RemoveTemp[删除临时文件] + + RemoveTemp --> WriteFinal[写入最终位置
writeBinary] + WriteFinal --> UpdateCanvasLinks[更新 Canvas 链接
updateCanvasLinksInContent] + + UpdateCanvasLinks --> NextCanvas{还有 Canvas?} + LogError1 --> NextCanvas + NextCanvas -->|是| GetCanvasFile + NextCanvas -->|否| ProcessAssetFiles + + subgraph 资源复制流程 + ProcessAssetFiles[处理资源文件] --> CheckAssets{有资源文件?} + CheckAssets -->|否| WriteDocs + CheckAssets -->|是| GetAssetFile[获取资源文件对象] + + GetAssetFile --> ReadAsset[读取资源文件
readBinary binary 模式] + ReadAsset --> MkdirAssets[创建 assets 目录
mkdir] + + MkdirAssets --> WriteAsset[写入到 docs/assets
writeBinary binary 模式] + WriteAsset --> UpdateLinks[更新资源链接
updateLinksInContent] + + UpdateLinks --> NextAsset{还有资源?} + NextAsset -->|是| GetAssetFile + NextAsset -->|否| WriteDocs + end + + WriteDocs[写入到 docs 目录
writeBinary binary 模式] --> Success[显示成功提示] + Success --> End([结束]) + + ShowError1 --> End + ShowError2 --> End + ReturnContent --> WriteDocs + + style Start fill:#e1f5e1 + style End fill:#ffe1e1 + style Success fill:#e1f5e1 + style ShowError1 fill:#ffe1e1 + style ShowError2 fill:#ffe1e1 + style ProcessCanvasFiles fill:#fff4e1 + style ProcessAssetFiles fill:#e1f0ff + style ExportInternalAPI fill:#ffe1ff +``` + +## 核心功能模块 + +### 1. 导出流程 + +**触发方式**: +- 命令面板:`Export current note to VitePress` +- 文件右键菜单:`Export to VitePress` +- 编辑器右键菜单:`Export to VitePress` + +**文件验证**: +- 检查活动文件是否存在 +- 验证文件扩展名是否为 `md` + +**内容读取**: +- 使用 `vault.readBinary()` 读取文件 +- 保留原始格式(包括行尾空格) + +### 2. 资源处理 + +**扫描机制**: +- 使用 `metadataCache.getCache()` 获取文件元数据 +- 扫描 `cache.embeds` 获取嵌入文件 +- 扫描 `cache.links` 获取链接文件 + +**文件分类**: +- Canvas 文件:扩展名为 `.canvas` +- 普通资源:非 Markdown 文件 +- Markdown 文件:不复制 + +**路径解析**: +- 使用 `metadataCache.getFirstLinkpathDest()` 解析路径 +- 支持相对路径和绝对路径 + +### 3. Canvas 渲染 + +**打开文件**: +- 使用 `workspace.getLeaf()` 获取 leaf +- 调用 `activeLeaf.openFile()` 打开 Canvas +- 从 `activeLeaf.view.canvas` 获取 Canvas 对象 + +**渲染过程**: +- 获取视口边界框 `getViewportBBox()` +- 设置 `zoom = 0`(100% 缩放) +- 请求重绘 `requestFrame()` +- 等待渲染完成(100ms + requestAnimationFrame) +- 调用 `takeScreenshot(绝对路径)` 截图 + +**文件处理**: +- 保存到临时文件(绝对路径) +- 读取临时文件(相对路径) +- 删除临时文件 +- 写入到最终位置 + +### 4. 链接更新 + +**Markdown 格式**: +```markdown +之前: ![](path/to/image.png) +之后: ![](assets/image.png) +``` + +**Wikilink 格式**: +```markdown +之前: ![[path/to/image.png]] +之后: ![[assets/image.png]] +``` + +**Canvas 特殊处理**: +```markdown +之前: ![[diagram.canvas]] +之后: +``` + +**路径匹配**: +- 支持多种格式(绝对、相对、URL 编码) +- 使用正则表达式匹配和替换 +- 转换为相对路径 + +### 5. 文件写入 + +**Binary 模式**: +- 使用 `TextEncoder.encode()` 转换内容 +- 调用 `vault.adapter.writeBinary()` 写入 +- 保留原始格式 + +## 关键方法说明 + +### exportCurrentNote() +导出当前活动笔记 + +```typescript +async exportCurrentNote() { + const activeFile = this.app.workspace.getActiveFile(); + if (!activeFile) { + new Notice('No active file found'); + return; + } + if (activeFile.extension !== 'md') { + new Notice('Current file is not a markdown file'); + return; + } + await this.exportNote(activeFile); +} +``` + +### exportNote(file) +执行导出逻辑 + +```typescript +async exportNote(file: TFile) { + // 1. 读取文件(binary 模式) + const contentBuffer = await vault.readBinary(file); + const content = new TextDecoder().decode(contentBuffer); + + // 2. 处理资源 + const updatedContent = await this.processAssets(content, file); + + // 3. 写入文件(binary 模式) + const docsPath = `${this.settings.docsPath}/${file.name}`; + const updatedBuffer = new TextEncoder().encode(updatedContent); + await vault.adapter.writeBinary(docsPath, updatedBuffer.buffer); +} +``` + +### processAssets(content, file) +处理资源文件 + +```typescript +async processAssets(content: string, sourceFile: TFile): Promise { + const cache = metadataCache.getCache(sourceFile.path); + if (!cache) return content; + + const assetsToCopy = new Set(); + const canvasFiles = new Set(); + + // 收集嵌入文件 + if (cache.embeds) { + for (const embed of cache.embeds) { + const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); + if (resolvedLink) { + if (resolvedLink.extension === 'canvas') { + canvasFiles.add(resolvedLink.path); + } else { + assetsToCopy.add(resolvedLink.path); + } + } + } + } + + // 收集链接文件 + if (cache.links) { + for (const link of cache.links) { + const resolvedLink = metadataCache.getFirstLinkpathDest(link.link, sourceFile.path); + if (resolvedLink && resolvedLink.extension !== 'md') { + assetsToCopy.add(resolvedLink.path); + } + } + } + + // 处理 Canvas 文件 + for (const canvasPath of canvasFiles) { + const renderedImage = await this.captureCanvas(canvasFile); + if (renderedImage) { + // 写入并更新链接 + } + } + + // 复制资源文件 + for (const assetPath of assetsToCopy) { + const assetContent = await vault.readBinary(sourceFile); + await vault.adapter.writeBinary(destPath, assetContent); + content = this.updateLinksInContent(content, ...); + } + + return content; +} +``` + +### captureCanvas(canvasFile) +捕获 Canvas 为图片 + +```typescript +async captureCanvas(canvasFile: TFile): Promise { + const activeLeaf = this.app.workspace.getLeaf(); + await activeLeaf.openFile(canvasFile); + + const canvas = activeLeaf.view.canvas; + if (!canvas) return null; + + return await this.exportCanvasWithInternalAPI(canvas, canvasFile); +} +``` + +## 数据流图 + +``` +用户触发 + ↓ +exportCurrentNote() + ↓ +exportNote(file) + ↓ +readBinary(file) → content + ↓ +processAssets(content, file) + ├─→ metadataCache.getCache() → cache + ├─→ 收集文件 → canvasFiles, assetsToCopy + ├─→ 处理 Canvas + │ ├─→ captureCanvas() + │ ├─→ takeScreenshot() + │ └─→ updateCanvasLinksInContent() + └─→ 复制资源 + ├─→ readBinary() + ├─→ writeBinary() + └─→ updateLinksInContent() + ↓ +updatedContent + ↓ +TextEncoder.encode() → buffer + ↓ +writeBinary(docsPath, buffer) + ↓ +完成 +``` + +## 错误处理 + +### 文件验证失败 +- 没有活动文件 → 显示 Notice +- 文件不是 Markdown → 显示 Notice + +### Canvas 渲染失败 +- 捕获异常并记录日志 +- 继续处理其他文件 +- 不中断整个导出流程 + +### 资源复制失败 +- 捕获异常并记录日志 +- 继续处理下一个资源 +- 不影响其他文件 + +## 性能特点 + +### 优化策略 + +1. **使用 MetadataCache** + - 快速获取文件关系 + - 避免手动解析 + +2. **Binary 模式** + - 减少字符串转换 + - 保留原始格式 + +3. **异步操作** + - 所有文件操作异步 + - 不阻塞 UI + +4. **错误隔离** + - 单个文件失败不影响其他 + - 继续处理后续文件 + +### 时间复杂度 + +- 文件读取:O(n) +- 资源扫描:O(e + l) 其中 e=嵌入数,l=链接数 +- Canvas 渲染:O(c) 其中 c=Canvas 数量 +- 资源复制:O(a) 其中 a=资源数量 + +总体:O(n + e + l + c + a) + +## 配置选项 + +用户可以在插件设置中配置: + +- **docsPath**: 导出文档目录(默认: `docs`) +- **assetsPath**: 资源文件目录(默认: `docs/assets`) + +## 未来改进方向 + +1. **批量导出** + - 导出整个文件夹 + - 导出多个选中的文件 + +2. **进度显示** + - 显示导出进度条 + - 显示当前处理的文件 + +3. **更多配置** + - 自定义图片格式 + - 自定义链接转换规则 + - 排除特定文件类型 + +4. **性能优化** + - 并行处理资源 + - 缓存已渲染的 Canvas + - 增量导出(只处理修改的文件) diff --git a/notes/render-canvas.md b/notes/render-canvas.md new file mode 100644 index 0000000..c188b09 --- /dev/null +++ b/notes/render-canvas.md @@ -0,0 +1,397 @@ +# Canvas 渲染系统实现 + +## 技术栈 + +- **渲染方式**: Obsidian Canvas 内部 API (`takeScreenshot`) +- **缩放控制**: `canvas.zoom` 属性(对数刻度) +- **语言**: TypeScript + +## 核心实现 + +### 1. Canvas 捕获流程 + +```typescript +async renderCanvas(canvasFile: TFile): Promise { + // 1. 获取活动 leaf + const activeLeaf = this.app.workspace.getLeaf(); + if (!activeLeaf) return null; + + // 2. 打开 Canvas 文件 + await activeLeaf.openFile(canvasFile); + + // 3. 获取 Canvas 对象 + const canvas = activeLeaf.view.canvas; + if (!canvas) return null; + + // 4. 使用内部 API 导出 + return await this.exportCanvasWithInternalAPI(canvas, canvasFile); +} +``` + +### 2. 使用 Canvas 内部 API + +```typescript +async exportCanvasWithInternalAPI( + canvas: any, + canvasFile: TFile +): Promise { + try { + // 1. 获取边界框 + const bbox = canvas.getViewportBBox(); + const contentWidth = bbox.maxX - bbox.minX; + const contentHeight = bbox.maxY - bbox.minY; + + // 2. 设置 zoom = 0 (100% 缩放) + const oldZoom = canvas.zoom; + canvas.zoom = 0; // 对数刻度:2^0 = 1.0 (100%) + + // 3. 请求重绘 + canvas.requestFrame(); + await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise(resolve => requestAnimationFrame(resolve)); + + // 4. 生成文件路径 + const tempFileName = `temp_canvas_${Date.now()}.png`; + const finalFileName = canvasFile.name.replace(".canvas", ".png"); + const finalPath = `${this.settings.assetsPath}/${finalFileName}`; + + // 5. 获取 vault 绝对路径 + const vaultBasePath = vault.adapter.basePath; + const tempFullPath = `${vaultBasePath}/${tempFileName}`; + + // 6. 调用 takeScreenshot(需要绝对路径) + await canvas.takeScreenshot(tempFullPath, false); + + // 7. 等待文件写入完成 + await new Promise(resolve => setTimeout(resolve, 100)); + + // 8. 读取临时文件(使用相对路径) + const imageBuffer = await vault.adapter.readBinary(tempFileName); + + if (!imageBuffer || imageBuffer.byteLength === 0) { + console.error("Failed to read temporary file"); + return null; + } + + // 9. 删除临时文件 + await vault.adapter.remove(tempFileName); + + // 10. 写入到最终位置 + await vault.adapter.writeBinary(finalPath, imageBuffer); + + // 11. 返回 Uint8Array + return new Uint8Array(imageBuffer); + + } catch (error) { + console.error("exportCanvasWithInternalAPI failed:", error); + return null; + } +} +``` + +### 3. Canvas Zoom 对数刻度 + +**关键发现**:`canvas.zoom` 使用对数刻度(base 2) + +| zoom 值 | 缩放比例 | 说明 | +|---------|----------|------| +| 0 | 100% (2^0) | 原始尺寸,我们要设置的值 | +| 1 | 200% (2^1) | 放大 2 倍 | +| -1 | 50% (2^-1) | 缩小一半 | +| -1.76 | ~30% | Obsidian 默认缩放 | + +**重要**:不要设置 `zoom = 1.0`,这会让 Canvas 放大到 200%!应该设置 `zoom = 0`。 + +### 4. 链接更新 + +Canvas 引用会被转换为 Viewer 组件: + +```typescript +updateCanvasLinksInContent(content: string, canvasFile: TFile, canvasPath: string, imageFileName: string): string { + // 支持多种路径格式 + const possiblePaths = [ + canvasPath, // 完整路径 + canvasPath.substring(sourceDir.length + 1), // 相对路径 + encodeURI(canvasPath), // URL 编码 + canvasFile.name, // 文件名 + canvasFile.name.replace('.canvas', ''), // 不带扩展名 + ]; + + // 替换 Markdown 格式 + const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; + content = content.replace(markdownRegex, (match, alt, path) => { + if (path匹配) { + const relativePath = this.settings.assetsPath.replace('docs/', ''); + return ``; + } + return match; + }); + + // 替换 Wikilink 格式 + const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; + content = content.replace(wikilinkRegex, (match, link) => { + if (link匹配) { + const relativePath = this.settings.assetsPath.replace('docs/', ''); + return ``; + } + return match; + }); + + return content; +} +``` + +## 渲染流程 + +``` +1. 打开 Canvas 文件 + └─> activeLeaf.openFile(canvasFile) + +2. 获取 Canvas 对象 + └─> activeLeaf.view.canvas + +3. 调用 exportCanvasWithInternalAPI + ├─> 获取视口边界框 + ├─> 设置 zoom = 0 (100%) + ├─> 请求重绘 + ├─> 等待 100ms + requestAnimationFrame + ├─> 调用 takeScreenshot(绝对路径) + ├─> 读取临时文件 + ├─> 删除临时文件 + └─> 写入到 docs/assets/ + +4. 更新内容中的链接 + └─> 转换为 +``` + +## 在资源处理中的集成 + +Canvas 渲染是资源处理流程的一部分: + +```typescript +async processAssets(content: string, sourceFile: TFile): Promise { + const cache = metadataCache.getCache(sourceFile.path); + const canvasFiles = new Set(); + + // 1. 收集 Canvas 文件 + if (cache.embeds) { + for (const embed of cache.embeds) { + const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); + if (resolvedLink?.extension === 'canvas') { + canvasFiles.add(resolvedLink.path); + } + } + } + + // 2. 渲染每个 Canvas + for (const canvasPath of canvasFiles) { + try { + const canvasFile = vault.getAbstractFileByPath(canvasPath); + if (canvasFile instanceof TFile) { + const renderedImage = await this.captureCanvas(canvasFile); + if (renderedImage) { + const imageFileName = canvasFile.name.replace('.canvas', '.png'); + const imagePath = `${this.settings.assetsPath}/${imageFileName}`; + + // 确保 assets 目录存在 + await vault.adapter.mkdir(this.settings.assetsPath); + + // 写入渲染的图片 + await vault.adapter.writeBinary(imagePath, renderedImage.buffer); + + // 更新内容中的 canvas 引用 + content = this.updateCanvasLinksInContent(content, canvasFile, canvasPath, imageFileName); + } + } + } catch (error) { + console.error(`Failed to render canvas ${canvasPath}:`, error); + } + } + + return content; +} +``` + +## 优势 + +1. **完全使用 Obsidian 内部 API** + - 不依赖第三方库(html-to-image) + - 兼容性好,Obsidian 升级时应该能正常工作 + - 代码简洁,维护方便 + +2. **正确的缩放控制** + - 使用对数刻度的 `zoom` 属性 + - 设置 `zoom = 0` 获得准确的 100% 缩放 + - 每个元素都是原始尺寸 + +3. **路径处理灵活** + - 支持多种路径格式(绝对、相对、URL 编码) + - 自动转换为正确的相对路径 + - 支持 Markdown 和 Wikilink 两种格式 + +4. **错误隔离** + - 单个 Canvas 渲染失败不影响其他文件 + - 在控制台输出详细错误信息 + - 继续处理后续资源 + +## 测试方法 + +### 1. 基本功能测试 + +创建测试 Canvas 文件: +- 小尺寸: 800x600 +- 大尺寸: 4000x3000 +- 包含多个节点和连接 + +### 2. 验证步骤 + +1. **创建测试笔记**,包含 Canvas 引用 + ```markdown + # 测试笔记 + + 这是一个 Canvas: + ![[test.canvas]] + ``` + +2. **执行导出命令** + +3. **检查控制台输出**: + ``` + Processing assets for file: test.md + Canvas files to render: ['test.canvas'] + Successfully rendered canvas: test.canvas -> docs/assets/test.png + ``` + +4. **检查输出文件**: + - 图片位置:`docs/assets/test.png` + - 图片尺寸应该等于 Canvas 的实际内容尺寸 + - 文字清晰,没有缩水 + - 导出后的笔记内容被更新 + +### 3. 路径格式测试 + +测试各种路径格式的 Canvas 引用: + +```markdown +![[test.canvas]] # 文件名 +![[folder/test.canvas]] # 相对路径 +![](test.canvas) # Markdown 格式 +![](folder/test.canvas) # Markdown 相对路径 +![[test.canvas|别名]] # 带别名 +![](%E6%B5%8B%E8%AF%95.canvas) # URL 编码 +``` + +所有格式都应该被正确识别和转换。 + +## API 参考 + +### Canvas 内部方法 + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `getViewportBBox()` | - | `{minX, minY, maxX, maxY}` | 获取视口边界框 | +| `takeScreenshot(path, privacy)` | `path: string`, `privacy: boolean` | `Promise` | 截图并保存到文件 | +| `requestFrame()` | - | - | 请求重绘 | +| `zoom` 属性 | - | `number` | 对数刻度缩放(0 = 100%) | + +### Workspace API + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `getLeaf()` | - | `WorkspaceLeaf` | 获取活动 leaf | +| `openFile(file)` | `TFile` | `Promise` | 打开文件 | + +### Vault API + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `adapter.readBinary(path)` | `string` | `Promise` | 读取二进制文件 | +| `adapter.writeBinary(path, data)` | `string, ArrayBuffer` | `Promise` | 写入二进制文件 | +| `adapter.mkdir(path)` | `string` | `Promise` | 创建目录 | +| `adapter.remove(path)` | `string` | `Promise` | 删除文件 | + +### 重要常量 + +- `zoom = 0` → 100% 缩放 +- `zoom = 1` → 200% 缩放 +- `zoom = -1` → 50% 缩放 +- `zoom = Math.log2(scale)` → zoom 和缩放的转换公式 + +## 已知问题 + +1. **临时文件处理** + - `takeScreenshot` 需要**绝对文件系统路径** + - 必须先保存到临时文件,然后读取并移动 + - 临时文件会自动清理 + +2. **路径获取** + - 使用 `vault.adapter.basePath` 获取 vault 的完整路径 + - 这是 Obsidian 的内部 API,可能在未来版本中变化 + +3. **同步问题** + - 需要等待 `takeScreenshot` 完成 + - 使用 `setTimeout` 和 `requestAnimationFrame` 确保渲染完成 + - 时间可能需要根据实际情况调整 + +## 故障排除 + +### Canvas 渲染失败 + +**问题**:Canvas 没有被渲染成图片 + +**可能原因**: +1. Canvas 文件路径不正确 +2. Canvas 对象获取失败 +3. `takeScreenshot` 调用失败 +4. 临时文件读写权限问题 + +**解决方法**: +- 检查控制台日志 +- 确认 Canvas 文件存在且可打开 +- 检查文件系统权限 + +### 图片质量差 + +**问题**:渲染的图片模糊或尺寸不正确 + +**可能原因**: +- zoom 值设置不正确 +- Canvas 节点被折叠 + +**解决方法**: +- 确认 `zoom = 0`(100%) +- 检查 Canvas 是否有折叠的节点 +- 增加等待时间确保完全渲染 + +### 链接没有更新 + +**问题**:导出后 Canvas 引用没有被替换 + +**可能原因**: +- 路径格式不支持 +- 正则表达式不匹配 + +**解决方法**: +- 检查链接格式(Markdown vs Wikilink) +- 查看控制台日志确认路径匹配 +- 添加更多路径格式支持 + +## 未来改进 + +1. **进度反馈** + - 添加渲染进度提示 + - 显示 Canvas 尺寸和预计时间 + +2. **错误处理** + - 更详细的错误信息 + - 降级方案(如果 takeScreenshot 不可用) + +3. **性能优化** + - 缓存已渲染的 Canvas + - 避免重复截图 + - 并行处理多个 Canvas + +4. **更多格式** + - 支持 JPEG、WebP 等格式 + - 可配置的图片质量 + - 可配置的分辨率 diff --git a/package-lock.json b/package-lock.json index 319339c..10db013 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,27 +7,26 @@ "": { "name": "vitepress-exporter", "version": "0.1.0", - "license": "MIT", + "license": "0-BSD", "dependencies": { - "html2canvas": "^1.4.1" + "obsidian": "latest" }, "devDependencies": { + "@eslint/js": "9.30.1", "@types/node": "^16.11.6", - "@typescript-eslint/eslint-plugin": "5.29.0", - "@typescript-eslint/parser": "5.29.0", - "builtin-modules": "3.3.0", - "dom-to-image-more": "^3.7.2", - "esbuild": "0.17.3", - "obsidian": "latest", + "esbuild": "0.25.5", + "eslint-plugin-obsidianmd": "0.1.9", + "globals": "14.0.0", + "jiti": "2.6.1", "tslib": "2.4.0", - "typescript": "4.7.4" + "typescript": "^5.8.3", + "typescript-eslint": "8.35.1" } }, "node_modules/@codemirror/state": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.0.tgz", "integrity": "sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==", - "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -38,7 +37,6 @@ "version": "6.38.6", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.6.tgz", "integrity": "sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==", - "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -48,10 +46,27 @@ "w3c-keyname": "^2.2.4" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz", - "integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", "cpu": [ "arm" ], @@ -62,13 +77,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz", - "integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", "cpu": [ "arm64" ], @@ -79,13 +94,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz", - "integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", "cpu": [ "x64" ], @@ -96,13 +111,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz", - "integrity": "sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", "cpu": [ "arm64" ], @@ -113,13 +128,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz", - "integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", "cpu": [ "x64" ], @@ -130,13 +145,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz", - "integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", "cpu": [ "arm64" ], @@ -147,13 +162,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz", - "integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", "cpu": [ "x64" ], @@ -164,13 +179,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz", - "integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", "cpu": [ "arm" ], @@ -181,13 +196,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz", - "integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", "cpu": [ "arm64" ], @@ -198,13 +213,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz", - "integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", "cpu": [ "ia32" ], @@ -215,13 +230,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz", - "integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", "cpu": [ "loong64" ], @@ -232,13 +247,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz", - "integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", "cpu": [ "mips64el" ], @@ -249,13 +264,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz", - "integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", "cpu": [ "ppc64" ], @@ -266,13 +281,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz", - "integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", "cpu": [ "riscv64" ], @@ -283,13 +298,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz", - "integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", "cpu": [ "s390x" ], @@ -300,13 +315,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz", - "integrity": "sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", "cpu": [ "x64" ], @@ -317,13 +332,30 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz", - "integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", "cpu": [ "x64" ], @@ -334,13 +366,30 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz", - "integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", "cpu": [ "x64" ], @@ -351,13 +400,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz", - "integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", "cpu": [ "x64" ], @@ -368,13 +417,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz", - "integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", "cpu": [ "arm64" ], @@ -385,13 +434,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz", - "integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", "cpu": [ "ia32" ], @@ -402,13 +451,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz", - "integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", "cpu": [ "x64" ], @@ -419,7 +468,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -428,7 +477,6 @@ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -442,35 +490,12 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -478,32 +503,171 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.1.tgz", + "integrity": "sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/json": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/json/-/json-0.14.0.tgz", + "integrity": "sha512-rvR/EZtvUG3p9uqrSmcDJPYSH7atmWr0RnFWN6m917MAPx82+zQgPUmDu0whPFG6XTyM0vB/hR6c1Q63OaYtCQ==", "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@eslint/core": "^0.17.0", + "@eslint/plugin-kit": "^0.4.1", + "@humanwhocodes/momoa": "^3.3.10", + "natural-compare": "^1.4.0" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -512,7 +676,6 @@ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=12.22" }, @@ -521,23 +684,76 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/momoa": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-3.3.10.tgz", + "integrity": "sha512-KWiFQpSAqEIyrTXko3hFNLeQvSK8zXlJQzhhxsyVn58WFRYXST99b3Nqnu+ttOtjds2Pl2grUHGpe2NzhPynuQ==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@marijn/find-cluster-break": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", - "dev": true, "license": "MIT", "peer": true }, + "node_modules/@microsoft/eslint-plugin-sdl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@microsoft/eslint-plugin-sdl/-/eslint-plugin-sdl-1.1.0.tgz", + "integrity": "sha512-dxdNHOemLnBhfY3eByrujX9KyLigcNtW8sU+axzWv5nLGcsSBeKW2YYyTpfPo1hV8YPOmIGnfA4fZHyKVtWqBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-plugin-n": "17.10.3", + "eslint-plugin-react": "7.37.3", + "eslint-plugin-security": "1.4.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "eslint": "^9" + } + }, + "node_modules/@microsoft/eslint-plugin-sdl/node_modules/eslint-plugin-security": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-1.4.0.tgz", + "integrity": "sha512-xlS7P2PLMXeqfhyf3NpqbvbnW04kN8M9NtmhpR3XGyOvt/vNKS7XPXT5EDbwKW9vCjWH4PpfQvgD/+JgN0VJKA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-regex": "^1.1.0" + } + }, + "node_modules/@microsoft/eslint-plugin-sdl/node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -576,21 +792,50 @@ "node": ">= 8" } }, + "node_modules/@pkgr/core": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz", + "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/codemirror": { "version": "5.60.8", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz", "integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==", - "dev": true, "license": "MIT", "dependencies": { "@types/tern": "*" } }, + "node_modules/@types/eslint": { + "version": "8.56.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", + "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { @@ -600,6 +845,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "16.18.126", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", @@ -611,127 +863,165 @@ "version": "0.23.9", "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz", - "integrity": "sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz", + "integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.29.0", - "@typescript-eslint/type-utils": "5.29.0", - "@typescript-eslint/utils": "5.29.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/type-utils": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.35.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", - "integrity": "sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz", + "integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.29.0", - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/typescript-estree": "5.29.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz", + "integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.35.1", + "@typescript-eslint/types": "^8.35.1", + "debug": "^4.3.4" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz", - "integrity": "sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz", + "integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/visitor-keys": "5.29.0" + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz", - "integrity": "sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz", + "integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==", "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "5.29.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz", + "integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.35.1", + "@typescript-eslint/utils": "8.35.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz", - "integrity": "sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz", + "integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==", "dev": true, "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -739,91 +1029,108 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz", - "integrity": "sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/visitor-keys": "5.29.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz", - "integrity": "sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==", + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz", + "integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==", "dev": true, "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.29.0", - "@typescript-eslint/types": "5.29.0", - "@typescript-eslint/typescript-estree": "5.29.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@typescript-eslint/project-service": "8.35.1", + "@typescript-eslint/tsconfig-utils": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/visitor-keys": "8.35.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz", - "integrity": "sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.29.0", - "eslint-visitor-keys": "^3.3.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz", + "integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.35.1", + "@typescript-eslint/types": "8.35.1", + "@typescript-eslint/typescript-estree": "8.35.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz", + "integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.35.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC", - "peer": true - }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -837,7 +1144,6 @@ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -848,7 +1154,6 @@ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -860,24 +1165,12 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -893,17 +1186,192 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "license": "Python-2.0", - "peer": true + "license": "Python-2.0" }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/balanced-match": { @@ -911,17 +1379,7 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.14", @@ -929,7 +1387,6 @@ "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -948,17 +1405,54 @@ "node": ">=8" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { @@ -967,7 +1461,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -978,7 +1471,6 @@ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -996,7 +1488,6 @@ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1009,22 +1500,19 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", - "dev": true, "license": "MIT", "peer": true }, @@ -1034,7 +1522,6 @@ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1044,13 +1531,58 @@ "node": ">= 8" } }, - "node_modules/css-line-break": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", - "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, "license": "MIT", "dependencies": { - "utrie": "^1.0.2" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/debug": { @@ -1076,47 +1608,277 @@ "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", - "peer": true + "license": "MIT" }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "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", "dependencies": { - "path-type": "^4.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=8" + "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", + "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/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, - "node_modules/dom-to-image-more": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.7.2.tgz", - "integrity": "sha512-uQf+pHv6eQhgfI8t2bFuinV0KsPyT8TZgCLwcSU8uBVgN9v6leb0mMpvp6HQAlAcplP3NCcGjxbdqef6pTzvmw==", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", + "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/esbuild": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz", - "integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1124,31 +1886,34 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.3", - "@esbuild/android-arm64": "0.17.3", - "@esbuild/android-x64": "0.17.3", - "@esbuild/darwin-arm64": "0.17.3", - "@esbuild/darwin-x64": "0.17.3", - "@esbuild/freebsd-arm64": "0.17.3", - "@esbuild/freebsd-x64": "0.17.3", - "@esbuild/linux-arm": "0.17.3", - "@esbuild/linux-arm64": "0.17.3", - "@esbuild/linux-ia32": "0.17.3", - "@esbuild/linux-loong64": "0.17.3", - "@esbuild/linux-mips64el": "0.17.3", - "@esbuild/linux-ppc64": "0.17.3", - "@esbuild/linux-riscv64": "0.17.3", - "@esbuild/linux-s390x": "0.17.3", - "@esbuild/linux-x64": "0.17.3", - "@esbuild/netbsd-x64": "0.17.3", - "@esbuild/openbsd-x64": "0.17.3", - "@esbuild/sunos-x64": "0.17.3", - "@esbuild/win32-arm64": "0.17.3", - "@esbuild/win32-ia32": "0.17.3", - "@esbuild/win32-x64": "0.17.3" + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" } }, "node_modules/escape-string-regexp": { @@ -1157,7 +1922,6 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -1166,162 +1930,544 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "url": "https://eslint.org/donate" }, - "engines": { - "node": ">=8.0.0" + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "semver": "^7.5.4" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=12" }, "peerDependencies": { - "eslint": ">=5" + "eslint": ">=6.0.0" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-depend": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-depend/-/eslint-plugin-depend-1.3.1.tgz", + "integrity": "sha512-1uo2rFAr9vzNrCYdp7IBZRB54LiyVxfaIso0R6/QV3t6Dax6DTbW/EV2Hktf0f4UtmGHK8UyzJWI382pwW04jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "empathic": "^2.0.0", + "module-replacements": "^2.8.0", + "semver": "^7.6.3" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-json-schema-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-schema-validator/-/eslint-plugin-json-schema-validator-5.1.0.tgz", + "integrity": "sha512-ZmVyxRIjm58oqe2kTuy90PpmZPrrKvOjRPXKzq8WCgRgAkidCgm5X8domL2KSfadZ3QFAmifMgGTcVNhZ5ez2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.3.0", + "ajv": "^8.0.0", + "debug": "^4.3.1", + "eslint-compat-utils": "^0.5.0", + "json-schema-migrate": "^2.0.0", + "jsonc-eslint-parser": "^2.0.0", + "minimatch": "^8.0.0", + "synckit": "^0.9.0", + "toml-eslint-parser": "^0.9.0", + "tunnel-agent": "^0.6.0", + "yaml-eslint-parser": "^1.0.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-json-schema-validator/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint-plugin-json-schema-validator/node_modules/brace-expansion": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/eslint-plugin-json-schema-validator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "license": "Apache-2.0", + "license": "MIT" + }, + "node_modules/eslint-plugin-json-schema-validator/node_modules/minimatch": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.7.tgz", + "integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-n": { + "version": "17.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.10.3.tgz", + "integrity": "sha512-ySZBfKe49nQZWR1yFaA0v/GsH6Fgp8ah6XV0WDz6CN8WO0ek4McMzb7A2xnf4DCYV43frjCygvb9f/wx7UUxRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "enhanced-resolve": "^5.17.0", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^15.8.0", + "ignore": "^5.2.4", + "minimatch": "^9.0.5", + "semver": "^7.5.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-obsidianmd": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-plugin-obsidianmd/-/eslint-plugin-obsidianmd-0.1.9.tgz", + "integrity": "sha512-/gyo5vky3Y7re4BtT/8MQbHU5Wes4o6VRqas3YmXE7aTCnMsdV0kfzV1GDXJN9Hrsc9UQPoeKUMiapKL0aGE4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/eslint-plugin-sdl": "^1.1.0", + "@types/eslint": "8.56.2", + "@types/node": "20.12.12", + "eslint": ">=9.0.0 <10.0.0", + "eslint-plugin-depend": "1.3.1", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-json-schema-validator": "5.1.0", + "eslint-plugin-security": "2.1.1", + "globals": "14.0.0", + "obsidian": "1.8.7", + "typescript": "5.4.5" + }, + "bin": { + "eslint-plugin-obsidian": "dist/lib/index.js" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@eslint/js": "^9.30.1", + "@eslint/json": "0.14.0", + "eslint": ">=9.0.0 <10.0.0", + "obsidian": "1.8.7", + "typescript-eslint": "^8.35.1" + } + }, + "node_modules/eslint-plugin-obsidianmd/node_modules/@types/node": { + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/eslint-plugin-obsidianmd/node_modules/obsidian": { + "version": "1.8.7", + "resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.8.7.tgz", + "integrity": "sha512-h4bWwNFAGRXlMlMAzdEiIM2ppTGlrh7uGOJS6w4gClrsjc+ei/3YAtU2VdFUlCiPuTHpY4aBpFJJW75S1Tl/JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/codemirror": "5.60.8", + "moment": "2.29.4" + }, + "peerDependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/eslint-plugin-obsidianmd/node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz", + "integrity": "sha512-DomWuTQPFYZwF/7c9W2fkKkStqZmBd3uugfqBYLdkZ3Hii23WzZuOLUskGxB8qkSKqftxEeGL1TB2kMhrce0jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-security": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-2.1.1.tgz", + "integrity": "sha512-7cspIGj7WTfR3EhaILzAPcfCo5R9FbeWvbgsPYWivSurTBKW88VQxtP3c4aWMG9Hz/GfJlJVdXEJ3c8LqS+u2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-regex": "^2.1.1" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "license": "BSD-2-Clause", - "peer": true, + "license": "Apache-2.0", "engines": { - "node": ">=4.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -1333,7 +2479,6 @@ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -1341,17 +2486,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -1365,7 +2499,7 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", @@ -1375,23 +2509,12 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1401,8 +2524,7 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", @@ -1439,16 +2561,31 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastq": { "version": "1.20.1", @@ -1461,17 +2598,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -1493,7 +2629,6 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -1506,19 +2641,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -1526,45 +2659,143 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "peer": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "is-callable": "^1.2.7" }, "engines": { - "node": "*" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, "node_modules/glob-parent": { @@ -1573,7 +2804,6 @@ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -1582,50 +2812,74 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/has-flag": { "version": "4.0.0", @@ -1633,22 +2887,79 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } }, - "node_modules/html2canvas": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", - "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { - "css-line-break": "^2.1.0", - "text-segmentation": "^1.0.3" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/ignore": { @@ -1667,7 +2978,6 @@ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1685,31 +2995,159 @@ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, - "license": "ISC", - "peer": true, + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, - "license": "ISC", - "peer": true + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-extglob": { "version": "2.1.1", @@ -1721,6 +3159,42 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1734,6 +3208,32 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1744,24 +3244,216 @@ "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", - "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.1", @@ -1769,7 +3461,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -1782,24 +3473,134 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-migrate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/json-schema-migrate/-/json-schema-migrate-2.0.0.tgz", + "integrity": "sha512-r38SVTtojDRp4eD6WsCqiE0eNDt4v1WalBXb9cyZYw9ai5cGtBwzRNWjHzJl38w6TxFkXAIA7h+fyX3tnrAFhQ==", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "ajv": "^8.0.0" + } + }, + "node_modules/json-schema-migrate/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/json-schema-migrate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.2.tgz", + "integrity": "sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } }, "node_modules/keyv": { "version": "4.5.4", @@ -1807,7 +3608,6 @@ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -1818,7 +3618,6 @@ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -1833,7 +3632,6 @@ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -1849,8 +3647,30 @@ "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/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "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/merge2": { "version": "1.4.1", @@ -1882,7 +3702,6 @@ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1890,11 +3709,27 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/module-replacements": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-2.11.0.tgz", + "integrity": "sha512-j5sNQm3VCpQQ7nTqGeOZtoJtV3uKERgCBm9QRhmGRiXiqkf7iRFOkfxdJRZWLkqYY8PNf4cDQF/WfXUYLENrRA==", + "dev": true, + "license": "MIT" + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -1912,14 +3747,164 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, + "license": "MIT" + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/obsidian": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.12.3.tgz", "integrity": "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw==", - "dev": true, "license": "MIT", "dependencies": { "@types/codemirror": "5.60.8", @@ -1930,24 +3915,12 @@ "@codemirror/view": "6.38.6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -1960,13 +3933,30 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -1983,7 +3973,6 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -2000,7 +3989,6 @@ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -2014,42 +4002,26 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "license": "MIT" }, "node_modules/picomatch": { "version": "2.3.2", @@ -2064,24 +4036,44 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -2107,17 +4099,99 @@ ], "license": "MIT" }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { @@ -2126,11 +4200,30 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -2142,24 +4235,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -2184,6 +4259,92 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", @@ -2197,13 +4358,61 @@ "node": ">=10" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2217,33 +4426,206 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "peer": true, "dependencies": { - "ansi-regex": "^5.0.1" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/strip-json-comments": { @@ -2252,7 +4634,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" }, @@ -2264,7 +4645,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", "integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==", - "dev": true, "license": "MIT", "peer": true }, @@ -2274,7 +4654,6 @@ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -2282,22 +4661,56 @@ "node": ">=8" } }, - "node_modules/text-segmentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", - "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", - "license": "MIT", - "dependencies": { - "utrie": "^1.0.2" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.3.tgz", + "integrity": "sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tapable": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -2312,6 +4725,61 @@ "node": ">=8.0" } }, + "node_modules/toml-eslint-parser": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz", + "integrity": "sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/toml-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -2319,36 +4787,25 @@ "dev": true, "license": "0BSD" }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "tslib": "^1.8.1" + "safe-buffer": "^5.0.1" }, "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "node": "*" } }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -2356,24 +4813,88 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, - "license": "(MIT OR CC0-1.0)", - "peer": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2381,34 +4902,72 @@ "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.35.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.35.1.tgz", + "integrity": "sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.35.1", + "@typescript-eslint/parser": "8.35.1", + "@typescript-eslint/utils": "8.35.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "punycode": "^2.1.0" } }, - "node_modules/utrie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", - "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", - "license": "MIT", - "dependencies": { - "base64-arraybuffer": "^1.0.2" - } - }, "node_modules/w3c-keyname": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "dev": true, "license": "MIT", "peer": true }, @@ -2418,7 +4977,6 @@ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2429,24 +4987,150 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, "license": "ISC", - "peer": true + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yaml-eslint-parser": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.3.2.tgz", + "integrity": "sha512-odxVsHAkZYYglR30aPYRY4nUGJnoJ2y1ww2HDvZALo0BDETv9kWbi16J52eHs+PWRNmF4ub6nZqfVOeesOvntg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "yaml": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, "node_modules/yocto-queue": { "version": "0.1.0", @@ -2454,7 +5138,6 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 193b1d6..e7f091d 100644 --- a/package.json +++ b/package.json @@ -3,30 +3,27 @@ "version": "0.1.0", "description": "Export Obsidian notes to VitePress", "main": "main.js", + "type": "module", "scripts": { "dev": "node esbuild.config.mjs", "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", - "version": "node version-bump.mjs && git add manifest.json versions.json" + "version": "node version-bump.mjs && git add manifest.json versions.json", + "lint": "eslint ." }, - "keywords": [ - "obsidian", - "vitepress", - "export" - ], - "author": "Your Name", - "license": "MIT", + "keywords": [], + "license": "0-BSD", "devDependencies": { "@types/node": "^16.11.6", - "@typescript-eslint/eslint-plugin": "5.29.0", - "@typescript-eslint/parser": "5.29.0", - "builtin-modules": "3.3.0", - "dom-to-image-more": "^3.7.2", - "esbuild": "0.17.3", - "obsidian": "latest", + "esbuild": "0.25.5", + "eslint-plugin-obsidianmd": "0.1.9", + "globals": "14.0.0", "tslib": "2.4.0", - "typescript": "4.7.4" + "typescript": "^5.8.3", + "typescript-eslint": "8.35.1", + "@eslint/js": "9.30.1", + "jiti": "2.6.1" }, "dependencies": { - "dom-to-image-more": "^3.7.2" + "obsidian": "latest" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 9e80298..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,1443 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - devDependencies: - '@types/node': - specifier: ^16.11.6 - version: 16.18.126 - '@typescript-eslint/eslint-plugin': - specifier: 5.29.0 - version: 5.29.0(@typescript-eslint/parser@5.29.0(eslint@8.57.1)(typescript@4.7.4))(eslint@8.57.1)(typescript@4.7.4) - '@typescript-eslint/parser': - specifier: 5.29.0 - version: 5.29.0(eslint@8.57.1)(typescript@4.7.4) - builtin-modules: - specifier: 3.3.0 - version: 3.3.0 - dom-to-image-more: - specifier: ^3.7.2 - version: 3.7.2 - esbuild: - specifier: 0.17.3 - version: 0.17.3 - obsidian: - specifier: latest - version: 1.12.3(@codemirror/state@6.5.0)(@codemirror/view@6.38.6) - tslib: - specifier: 2.4.0 - version: 2.4.0 - typescript: - specifier: 4.7.4 - version: 4.7.4 - -packages: - - '@codemirror/state@6.5.0': - resolution: {integrity: sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==} - - '@codemirror/view@6.38.6': - resolution: {integrity: sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==} - - '@esbuild/android-arm64@0.17.3': - resolution: {integrity: sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.17.3': - resolution: {integrity: sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.17.3': - resolution: {integrity: sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.17.3': - resolution: {integrity: sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.17.3': - resolution: {integrity: sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.17.3': - resolution: {integrity: sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.17.3': - resolution: {integrity: sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.17.3': - resolution: {integrity: sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.17.3': - resolution: {integrity: sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.17.3': - resolution: {integrity: sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.17.3': - resolution: {integrity: sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.17.3': - resolution: {integrity: sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.17.3': - resolution: {integrity: sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.17.3': - resolution: {integrity: sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.17.3': - resolution: {integrity: sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.17.3': - resolution: {integrity: sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.17.3': - resolution: {integrity: sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.17.3': - resolution: {integrity: sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.17.3': - resolution: {integrity: sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.17.3': - resolution: {integrity: sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.17.3': - resolution: {integrity: sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.17.3': - resolution: {integrity: sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead - - '@marijn/find-cluster-break@1.0.2': - resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@types/codemirror@5.60.8': - resolution: {integrity: sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@16.18.126': - resolution: {integrity: sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==} - - '@types/tern@0.23.9': - resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==} - - '@typescript-eslint/eslint-plugin@5.29.0': - resolution: {integrity: sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@5.29.0': - resolution: {integrity: sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/scope-manager@5.29.0': - resolution: {integrity: sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@typescript-eslint/type-utils@5.29.0': - resolution: {integrity: sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/types@5.29.0': - resolution: {integrity: sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@typescript-eslint/typescript-estree@5.29.0': - resolution: {integrity: sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/utils@5.29.0': - resolution: {integrity: sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - - '@typescript-eslint/visitor-keys@5.29.0': - resolution: {integrity: sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.14.0: - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - crelt@1.0.6: - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dom-to-image-more@3.7.2: - resolution: {integrity: sha512-uQf+pHv6eQhgfI8t2bFuinV0KsPyT8TZgCLwcSU8uBVgN9v6leb0mMpvp6HQAlAcplP3NCcGjxbdqef6pTzvmw==} - - esbuild@0.17.3: - resolution: {integrity: sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==} - engines: {node: '>=12'} - hasBin: true - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-utils@3.0.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - - eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - functional-red-black-tree@1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - - moment@2.29.4: - resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - obsidian@1.12.3: - resolution: {integrity: sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw==} - peerDependencies: - '@codemirror/state': 6.5.0 - '@codemirror/view': 6.38.6 - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - style-mod@4.1.3: - resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - tslib@2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} - - tsutils@3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - typescript@4.7.4: - resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} - engines: {node: '>=4.2.0'} - hasBin: true - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - -snapshots: - - '@codemirror/state@6.5.0': - dependencies: - '@marijn/find-cluster-break': 1.0.2 - - '@codemirror/view@6.38.6': - dependencies: - '@codemirror/state': 6.5.0 - crelt: 1.0.6 - style-mod: 4.1.3 - w3c-keyname: 2.2.8 - - '@esbuild/android-arm64@0.17.3': - optional: true - - '@esbuild/android-arm@0.17.3': - optional: true - - '@esbuild/android-x64@0.17.3': - optional: true - - '@esbuild/darwin-arm64@0.17.3': - optional: true - - '@esbuild/darwin-x64@0.17.3': - optional: true - - '@esbuild/freebsd-arm64@0.17.3': - optional: true - - '@esbuild/freebsd-x64@0.17.3': - optional: true - - '@esbuild/linux-arm64@0.17.3': - optional: true - - '@esbuild/linux-arm@0.17.3': - optional: true - - '@esbuild/linux-ia32@0.17.3': - optional: true - - '@esbuild/linux-loong64@0.17.3': - optional: true - - '@esbuild/linux-mips64el@0.17.3': - optional: true - - '@esbuild/linux-ppc64@0.17.3': - optional: true - - '@esbuild/linux-riscv64@0.17.3': - optional: true - - '@esbuild/linux-s390x@0.17.3': - optional: true - - '@esbuild/linux-x64@0.17.3': - optional: true - - '@esbuild/netbsd-x64@0.17.3': - optional: true - - '@esbuild/openbsd-x64@0.17.3': - optional: true - - '@esbuild/sunos-x64@0.17.3': - optional: true - - '@esbuild/win32-arm64@0.17.3': - optional: true - - '@esbuild/win32-ia32@0.17.3': - optional: true - - '@esbuild/win32-x64@0.17.3': - optional: true - - '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.14.0 - debug: 4.4.3 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.5 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.1': {} - - '@humanwhocodes/config-array@0.13.0': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.5 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@2.0.3': {} - - '@marijn/find-cluster-break@1.0.2': {} - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@types/codemirror@5.60.8': - dependencies: - '@types/tern': 0.23.9 - - '@types/estree@1.0.8': {} - - '@types/json-schema@7.0.15': {} - - '@types/node@16.18.126': {} - - '@types/tern@0.23.9': - dependencies: - '@types/estree': 1.0.8 - - '@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.29.0(eslint@8.57.1)(typescript@4.7.4))(eslint@8.57.1)(typescript@4.7.4)': - dependencies: - '@typescript-eslint/parser': 5.29.0(eslint@8.57.1)(typescript@4.7.4) - '@typescript-eslint/scope-manager': 5.29.0 - '@typescript-eslint/type-utils': 5.29.0(eslint@8.57.1)(typescript@4.7.4) - '@typescript-eslint/utils': 5.29.0(eslint@8.57.1)(typescript@4.7.4) - debug: 4.4.3 - eslint: 8.57.1 - functional-red-black-tree: 1.0.1 - ignore: 5.3.2 - regexpp: 3.2.0 - semver: 7.7.4 - tsutils: 3.21.0(typescript@4.7.4) - optionalDependencies: - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@5.29.0(eslint@8.57.1)(typescript@4.7.4)': - dependencies: - '@typescript-eslint/scope-manager': 5.29.0 - '@typescript-eslint/types': 5.29.0 - '@typescript-eslint/typescript-estree': 5.29.0(typescript@4.7.4) - debug: 4.4.3 - eslint: 8.57.1 - optionalDependencies: - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@5.29.0': - dependencies: - '@typescript-eslint/types': 5.29.0 - '@typescript-eslint/visitor-keys': 5.29.0 - - '@typescript-eslint/type-utils@5.29.0(eslint@8.57.1)(typescript@4.7.4)': - dependencies: - '@typescript-eslint/utils': 5.29.0(eslint@8.57.1)(typescript@4.7.4) - debug: 4.4.3 - eslint: 8.57.1 - tsutils: 3.21.0(typescript@4.7.4) - optionalDependencies: - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@5.29.0': {} - - '@typescript-eslint/typescript-estree@5.29.0(typescript@4.7.4)': - dependencies: - '@typescript-eslint/types': 5.29.0 - '@typescript-eslint/visitor-keys': 5.29.0 - debug: 4.4.3 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.7.4 - tsutils: 3.21.0(typescript@4.7.4) - optionalDependencies: - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@5.29.0(eslint@8.57.1)(typescript@4.7.4)': - dependencies: - '@types/json-schema': 7.0.15 - '@typescript-eslint/scope-manager': 5.29.0 - '@typescript-eslint/types': 5.29.0 - '@typescript-eslint/typescript-estree': 5.29.0(typescript@4.7.4) - eslint: 8.57.1 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0(eslint@8.57.1) - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@5.29.0': - dependencies: - '@typescript-eslint/types': 5.29.0 - eslint-visitor-keys: 3.4.3 - - '@ungap/structured-clone@1.3.0': {} - - acorn-jsx@5.3.2(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - - acorn@8.16.0: {} - - ajv@6.14.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - argparse@2.0.1: {} - - array-union@2.1.0: {} - - balanced-match@1.0.2: {} - - brace-expansion@1.1.14: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - builtin-modules@3.3.0: {} - - callsites@3.1.0: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - concat-map@0.0.1: {} - - crelt@1.0.6: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dom-to-image-more@3.7.2: {} - - esbuild@0.17.3: - optionalDependencies: - '@esbuild/android-arm': 0.17.3 - '@esbuild/android-arm64': 0.17.3 - '@esbuild/android-x64': 0.17.3 - '@esbuild/darwin-arm64': 0.17.3 - '@esbuild/darwin-x64': 0.17.3 - '@esbuild/freebsd-arm64': 0.17.3 - '@esbuild/freebsd-x64': 0.17.3 - '@esbuild/linux-arm': 0.17.3 - '@esbuild/linux-arm64': 0.17.3 - '@esbuild/linux-ia32': 0.17.3 - '@esbuild/linux-loong64': 0.17.3 - '@esbuild/linux-mips64el': 0.17.3 - '@esbuild/linux-ppc64': 0.17.3 - '@esbuild/linux-riscv64': 0.17.3 - '@esbuild/linux-s390x': 0.17.3 - '@esbuild/linux-x64': 0.17.3 - '@esbuild/netbsd-x64': 0.17.3 - '@esbuild/openbsd-x64': 0.17.3 - '@esbuild/sunos-x64': 0.17.3 - '@esbuild/win32-arm64': 0.17.3 - '@esbuild/win32-ia32': 0.17.3 - '@esbuild/win32-x64': 0.17.3 - - escape-string-regexp@4.0.0: {} - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-utils@3.0.0(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 2.1.0 - - eslint-visitor-keys@2.1.0: {} - - eslint-visitor-keys@3.4.3: {} - - eslint@8.57.1: - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@eslint-community/regexpp': 4.12.2 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.3.0 - ajv: 6.14.0 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.1 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.5 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - espree@9.6.1: - dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) - eslint-visitor-keys: 3.4.3 - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.4.2 - keyv: 4.5.4 - rimraf: 3.0.2 - - flatted@3.4.2: {} - - fs.realpath@1.0.0: {} - - functional-red-black-tree@1.0.1: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.5 - once: 1.4.0 - path-is-absolute: 1.0.1 - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - graphemer@1.4.0: {} - - has-flag@4.0.0: {} - - ignore@5.3.2: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} - - isexe@2.0.0: {} - - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.2 - - minimatch@3.1.5: - dependencies: - brace-expansion: 1.1.14 - - moment@2.29.4: {} - - ms@2.1.3: {} - - natural-compare@1.4.0: {} - - obsidian@1.12.3(@codemirror/state@6.5.0)(@codemirror/view@6.38.6): - dependencies: - '@codemirror/state': 6.5.0 - '@codemirror/view': 6.38.6 - '@types/codemirror': 5.60.8 - moment: 2.29.4 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-type@4.0.0: {} - - picomatch@2.3.2: {} - - prelude-ls@1.2.1: {} - - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - - regexpp@3.2.0: {} - - resolve-from@4.0.0: {} - - reusify@1.1.0: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - semver@7.7.4: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - slash@3.0.0: {} - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-json-comments@3.1.1: {} - - style-mod@4.1.3: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - text-table@0.2.0: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tslib@1.14.1: {} - - tslib@2.4.0: {} - - tsutils@3.21.0(typescript@4.7.4): - dependencies: - tslib: 1.14.1 - typescript: 4.7.4 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@0.20.2: {} - - typescript@4.7.4: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - w3c-keyname@2.2.8: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - word-wrap@1.2.5: {} - - wrappy@1.0.2: {} - - yocto-queue@0.1.0: {} diff --git a/puppeteer_version.txt b/puppeteer_version.txt deleted file mode 100644 index 32fee9c..0000000 --- a/puppeteer_version.txt +++ /dev/null @@ -1,92 +0,0 @@ - // 尝试使用 Puppeteer 截图 Canvas(保留完整样式) - async tryNativeCanvasCapture(canvasFile: TFile): Promise { - let newWindowLeaf: any = null; - - try { - console.log('🔍 Step 1: Opening canvas in new window...'); - - // 创建新窗口 - newWindowLeaf = this.app.workspace.getLeaf('window'); - if (!newWindowLeaf) { - console.log('❌ Failed to create new window'); - return null; - } - - console.log('✅ New window created, opening canvas file...'); - await newWindowLeaf.openFile(canvasFile); - - console.log('⏳ Step 2: Waiting for canvas render...'); - // 等待 Canvas 渲染 - await new Promise(resolve => setTimeout(resolve, 3000)); - - console.log('📸 Step 3: Capturing with Puppeteer...'); - // @ts-ignore - const puppeteer = require('puppeteer'); - - // 启动 Puppeteer - const browser = await puppeteer.launch({ - headless: true, - args: ['--no-sandbox', '--disable-setuid-sandbox'] - }); - - try { - const page = await browser.newPage(); - - // 获取新窗口的 HTML 内容 - const container = newWindowLeaf.containerEl; - const canvasWrapper = container.querySelector('.canvas-wrapper'); - - if (!canvasWrapper) { - console.log('❌ Could not find canvas wrapper'); - return null; - } - - // 获取完整的 HTML,包括所有样式 - const htmlContent = canvasWrapper.outerHTML; - - // 设置 HTML 内容 - await page.setContent(htmlContent, { - waitUntil: 'networkidle0', - timeout: 10000 - }); - - // 计算内容尺寸 - const contentSize = this.getCanvasContentSize(canvasWrapper); - const viewportWidth = Math.ceil(contentSize.width); - const viewportHeight = Math.ceil(contentSize.height); - - console.log(`📸 Screenshot size: ${viewportWidth}x${viewportHeight}`); - - // 截图 - const screenshot = await page.screenshot({ - type: 'png', - clip: { - x: contentSize.offsetX, - y: contentSize.offsetY, - width: contentSize.width, - height: contentSize.height - } - }); - - console.log('✅ Capture successful!'); - return new Uint8Array(screenshot); - - } finally { - await browser.close(); - } - - } catch (error) { - console.error('❌ Puppeteer capture failed:', error); - return null; - } finally { - // 关闭新窗口 - if (newWindowLeaf) { - try { - newWindowLeaf.detach(); - console.log('🧹 Closed new window'); - } catch (e) { - console.log('⚠️ Could not close new window:', e); - } - } - } - } diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..b3d97ec --- /dev/null +++ b/src/main.ts @@ -0,0 +1,448 @@ +import { Plugin, TFile, Notice } from 'obsidian'; +import { DEFAULT_SETTINGS, VitePressExporterSettings, VitePressExporterSettingTab } from "./settings"; + + + +export default class VitePressExporterPlugin extends Plugin { + settings!: VitePressExporterSettings; + + async onload() { + await this.loadSettings(); + + // 添加导出命令 + this.addCommand({ + id: 'export-to-vitepress', + name: 'Export current note to VitePress', + callback: () => { + this.exportCurrentNote(); + } + }); + + // Add file menu item + this.registerEvent( + // @ts-ignore + this.app.workspace.on("file-menu", (menu: any, file: TFile) => { + if (file.extension === "md") { + menu.addItem((item: any) => { + item + .setTitle("Export to VitePress") + .setIcon("upload") + .onClick(() => { + this.exportNote(file); + }); + }); + } + }) + ); + + // Add editor menu item + this.registerEvent( + this.app.workspace.on("editor-menu", (menu: any) => { + menu.addItem((item: any) => { + item + .setTitle("Export to VitePress") + .setIcon("upload") + .onClick(() => { + this.exportCurrentNote(); + }); + }); + }) + ); + + // 添加设置面板 + this.addSettingTab(new VitePressExporterSettingTab(this.app, this)); + + console.log('VitePress Exporter plugin loaded'); + } + + onunload() { + console.log('VitePress Exporter plugin unloaded'); + } + + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } + + async saveSettings() { + await this.saveData(this.settings); + } + + // 导出当前笔记 + async exportCurrentNote() { + const activeFile = this.app.workspace.getActiveFile(); + + if (!activeFile) { + new Notice('No active file found'); + return; + } + + if (activeFile.extension !== 'md') { + new Notice('Current file is not a markdown file'); + return; + } + + await this.exportNote(activeFile); + } + + // 导出单个笔记 + async exportNote(file: TFile) { + const { vault } = this.app; + + // 使用 binary 模式读取文件以保留原始格式(包括行尾空格) + const contentBuffer = await vault.readBinary(file); + const content = new TextDecoder().decode(contentBuffer); + + // 1. 扫描并复制所有资源文件(传入文件对象用于路径解析) + const updatedContent = await this.processAssets(content, file); + + // 2. 处理 canvas 引用(暂时保留,后续实现) + // const finalContent = await this.processCanvases(updatedContent); + + // 3. 写入到 docs 目录(使用 binary 模式保留原始格式) + const docsPath = `${this.settings.docsPath}/${file.name}`; + const updatedBuffer = new TextEncoder().encode(updatedContent); + await vault.adapter.writeBinary(docsPath, updatedBuffer.buffer); + + console.log(`Exported ${file.name} to ${docsPath}`); + } + + // 处理资源文件 + async processAssets(content: string, sourceFile: TFile): Promise { + const { vault, metadataCache } = this.app; + + console.log('Processing assets for file:', sourceFile.path); + + // 使用 Obsidian API 获取文件的所有嵌入和链接 + const cache = metadataCache.getCache(sourceFile.path); + + console.log('Cache:', cache); + console.log('Embeds:', cache?.embeds); + console.log('Links:', cache?.links); + + if (!cache) { + console.log('No cache found for file'); + return content; + } + + const assetsToCopy = new Set(); + const canvasFiles = new Set(); + + // 收集嵌入文件(图片等) + if (cache.embeds) { + for (const embed of cache.embeds) { + console.log('Processing embed:', embed); + const resolvedLink = metadataCache.getFirstLinkpathDest(embed.link, sourceFile.path); + console.log('Resolved link for embed:', resolvedLink?.path); + if (resolvedLink) { + // 检查是否是 canvas 文件 + if (resolvedLink.extension === 'canvas') { + canvasFiles.add(resolvedLink.path); + } else { + assetsToCopy.add(resolvedLink.path); + } + } + } + } + + // 收集普通链接(可选,如果也想复制链接的文件) + if (cache.links) { + for (const link of cache.links) { + const resolvedLink = metadataCache.getFirstLinkpathDest(link.link, sourceFile.path); + // 只复制本地文件链接,不包括其他 md 文件 + if (resolvedLink && resolvedLink.extension !== 'md') { + assetsToCopy.add(resolvedLink.path); + } + } + } + + console.log('Assets to copy:', Array.from(assetsToCopy)); + console.log('Canvas files to render:', Array.from(canvasFiles)); + + // 处理 Canvas 文件:渲染为图片 + for (const canvasPath of canvasFiles) { + try { + const canvasFile = vault.getAbstractFileByPath(canvasPath); + if (canvasFile instanceof TFile) { + const renderedImage = await this.renderCanvas(canvasFile); + if (renderedImage) { + const imageFileName = canvasFile.name.replace('.canvas', '.png'); + // 图片保存到 docs/assets/ + const imagePath = `${this.settings.assetsPath}/${imageFileName}`; + + // 确保目标目录存在 + await vault.adapter.mkdir(this.settings.assetsPath); + + // 写入渲染的图片 + await vault.adapter.writeBinary(imagePath, renderedImage.buffer); + + // 更新内容中的 canvas 引用,使用相对路径 assets/xxx.png + content = this.updateCanvasLinksInContent(content, canvasFile, canvasPath, imageFileName); + + console.log(`Successfully rendered canvas: ${canvasPath} -> ${imagePath}`); + } + } + } catch (error) { + console.error(`Failed to render canvas ${canvasPath}:`, error); + } + } + + // 复制资源文件到 docs/assets + for (const assetPath of assetsToCopy) { + try { + const sourceFile = vault.getAbstractFileByPath(assetPath); + console.log('Source file for asset:', sourceFile); + + if (sourceFile instanceof TFile) { + // 使用 binary 读取模式来保留文件原始内容 + const assetContent = await vault.readBinary(sourceFile); + const fileName = sourceFile.name; + const destPath = `${this.settings.assetsPath}/${fileName}`; + + console.log('Copying asset:', assetPath, '->', destPath); + + // 确保目标目录存在 + await vault.adapter.mkdir(this.settings.assetsPath); + + // 写入资源文件(使用 binary 模式) + await vault.adapter.writeBinary(destPath, assetContent); + + // 更新内容中的资源路径(使用更智能的替换) + content = this.updateLinksInContent(content, sourceFile, assetPath, fileName); + + console.log(`Successfully copied asset: ${assetPath} -> ${destPath}`); + } + } catch (error) { + console.error(`Failed to copy asset ${assetPath}:`, error); + } + } + + return content; + } + + // 更新内容中的链接 + updateLinksInContent(content: string, sourceFile: TFile, assetPath: string, newFileName: string): string { + // 获取源文件的目录路径 + const sourceDir = sourceFile.path.substring(0, sourceFile.path.lastIndexOf('/')); + if (!sourceDir) return content; + + // 尝试多种可能的路径格式 + const possiblePaths = [ + // 完整路径 + assetPath, + // 相对于源文件的路径 + assetPath.substring(sourceDir.length + 1), + // URL 编码版本 + encodeURI(assetPath), + encodeURI(assetPath.substring(sourceDir.length + 1)), + // 文件名 + sourceFile.name, + encodeURI(sourceFile.name) + ]; + + console.log('Trying to replace links for paths:', possiblePaths); + + // 替换 markdown 格式: ![](path) -> ![](assets/newfile.png) + const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; + content = content.replace(markdownRegex, (match, alt, path) => { + // 检查这个路径是否匹配我们的目标文件 + for (const testPath of possiblePaths) { + if (path === testPath || path === testPath.replace(/^\//, '')) { + console.log(`Found matching link: ${path} -> ${this.settings.assetsPath}/${newFileName}`); + return `![](${this.settings.assetsPath}/${newFileName})`; + } + } + return match; + }); + + // 替换 wikilink 格式: ![[path]] -> ![[assets/newfile.png]] + const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; + content = content.replace(wikilinkRegex, (match, link) => { + // 移除可能的别名字段 + const cleanLink = link.split('|')[0].trim(); + + for (const testPath of possiblePaths) { + if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { + console.log(`Found matching wikilink: ${cleanLink} -> ${this.settings.assetsPath}/${newFileName}`); + return `![[${this.settings.assetsPath}/${newFileName}]]`; + } + } + return match; + }); + + return content; + } + + // 尝试捕获 Obsidian 原生 Canvas 渲染(通过临时调整视口大小) + async renderCanvas(canvasFile: TFile): Promise { + + const activeLeaf = this.app.workspace.getLeaf(); + if (!activeLeaf) { + console.log('❌ No active leaf found'); + return null; + } + + await activeLeaf.openFile(canvasFile); + + //@ts-ignore + const canvas = activeLeaf.view.canvas; + if (!canvas) { + console.log("Could not get canvas object from view"); + return null; + } + // Use Canvas internal API + const imageData = await this.exportCanvasWithInternalAPI(canvas, canvasFile); + + if (!imageData) { + console.log("Canvas internal API capture failed"); + return null; + } + console.log("Canvas internal API capture successful!"); + return imageData; + + } + + // Use Canvas internal API to export + async exportCanvasWithInternalAPI( + canvas: any, + canvasFile: TFile + ): Promise { + try { + console.log("=== Using Canvas Internal API ==="); + + const { vault } = this.app; + + // 1. Get viewport bbox + // @ts-ignore + const bbox = canvas.getViewportBBox(); + console.log("Viewport bbox:", bbox); + + // 2. Calculate content size + const contentWidth = bbox.maxX - bbox.minX; + const contentHeight = bbox.maxY - bbox.minY; + console.log(`Content size: ${contentWidth}x${contentHeight}`); + + // 3. Set zoom = 0 (100%) + // @ts-ignore + const oldZoom = canvas.zoom; + // @ts-ignore + canvas.zoom = 0; + console.log(`Set zoom from ${oldZoom} to 0 (100%)`); + + // 4. Request frame + // @ts-ignore + canvas.requestFrame(); + await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise(resolve => requestAnimationFrame(resolve)); + + + // Generate temp filename (relative path) + const tempFileName = `temp_canvas_${Date.now()}.png`; + + // Ensure assets directory exists + await vault.adapter.mkdir(this.settings.assetsPath); + + // Generate final save path (relative path) + const finalFileName = canvasFile.name.replace(".canvas", ".png"); + const finalPath = `${this.settings.assetsPath}/${finalFileName}`; + + // Get vault full path + // @ts-ignore + const vaultBasePath = vault.adapter.basePath; + console.log("Vault base path:", vaultBasePath); + + // Build temp file absolute path + const tempFullPath = `${vaultBasePath}/${tempFileName}`; + console.log("Temp full path:", tempFullPath); + + // Call takeScreenshot (using absolute path) + // @ts-ignore + await canvas.takeScreenshot(tempFullPath, false); + console.log(`Screenshot saved to ${tempFullPath}`); + + // Wait for file write to complete + await new Promise(resolve => setTimeout(resolve, 100)); + + // Read temp file (using relative path, returns ArrayBuffer) + const imageBuffer = await vault.adapter.readBinary(tempFileName); + console.log(`Read imageBuffer, type: ${imageBuffer?.constructor?.name}, byteLength: ${imageBuffer?.byteLength}`); + + // Check if read was successful + if (!imageBuffer || imageBuffer.byteLength === 0) { + console.error("Failed to read temporary file"); + return null; + } + + // Delete temp file + await vault.adapter.remove(tempFileName); + console.log("Removed temporary file"); + + // Write to final location (needs ArrayBuffer, not Uint8Array) + await vault.adapter.writeBinary(finalPath, imageBuffer); + console.log(`Image saved to ${finalPath}`); + + // Return Uint8Array + return new Uint8Array(imageBuffer); + + } catch (error) { + console.error("exportCanvasWithInternalAPI failed:", error); + return null; + } + } + + // 更新内容中的 Canvas 链接 + updateCanvasLinksInContent(content: string, canvasFile: TFile, canvasPath: string, imageFileName: string): string { + // 获取源文件的目录路径 + const sourceDir = canvasFile.path.substring(0, canvasFile.path.lastIndexOf('/')); + if (!sourceDir) return content; + + // 尝试多种可能的路径格式 + const possiblePaths = [ + // 完整路径 + canvasPath, + // 相对于源文件的路径 + canvasPath.substring(sourceDir.length + 1), + // URL 编码版本 + encodeURI(canvasPath), + encodeURI(canvasPath.substring(sourceDir.length + 1)), + // 文件名(包括和不包括 .canvas 扩展名) + canvasFile.name, + canvasFile.name.replace('.canvas', ''), + encodeURI(canvasFile.name), + encodeURI(canvasFile.name.replace('.canvas', '')) + ]; + + console.log('Trying to replace canvas links for paths:', possiblePaths); + + // 替换 markdown 格式: !(canvas) -> + const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; + content = content.replace(markdownRegex, (match, alt, path) => { + // 检查这个路径是否匹配我们的 canvas 文件 + for (const testPath of possiblePaths) { + if (path === testPath || path === testPath.replace(/^\//, '')) { + const relativePath = this.settings.assetsPath.replace('docs/', ''); + console.log(`Found matching canvas link: ${path} -> `); + return ``; + } + } + return match; + }); + + // 替换 wikilink 格式: ![[canvas]] -> + const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; + content = content.replace(wikilinkRegex, (match, link) => { + // 移除可能的别名字段 + const cleanLink = link.split('|')[0].trim(); + + for (const testPath of possiblePaths) { + if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { + const relativePath = this.settings.assetsPath.replace('docs/', ''); + console.log(`Found matching canvas wikilink: ${cleanLink} -> `); + return ``; + } + } + return match; + }); + + return content; + } +} \ No newline at end of file diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 0000000..06ea253 --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,52 @@ +import {App, PluginSettingTab, Setting} from "obsidian"; +import VitePressExporterPlugin from "./main"; + +export interface VitePressExporterSettings { + docsPath: string; + assetsPath: string; +} + +export const DEFAULT_SETTINGS: VitePressExporterSettings = { + docsPath: 'docs', + assetsPath: 'docs/assets' +} + +// 设置面板 +export class VitePressExporterSettingTab extends PluginSettingTab { + plugin: VitePressExporterPlugin; + + constructor(app: App, plugin: VitePressExporterPlugin) { + super(app, plugin); + this.plugin = plugin; + } + + display(): void { + const { containerEl } = this; + + containerEl.empty(); + + containerEl.createEl('h2', { text: 'VitePress Exporter Settings' }); + + new Setting(containerEl) + .setName('Docs path') + .setDesc('Path to the docs directory (relative to vault root)') + .addText(text => text + .setPlaceholder('docs') + .setValue(this.plugin.settings.docsPath) + .onChange(async (value) => { + this.plugin.settings.docsPath = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName('Assets path') + .setDesc('Path to the assets directory (relative to vault root)') + .addText(text => text + .setPlaceholder('docs/assets') + .setValue(this.plugin.settings.assetsPath) + .onChange(async (value) => { + this.plugin.settings.assetsPath = value; + await this.plugin.saveSettings(); + })); + } +} \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..71cc60f --- /dev/null +++ b/styles.css @@ -0,0 +1,8 @@ +/* + +This CSS file will be included with your plugin, and +available in the app when your plugin is enabled. + +If your plugin does not need CSS, delete this file. + +*/ diff --git a/tsconfig.json b/tsconfig.json index 0ee61f0..222535d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,30 @@ { - "compilerOptions": { - "baseUrl": ".", - "inlineSourceMap": true, - "inlineSources": true, - "module": "ESNext", - "target": "ES6", - "allowJs": true, - "noImplicitAny": true, - "moduleResolution": "node", - "importHelpers": true, - "isolatedModules": true, - "strictNullChecks": true, - "lib": [ - "DOM", - "ES5", - "ES6", - "ES7" - ] - }, - "include": [ - "**/*.ts" - ], - "exclude": [ - "node_modules", - "docs", - "**/*.vue" - ] + "compilerOptions": { + "baseUrl": "src", + "inlineSourceMap": true, + "inlineSources": true, + "module": "ESNext", + "target": "ES6", + "allowJs": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noImplicitReturns": true, + "moduleResolution": "node", + "importHelpers": true, + "noUncheckedIndexedAccess": true, + "isolatedModules": true, + "strictNullChecks": true, + "strictBindCallApply": true, + "allowSyntheticDefaultImports": true, + "useUnknownInCatchVariables": true, + "lib": [ + "DOM", + "ES5", + "ES6", + "ES7" + ] + }, + "include": [ + "src/**/*.ts" + ] } diff --git a/version-bump.mjs b/version-bump.mjs new file mode 100644 index 0000000..55d631f --- /dev/null +++ b/version-bump.mjs @@ -0,0 +1,17 @@ +import { readFileSync, writeFileSync } from "fs"; + +const targetVersion = process.env.npm_package_version; + +// read minAppVersion from manifest.json and bump version to target version +const manifest = JSON.parse(readFileSync("manifest.json", "utf8")); +const { minAppVersion } = manifest; +manifest.version = targetVersion; +writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t")); + +// update versions.json with target version and minAppVersion from manifest.json +// but only if the target version is not already in versions.json +const versions = JSON.parse(readFileSync('versions.json', 'utf8')); +if (!Object.values(versions).includes(minAppVersion)) { + versions[targetVersion] = minAppVersion; + writeFileSync('versions.json', JSON.stringify(versions, null, '\t')); +} diff --git a/versions.json b/versions.json new file mode 100644 index 0000000..26382a1 --- /dev/null +++ b/versions.json @@ -0,0 +1,3 @@ +{ + "1.0.0": "0.15.0" +}