diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 00000000..04d4691d --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,59 @@ +# 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程 +# +name: Deploy VitePress site to Pages + +on: + # 在针对 `main` 分支的推送上运行。如果你 + # 使用 `master` 分支作为默认分支,请将其更改为 `master` + push: + branches: [master] + + # 允许你从 Actions 选项卡手动运行此工作流程 + workflow_dispatch: + +# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列 +# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成 +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # 构建工作 + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci + - name: Build with VitePress + run: npm run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # 部署工作 + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index e6dd3f3a..7a03ad50 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ package.nls.* TODO.md CHANGELOG-CODE.md + +docs/.vitepress/dist +docs/.vitepress/cache diff --git a/README.md b/README.md index 44da83b4..edf59faa 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,12 @@

Image Manager

-> View, compress, crop, convert formats, search, and find similar images in VS Code +

Powerful yet easy-to-use VSCode image management extension

-[中文文档](./README.zh.md) -## [Changelog](./CHANGELOG.md) +[中文](./README.zh.md) + +## [Document](https://hemengke1997.github.io/vscode-image-manager/) ## Screenshot @@ -56,96 +57,6 @@ - -## Features - -> **Absolutely secure, processed locally**. All image processing is done locally, ensuring privacy and security. - -- **Batch image compression** -- **Image cropper** -- **Image viewer** -- **Finding similar images** -- Multi-select (Shift/Ctrl/Cmd) -- View image details -- Finding images -- Conditional filtering of images -- Dark/light theme -- I18n support: `English`, `简体中文`, `繁體中文`, `日本語` - -## Usage - -**Several ways open extension** - -### 1.Shortcut - -- Windows: `Shift+Alt+J` -- macOS: `Cmd+Option+J` - -### 2.Context Menu - -Right-click in Explorer, select `Image Manager` to open the extension (opens the current folder). - -### 3.Command - -Press `Ctrl+Shift+P` (macOS: `Cmd+Shift+P`), type `Image Manager` to open (opens the workspace root folder). - -## [Extension Configurations](./docs//vscode-configuration.md) - -## Tips - -### Compression - -

- Right-click on the image - -![compress-right-click-image](./screenshots/compress-1.png) -
- -
- Right-click on the folder - -![compress-right-click-folder](./screenshots/compress-2.png) -
- - - -### Viewer - -- `Cmd/Ctrl + Mouse Wheel` to scale image size -- `Cmd/Ctrl + F` to open the `Search` modal - -### Common Questions - -#### Why is opening the extension slow the first time? - -The first time you open the extension, it will need to download the necessary dependencies. Depending on your network environment, this process may be slow. Please be patient! - -#### Why does the file get bigger after compression? - -- Meta information about whether the image is compressed is added during compression. As a result, a small image may become larger after compression. -- You can set `image-manager.compression.errorRange` to adjust the compression error range. - -#### What to do if there are too many images and it feels sluggish? - -- You can configure `image-manager.appearance.reduceMotion: 'on'` to reduce animation effects. -- You can open a specific directory by right-clicking on the folder, which will reduce the number of images rendered. - -## Support - -> If this plugin has been helpful to you, please consider buying the author a cup of coffee :) ☕️ -> -> Or give it a star by [clicking here](https://github.com/hemengke1997/vscode-image-manager) ⭐️ - -| Wechat Pay | Alipay | -| ------------------------------------------------------ | --------------------------------------------------- | -| | | - -## Feedback - -If you have any questions or suggestions, please raise them in [GitHub Issues](https://github.com/hemengke1997/vscode-image-manager/issues). - -If you find this plugin useful, please give it a good rating in the [Marketplace](https://marketplace.visualstudio.com/items?itemName=minko.image-manager&ssr=false#review-details). Thank you very much! Your support is my greatest motivation for open source. - ## Thanks ❤️ [vscode-image-viewer](https://github.com/ZhangJian1713/vscode-image-viewer) diff --git a/README.zh.md b/README.zh.md index 20d11a85..7c2c632c 100644 --- a/README.zh.md +++ b/README.zh.md @@ -6,11 +6,11 @@

Image Manager

-> 浏览、压缩、裁剪、转换格式、搜索、查找相似图片的 VS Code 插件 +

强大易用的VSCode图片管理插件

-[English Docs](./README.md) +[English](./README.md) -## [更新日志](./CHANGELOG.md) +## [文档](https://hemengke1997.github.io/vscode-image-manager/zh/) ## 插件截图 @@ -58,129 +58,6 @@ - - -## 核心功能 - -> **绝对安全,本地处理**。所有图片处理均在本地完成,确保隐私安全 - -- **图片批量压缩** -- **图片裁剪** -- **图片大图浏览** -- **相似图片查找** -- 支持多选(Shift/Ctrl/Cmd) -- 查看图片详情(尺寸、体积等) -- 查找图片 -- 条件筛选图片(根据 git-staged/图片大小/是否已压缩筛选) -- 暗黑/明亮主题,自定义 UI 主题色 -- 国际化。目前支持 `English`,`简体中文`,`繁體中文`,`日本語` - -## 使用方法 - -**有以下几种方式打开插件** - -### 1. 快捷键 - -- Windows: `Shift+Alt+J` -- macOS: `Cmd+Option+J` - -### 2. 右键菜单 - -在资源管理器中右键选择 `Image Manager 🏞️` 打开插件。 - -### 3. 命令面板 - -按 `Ctrl+Shift+P`(macOS: `Cmd+Shift+P`)打开命令面板,输入 `Image Manager` 并选择打开。 - -## [插件配置项](./docs/vscode-configuration.zh.md) - -## 小贴士 - -### 关于配置 - -大部分配置可以在插件页面中设置,比如主题、语言等。当然,也可以在 `settings.json` 中进行设置。 - -### 压缩 - -

- 在图片上右键,可以压缩单张图片 - -![compress-right-click-image](./screenshots/compress-cn-1.png) - -
- - -
- 在文件夹上右键,可以批量压缩文件夹下的所有图片 - -![compress-right-click-folder](./screenshots/compress-cn-2.png) - -
- -### 浏览区域 - -- `Cmd/Ctrl + 鼠标滚轮` 可以缩放图片大小。 -- `Cmd/Ctrl + F` 可以打开搜索窗口。 - -### 常见问题 - -#### 为什么第一次打开插件很慢? - -由于首次打开插件时需要下载必要的依赖,这个过程可能会比较慢,具体取决于您的网络环境。请耐心等待。 - -#### 报错:依赖安装失败,请检查网络 - -如果您在中国大陆且网络环境不佳(你懂的),有两种解决方案: - -1. 切换镜像源 -2. 手动安装依赖 - -##### 如何切换镜像源 - -使用命令面板,输入 `select mirror url` 并回车。 - -![选择](./screenshots/select-mirror-1.png) - -然后选择一个镜像源,重启 VS Code 并尝试重新下载依赖。 - -![选择](./screenshots/select-mirror-2.png) - -如果切换镜像源后依然安装失败,请手动安装依赖。 - -##### 如何手动安装依赖 - -1. 打开命令面板,输入 `Show Output Channel`,选择 Image Manager 对应的选项。 -2. 在输出中找到 `插件根目录 (Extension Root)`,之后需要用到。 -3. 下载 `Output Channel` 中打印的依赖地址。 -4. 将下载的文件放在步骤 2 的 `插件根目录`。 -5. 重启 VS Code 即可。 - -#### 为什么压缩后文件反而变大了? - -- 由于压缩时添加了「是否已压缩」的元信息,可能导致小体积图片压缩后变大。 -- 您可以设置 `image-manager.compression.errorRange` 来调整压缩误差范围。 - -#### 图片太多,感觉卡顿怎么办? - -- 可以配置 `image-manager.appearance.reduceMotion: 'on'` 来减少动画效果。 -- 可以使用右键文件夹的方式打开指定的目录,从而减少渲染的图片数量。 - -## 赞赏 - -> 如果这个插件能帮助到您,请作者喝杯咖啡吧 :) ☕️ -> -> 或者动动小手指 [点个 star](https://github.com/hemengke1997/vscode-image-manager) ⭐️ - -| 微信 | 支付宝 | -| ------------------------------------------------------ | --------------------------------------------------- | -| | | - -## 反馈 - -如果有任何问题或建议,请在 [GitHub Issues](https://github.com/hemengke1997/vscode-image-manager/issues) 中提出。 - -如果觉得此插件好用,请在 [Marketplace](https://marketplace.visualstudio.com/items?itemName=minko.image-manager&ssr=false#review-details) 中给予好评,非常感谢!你的支持是我开源的最大动力 - ## 感谢 ❤️ [vscode-image-viewer](https://github.com/ZhangJian1713/vscode-image-viewer) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 00000000..237ec8f4 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,164 @@ +import { defineConfig } from 'vitepress' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + base: '/vscode-image-manager/', + title: 'VSCode Image Manager', + locales: { + root: { + label: 'English', + lang: 'en', + description: 'View, compress, crop, convert format, search and find similary images in VSCode', + themeConfig: { + nav: [ + { + text: 'Changelog', + link: 'https://github.com/hemengke1997/vscode-image-manager/blob/master/CHANGELOG.md', + }, + ], + sidebar: [ + { + text: 'Guides', + items: [ + { text: 'Introduction', link: '/guides/introduction' }, + { text: 'Get Started', link: '/guides/get-started' }, + { + text: 'FAQ', + link: '/guides/faq', + }, + { + text: 'Support', + link: '/guides/support', + }, + { + text: 'Feedback', + link: '/guides/feedback', + }, + ], + }, + { + text: 'Features', + items: [ + { + text: 'Preview', + link: '/features/preview', + }, + { + text: 'Compress', + link: '/features/compress', + }, + { + text: 'Convert Format', + link: '/features/convert-format', + }, + { + text: 'Crop', + link: '/features/crop', + }, + { + text: 'Filter', + link: '/features/filter', + }, + { + text: 'Search', + link: '/features/search', + }, + { + text: 'Customize', + link: '/features/customize', + }, + ], + }, + { + text: 'Settings', + items: [ + { + text: 'VSCode Settings', + link: '/settings/vscode', + }, + ], + }, + ], + }, + }, + zh: { + label: '简体中文', + lang: 'zh', + description: '查看、压缩、裁剪、转换格式、搜索、过滤和查找相似图片的 VSCode 插件', + themeConfig: { + nav: [ + { + text: '更新日志', + link: 'https://github.com/hemengke1997/vscode-image-manager/blob/master/CHANGELOG.md', + }, + ], + sidebar: [ + { + text: '指南', + items: [ + { text: '介绍', link: '/zh/guides/introduction' }, + { text: '开始使用', link: '/zh/guides/get-started' }, + { + text: '常见问题', + link: '/zh/guides/faq', + }, + { + text: '支持作者', + link: '/zh/guides/support', + }, + { + text: '反馈', + link: '/zh/guides/feedback', + }, + ], + }, + { + text: '功能', + items: [ + { + text: '大图预览', + link: '/zh/features/preview', + }, + { + text: '图片压缩', + link: '/zh/features/compress', + }, + { + text: '格式转换', + link: '/zh/features/convert-format', + }, + { + text: '图片裁剪', + link: '/zh/features/crop', + }, + { + text: '图片筛选', + link: '/zh/features/filter', + }, + { + text: '图片搜索', + link: '/zh/features/search', + }, + { + text: '自定义设置', + link: '/zh/features/customize', + }, + ], + }, + { + text: '设置项', + items: [ + { + text: 'VSCode 设置项', + link: '/zh/settings/vscode', + }, + ], + }, + ], + }, + }, + }, + themeConfig: { + socialLinks: [{ icon: 'github', link: 'https://github.com/hemengke1997/vscode-image-manager' }], + }, +}) diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 00000000..2ef7144b --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,3 @@ +.vp-doc table tr { + text-wrap: nowrap; +} diff --git a/docs/.vitepress/theme/index.mts b/docs/.vitepress/theme/index.mts new file mode 100644 index 00000000..42fe9a93 --- /dev/null +++ b/docs/.vitepress/theme/index.mts @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme diff --git a/docs/features/compress.md b/docs/features/compress.md new file mode 100644 index 00000000..76af6c88 --- /dev/null +++ b/docs/features/compress.md @@ -0,0 +1,52 @@ +# Image Compression + +Image compression supports the following formats: `'png', 'jpg', 'jpeg', 'webp', 'gif', 'tiff', 'tif', 'avif', 'heif', 'svg'`. + +`svg` compression uses [`svgo`](https://svgo.dev/), while other formats use [`sharp`](https://sharp.pixelplumbing.com/). + +## Compression Options + +### Non-SVG + +![Compression Options](./images/compress-options.png) + +- **Image Quality**: `0-100`, `0` is the lowest quality, `100` is the highest quality. Default is `75`. +- **Image Size**: Scale image size proportionally, default is `100%`. +- **Image Format**: Convert image format if possible, default is `original format`. +- **Skip Compressed Images**: Whether to skip already compressed images, default is `true`. +- **Keep Original File**: Whether to keep the original file, default is `false`. + +### SVG + +![Compression Options](./images/svg-compress-options.png) + +- **Skip Compressed Images**: Whether to skip already compressed images, default is `true`. +- **Keep Original File**: Whether to keep the original file, default is `false`. + +Click the `svgo config` button to configure `svgo` compression options. Refer to the [svgo documentation](https://svgo.dev/) for more details. + +## View Compression Results + +![View Compression Results](./images/compress-result.png) + +After compression, a popup will display the compression results as shown above. + +### Undo Compression + +If you are not satisfied with the compression results, click the `Undo` button to restore the original image. + +### Error Range + +If the image size increases beyond the error range, it is considered an increase; otherwise, it is considered a successful compression. + +To save the compression status, the extension adds data to the image metadata, which may cause slight discrepancies. + +## Check Compression Status + +You can check if an image is compressed in the following ways: + +1. A ✔ icon is displayed at the bottom right of the image. +2. Displayed in the image details. +3. Displayed when hovering over the image. + +Some images cannot have metadata written, so their compression status cannot be determined. diff --git a/docs/features/convert-format.md b/docs/features/convert-format.md new file mode 100644 index 00000000..62277246 --- /dev/null +++ b/docs/features/convert-format.md @@ -0,0 +1,8 @@ +# Format Conversion + +Supported formats for conversion: `'png', 'jpg', 'jpeg', 'webp', 'gif', 'tiff', 'tif', 'avif', 'heif', 'svg'` + +![Format Conversion](./images/convert-format.png) + +- **Convert Format**: The image format to convert to. +- **Keep Original File**: Whether to keep the original file, default is `false`. diff --git a/docs/features/crop.md b/docs/features/crop.md new file mode 100644 index 00000000..0ae2ce41 --- /dev/null +++ b/docs/features/crop.md @@ -0,0 +1,5 @@ +# Image Cropping + +Image cropping uses `cropperjs` for cropping and saves the result as an image using `canvas`. + +![Image Cropping](./images/crop.png) diff --git a/docs/features/customize.md b/docs/features/customize.md new file mode 100644 index 00000000..cb4df339 --- /dev/null +++ b/docs/features/customize.md @@ -0,0 +1,21 @@ +# Custom Settings + +Click the settings button in the top right corner to customize settings. + +## Viewer Settings + +![Viewer Settings](./images/customize-viewer.png) + +- **Grouping**: Group images by directory/type. If both are off, all images are displayed in a flat view. +- **Layout**: Compact layout collapses empty directories to avoid deep nesting. +- **Sorting**: Sort images by name/size. +- **Image Background Color**: Set the background color of images. +- **Show Details on Hover**: Control whether to show image details when hovering over an image. + +## General Settings + +- Light/Dark Mode +- Custom Theme Color +- Built-in support for 4 languages + +![General Settings](./images/customize-general.png) diff --git a/docs/features/filter.md b/docs/features/filter.md new file mode 100644 index 00000000..8653af11 --- /dev/null +++ b/docs/features/filter.md @@ -0,0 +1,17 @@ +# Image Filtering + +There is a filter on the right side of the viewer to help you quickly find the images you want. + +## Filter Entry +![Entry](./images/filter-entry.png) + +## Filter Options + +![Filter Options](./images/filter-options.png) + +- **File Type**: Filter by image type +- **File Size**: Filter by image size +- **Git Staged Status**: Filter by Git staged status +- **Compression Status**: Filter by image compression status + +When filtering is enabled, the filter entry button will be highlighted. diff --git a/docs/features/images/compress-options.png b/docs/features/images/compress-options.png new file mode 100644 index 00000000..7523462c Binary files /dev/null and b/docs/features/images/compress-options.png differ diff --git a/docs/features/images/compress-result.png b/docs/features/images/compress-result.png new file mode 100644 index 00000000..a1ec0499 Binary files /dev/null and b/docs/features/images/compress-result.png differ diff --git a/docs/features/images/convert-format.png b/docs/features/images/convert-format.png new file mode 100644 index 00000000..bfbfd63e Binary files /dev/null and b/docs/features/images/convert-format.png differ diff --git a/docs/features/images/crop.png b/docs/features/images/crop.png new file mode 100644 index 00000000..dd57312e Binary files /dev/null and b/docs/features/images/crop.png differ diff --git a/docs/features/images/customize-general.png b/docs/features/images/customize-general.png new file mode 100644 index 00000000..699126d4 Binary files /dev/null and b/docs/features/images/customize-general.png differ diff --git a/docs/features/images/customize-viewer.png b/docs/features/images/customize-viewer.png new file mode 100644 index 00000000..4fdf8905 Binary files /dev/null and b/docs/features/images/customize-viewer.png differ diff --git a/docs/features/images/filter-entry.png b/docs/features/images/filter-entry.png new file mode 100644 index 00000000..5f0a491e Binary files /dev/null and b/docs/features/images/filter-entry.png differ diff --git a/docs/features/images/filter-options.png b/docs/features/images/filter-options.png new file mode 100644 index 00000000..b184a921 Binary files /dev/null and b/docs/features/images/filter-options.png differ diff --git a/docs/features/images/preview-hover.png b/docs/features/images/preview-hover.png new file mode 100644 index 00000000..25bcea35 Binary files /dev/null and b/docs/features/images/preview-hover.png differ diff --git a/docs/features/images/preview.png b/docs/features/images/preview.png new file mode 100644 index 00000000..e32b56a3 Binary files /dev/null and b/docs/features/images/preview.png differ diff --git a/docs/features/images/search.png b/docs/features/images/search.png new file mode 100644 index 00000000..777496c9 Binary files /dev/null and b/docs/features/images/search.png differ diff --git a/docs/features/images/svg-compress-options.png b/docs/features/images/svg-compress-options.png new file mode 100644 index 00000000..f10cd18f Binary files /dev/null and b/docs/features/images/svg-compress-options.png differ diff --git a/docs/features/preview.md b/docs/features/preview.md new file mode 100644 index 00000000..a2243123 --- /dev/null +++ b/docs/features/preview.md @@ -0,0 +1,9 @@ +# Large Image Preview + +If `image-manager.viewer.showDetailsOnHover` is `true`, hover over the image and click the preview button to view the large image. + +![Large Image Preview](./images/preview-hover.png) + +If `image-manager.viewer.showDetailsOnHover` is `false`, double-click the image or right-click and select details, then click the preview button. + +![Large Image Preview](./images/preview.png) diff --git a/docs/features/search.md b/docs/features/search.md new file mode 100644 index 00000000..9f7f8946 --- /dev/null +++ b/docs/features/search.md @@ -0,0 +1,12 @@ +# Image Search + +Image Manager provides a search function similar to VSCode, allowing you to search for all images in the current folder. + +![Image Search](./images/search.png) + +## Search Options + +- **Case Sensitive** +- **Match Whole Word** +- **Include Directory** +- **Exclude Directory** diff --git a/docs/guides/faq.md b/docs/guides/faq.md new file mode 100644 index 00000000..d67ae23c --- /dev/null +++ b/docs/guides/faq.md @@ -0,0 +1,39 @@ +# FAQ + +## Slow on First Launch? + +The first time you open the extension, it may be slow because it needs to download necessary dependencies. This process depends on your network environment. Please be patient. + +## Error: Dependency Installation Failed, Check Network + +If you are in mainland China and have a poor network environment, there are two solutions: + +1. Switch Mirror Source +2. Manually Install Dependencies + +### Switch Mirror Source + +Use the command palette, type `select mirror url`, and press Enter. +![Select](./images/select-mirror-1.png) + +Then choose a mirror source, restart VS Code, and try downloading the dependencies again. + +![Select](./images/select-mirror-2.png) + +### Manually Install Dependencies + +1. Open the command palette, type `Show Output Channel`, and select the Image Manager option. +2. Find the `Extension Root` in the output, you will need it later. +3. Download the dependencies from the URLs printed in the `Output Channel`. +4. Place the downloaded files in the `Extension Root` from step 2. +5. Restart VS Code. + +## Why Did the File Size Increase After Compression? + +- Adding "compressed" metadata during compression may cause small images to increase in size. +- You can adjust the compression error range by setting `image-manager.compression.errorRange`. + +## Too Many Images, Feels Laggy? + +- Configure `image-manager.appearance.reduceMotion: 'on'` to reduce animation effects. +- Open a specific directory by right-clicking the folder to reduce the number of rendered images. diff --git a/docs/guides/feedback.md b/docs/guides/feedback.md new file mode 100644 index 00000000..ce2096e8 --- /dev/null +++ b/docs/guides/feedback.md @@ -0,0 +1,3 @@ +# Feedback + +If you have any issues or suggestions, please submit them on [GitHub Issues](https://github.com/hemengke1997/vscode-image-manager/issues). diff --git a/docs/guides/get-started.md b/docs/guides/get-started.md new file mode 100644 index 00000000..225bd0cd --- /dev/null +++ b/docs/guides/get-started.md @@ -0,0 +1,74 @@ +# Get Started + +This guide will quickly introduce you to the key operations of Image Manager. + +## Open the Extension + +There are **3** ways to open the extension: + +### 1. Keyboard Shortcut + +- Windows: `Shift+Alt+J` +- macOS: `Cmd+Option+J` + +### 2. Context Menu + +Right-click in the Explorer and select `Image Manager` to open the extension (opens the current folder). + +![Context Menu](./images/contextmenu.png) + +### 3. Command + +Type `Image Manager` in the Command Palette to open the extension. + +![Command](./images/cmd.png) + +## Powerful Context Menu + +In Image Manager, most operations are performed by right-clicking on an image or directory, making it very convenient. + +### Right-click on an Image + +![Right-click Image](./images/contextmenu-image.png) + +### Right-click on a Directory + +![Right-click Directory](./images/contextmenu-dir.png) + +## Keyboard Shortcuts + +For higher efficiency, Image Manager also supports some keyboard shortcuts. + +Select an image or directory and press the shortcut key to perform the operation. + +### Rename + +- Windows: `F2` +- macOS: `⏎` + +### Delete + +- Windows: `Delete` +- macOS: `⌘ + ⌫` + +### Copy Image Name + +- Windows: `Ctrl + C` +- macOS: `⌘ + C` + +### View Image Details + +`Double-click` + +### Search Images + +- Windows: `Ctrl + F` +- macOS: `⌘ + F` + +## Multi-select + +To multi-select images, hold down the `Shift / ⇧` or `Ctrl / ⌘` key, just like in the system file manager. + +## Mouse Wheel + +In the viewer, hold down `Ctrl / ⌘` and use the mouse wheel to zoom in or out. diff --git a/docs/guides/images/alipay.jpeg b/docs/guides/images/alipay.jpeg new file mode 100644 index 00000000..f4401834 Binary files /dev/null and b/docs/guides/images/alipay.jpeg differ diff --git a/docs/guides/images/cmd.png b/docs/guides/images/cmd.png new file mode 100644 index 00000000..18c59e67 Binary files /dev/null and b/docs/guides/images/cmd.png differ diff --git a/docs/guides/images/contextmenu-dir.png b/docs/guides/images/contextmenu-dir.png new file mode 100644 index 00000000..ea719877 Binary files /dev/null and b/docs/guides/images/contextmenu-dir.png differ diff --git a/docs/guides/images/contextmenu-image.png b/docs/guides/images/contextmenu-image.png new file mode 100644 index 00000000..ac78ef12 Binary files /dev/null and b/docs/guides/images/contextmenu-image.png differ diff --git a/docs/guides/images/contextmenu.png b/docs/guides/images/contextmenu.png new file mode 100644 index 00000000..ed702f71 Binary files /dev/null and b/docs/guides/images/contextmenu.png differ diff --git a/docs/guides/images/select-mirror-1.png b/docs/guides/images/select-mirror-1.png new file mode 100644 index 00000000..56ab6035 Binary files /dev/null and b/docs/guides/images/select-mirror-1.png differ diff --git a/docs/guides/images/select-mirror-2.png b/docs/guides/images/select-mirror-2.png new file mode 100644 index 00000000..7700f9b8 Binary files /dev/null and b/docs/guides/images/select-mirror-2.png differ diff --git a/docs/guides/images/wechatpay.jpeg b/docs/guides/images/wechatpay.jpeg new file mode 100644 index 00000000..55c67909 Binary files /dev/null and b/docs/guides/images/wechatpay.jpeg differ diff --git a/docs/guides/introduction.md b/docs/guides/introduction.md new file mode 100644 index 00000000..ac5bc917 --- /dev/null +++ b/docs/guides/introduction.md @@ -0,0 +1,18 @@ +# Introduction + +VSCode Image Manager is a VSCode extension for viewing, compressing, cropping, converting formats, searching, filtering, and finding similar images. + +All image processing is done locally, ensuring privacy and security. Feel free to use it! + +## Features + +- **View**: Large image viewing with zoom, rotate, and other features +- **Compress**: Single image, multiple images, and folder compression with customizable quality +- **Crop**: Crop images with customizable dimensions +- **Format Conversion**: Convert image formats +- **Search**: Search images by name, size, and type +- **Filter Images**: Filter images by file size, file type, etc. +- **Find Similar Images**: Find similar images based on content +- **Theme Support**: Custom themes for personalization +- **Internationalization**: Supports Chinese, English, Japanese, and Traditional Chinese +- **File Operations**: Delete, rename files and directories diff --git a/docs/guides/support.md b/docs/guides/support.md new file mode 100644 index 00000000..71a07cf0 --- /dev/null +++ b/docs/guides/support.md @@ -0,0 +1,17 @@ +# Support Me + +If you like my project and want to support me, you can do so in the following ways: + +## Appreciation + +| WeChat | Alipay | +| ------------------------------------- | ---------------------------------- | +| | | + +## GitHub + +Feel free to [give a star](https://github.com/hemengke1997/vscode-image-manager) ⭐️ + +## VSCode Marketplace + +Please consider leaving a positive review on [Marketplace](https://marketplace.visualstudio.com/items?itemName=minko.image-manager&ssr=false#review-details). Your support is my greatest motivation for open source development. Thank you! diff --git a/docs/images/cmd.png b/docs/images/cmd.png new file mode 100644 index 00000000..18c59e67 Binary files /dev/null and b/docs/images/cmd.png differ diff --git a/docs/images/contextmenu.png b/docs/images/contextmenu.png new file mode 100644 index 00000000..ed702f71 Binary files /dev/null and b/docs/images/contextmenu.png differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..ddab8fda --- /dev/null +++ b/docs/index.md @@ -0,0 +1,35 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "VSCode Image Manager" + text: "Powerful yet easy-to-use VSCode image management extension" + actions: + - theme: brand + text: Get Started + link: /guides/get-started + - theme: alt + text: Download + link: https://marketplace.visualstudio.com/items?itemName=minko.image-manager + +features: + - title: Absolute Security + icon: 🔐 + details: Local image processing, no uploads to any server + - title: High Efficiency + icon: 🚀 + details: Unlimited batch image compression + - title: Powerful Features + icon: 💪 + details: Large image viewing, cropping, format conversion, search, find similar, filter images + - title: Simple and Easy to Use + icon: 🎨 + details: Simple interface, easy operation + - title: Theme Support + icon: 🌈 + details: Custom themes for personalization + - title: Internationalization + icon: 🌍 + details: Built-in support for Chinese, English, Japanese, and Traditional Chinese +--- diff --git a/docs/settings/vscode.md b/docs/settings/vscode.md new file mode 100644 index 00000000..1bdc6cbc --- /dev/null +++ b/docs/settings/vscode.md @@ -0,0 +1,34 @@ +# VSCode Extension Settings + +| Name | Type | Description | Default value | +| -------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | +| image-manager.file.root | `string[]` | Workspace root | Current workspace | +| image-manager.file.exclude | `string[]` | Scan images not in exclude (pattern syntax of micromatch) | `["**/node_modules/**","**/.git/**","**/dist/**","**/coverage/**","**/.next/**","**/.nuxt/**","**/.vercel/**","**/.idea/**"]` | +| image-manager.file.scan | `string[]` | Scan images with imageType | `["png","jpg","jpeg","webp","gif","tiff","tif","avif","heif","heic","apng","svg","bmp","ico"]` | +| image-manager.file.confirmDelete | `boolean` | Controls whether ask for confirmation when deleting a image | true | +| image-manager.file.revealFileInOsDeeply | `boolean` | Enter folder when it is revealed in OS | true | +| image-manager.appearance.theme | `dark \| light \| auto` | Theme | `auto` | +| image-manager.appearance.language | `en \| zh-CN \| zh-TW \| ja \| auto` | Language | `auto` | +| image-manager.appearance.primaryColor | `string` | Primary color | undefined | +| image-manager.viewer.warningSize | `number \| boolean` | Show warning dot if image size is larger than this value (KB) | 1024 | +| image-manager.viewer.imageWidth | `number` | Width of image (px) | 100 | +| image-manager.viewer.imageBackgroundColor | `string` | Image background color | `#1a1a1a` | +| image-manager.viewer.imageRendering | `auto \| crisp-edges \| pixelated` | Image rendering | `auto` | +| image-manager.viewer.showDetailsOnHover | `boolean` | Show image details on hover | true | +| image-manager.mirror.enabled | `boolean` | Use mirror for downloading dependencies | false | +| image-manager.mirror.url | `string` | Custom mirror url (No need to custom this in general) | undefined | +| image-manager.compression.errorRange | `number` | Error range (KB), exceeding this range is considered an increase in image size after compression | 2 | +| image-manager.compression.keepOriginal | `boolean` | Keep original image after compression | false | +| image-manager.compression.fileSuffix | `string` | Add suffix to compressed image | `.min` | +| image-manager.compression.skipCompressed | `boolean` | Skip the compressed images | true | +| image-manager.compression.quality | `number` | Compression quality | - | +| image-manager.compression.size | `number` | Image size (x scale factor) | 1 | +| image-manager.compression.format | `string` | Convert format after compression | '' | +| image-manager.compression.png.compressionLevel | `number` | Compression level of png | 9 | +| image-manager.compression.gif.colors | `number` | Image colors of gif | 256 | +| image-manager.compression.svg.compressedAttribute | `string \| null` | Add "compressed" attribute to svg after compression. Set to null to disable | `c` | +| image-manager.compression.svg.removeDataAttributes | `boolean` | Remove data-* attributes from svg. Except data-\[{compressedAttribute}\] | true | +| image-manager.conversion.format | `string` | Convert format | '' | +| image-manager.conversion.keepOriginal | `boolean` | Keep original image after format conversion | false | +| image-manager.conversion.icoSize | `number[]` | Size of ico | [16, 32] | +| image-manager.similarity.precision | `number` | Determining the precision of image similarity. The smaller the value, the stricter the judgment | 10 | diff --git a/docs/vscode-configuration.md b/docs/vscode-configuration.md deleted file mode 100644 index d817da11..00000000 --- a/docs/vscode-configuration.md +++ /dev/null @@ -1,32 +0,0 @@ -# Extension Configurations - -| Name | Type | Description | Default value | -| ---------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -| image-manager.file.root | `string[]` | Root folder to scan images | current workspace | -| image-manager.file.exclude | `string[]` | Scan images not in exclude | `['**/node_modules/**','**/.git/**',`
`'**/dist/**','**/coverage/**','**/.next/**',`
`'**/.nuxt/**','**/.vercel/**']` | -| image-manager.file.scan | `string[]` | Scan images with imageType | `['svg','png','jpeg','jpg',`
`'ico','gif','webp','bmp',`
`'tif','tiff','apng','avif']` | -| image-manager.file.confirmDelete | `boolean` | Controls whether ask for confirmation when deleting a image | true | -| image-manager.file.revealFileInOsDeeply | `boolean` | Enter folder when it is revealed in OS | true | -| image-manager.appearance.theme | `dark \| light \| auto` | Theme | `auto` | -| image-manager.appearance.language | `en \| zh-CN \| zh-TW \| ja \| auto` | Language | `auto` | -| image-manager.appearance.primaryColor | `string` | Primary color | undefined | -| image-manager.viewer.warningSize | `number \| boolean` | Show warning dot if image size is larger than this value (KB) | 1024 | -| image-manager.viewer.imageWidth | `number` | Width of image (px) | 100 | -| image-manager.viewer.imageBackgroundColor | `string` | Image background color | `#1a1a1a` | -| image-manager.viewer.imageRendering | `auto \| crisp-edges \| pixelated` | Image rendering | `auto` | -| image-manager.mirror.enabled | `boolean` | Use mirror for downloading dependencies | false | -| image-manager.mirror.url | `string` | Custom mirror url (No need to custom this in general) | undefined | -| image-manager.compression.errorRange | `number` | Error range (KB), exceeding this range is considered an increase in image size after compression | 2 | -| image-manager.compression.keepOriginal | `boolean` | Keep original image after compression | false | -| image-manager.compression.fileSuffix | `string` | Add suffix to compressed image | `.min` | -| image-manager.compression.skipCompressed | `boolean` | Skip the compressed images | true | -| image-manager.compression.quality | `number` | Compression quality | - | -| image-manager.compression.size | `number` | Image size (x scale factor) | 1 | -| image-manager.compression.format | `string` | Convert format after compression | '' | -| image-manager.compression.png.compressionLevel | `number` | Compression level of png | 9 | -| image-manager.compression.gif.colors | `number` | Image colors of gif | 256 | -| image-manager.compression.svg.\* | `svgo 配置` | Svgo config. Please refer to svgo offical docs | - | -| image-manager.conversion.format | `string` | Convert format | '' | -| image-manager.conversion.keepOriginal | `boolean` | Keep original image after format conversion | false | -| image-manager.conversion.icoSize | `number[]` | Size of ico | [16, 32] | -| image-manager.similarity.precision | `number` | Determining the precision of image similarity. The smaller the value, the stricter the judgment | 10 | diff --git a/docs/vscode-configuration.zh.md b/docs/vscode-configuration.zh.md deleted file mode 100644 index 4a18e2c5..00000000 --- a/docs/vscode-configuration.zh.md +++ /dev/null @@ -1,32 +0,0 @@ -# 插件配置项 - -| 配置项名称 | 数据类型 | 描述 | 默认值 | -| ---------------------------------------------- | ------------------------------------ | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| image-manager.file.root | `string[]` | 扫描图片的根目录 | 当前工作区 | -| image-manager.file.exclude | `string[]` | 排除目录 | `['**/node_modules/**','**/.git/**',`
`'**/dist/**','**/coverage/**','**/.next/**',`
`'**/.nuxt/**','**/.vercel/**']` | -| image-manager.file.scan | `string[]` | 扫描的图片类型 | `['svg','png','jpeg','jpg',`
`'ico','gif','webp','bmp',`
`'tif','tiff','apng','avif']` | -| image-manager.file.confirmDelete | `boolean` | 删除图片时是否询问 | true | -| image-manager.file.revealFileInOsDeeply | `boolean` | 在OS中显示文件夹时进入到文件夹中 | false | -| image-manager.appearance.theme | `dark \| light \| auto` | 主题 | `auto` | -| image-manager.appearance.language | `en \| zh-CN \| zh-TW \| ja \| auto` | 语言 | `auto` | -| image-manager.appearance.primaryColor | `string` | 主题色 | undefined | -| image-manager.viewer.warningSize | `number \| boolean` | 当图片体积大于此值时右上角展示警告点(KB) | 1024 | -| image-manager.viewer.imageWidth | `number` | 图片宽度(px) | 100 | -| image-manager.viewer.imageBackgroundColor | `string` | 图片背景色 | `#1a1a1a` | -| image-manager.viewer.imageRendering | `auto \| crisp-edges \| pixelated` | 图片渲染方式(可自行调整像素风) | `auto` | -| image-manager.mirror.enabled | `boolean` | 使用镜像下载依赖 | false | -| image-manager.mirror.url | `string` | 镜像地址(通常情况不需要自定义) | undefined | -| image-manager.compression.errorRange | `number` | 误差范围(KB),超出此误差视为图片压缩后增大 | 2 | -| image-manager.compression.keepOriginal | `boolean` | 压缩后保留原图 | false | -| image-manager.compression.fileSuffix | `string` | 压缩图片文件名添加后缀 | `.min` | -| image-manager.compression.skipCompressed | `boolean` | 跳过已压缩的图片 | true | -| image-manager.compression.quality | `number` | 压缩图片质量 | - | -| image-manager.compression.size | `number` | 图片尺寸(几倍图) | 1 | -| image-manager.compression.format | `string` | 压缩时转化图片的格式 | '' | -| image-manager.compression.png.compressionLevel | `number` | png图片压缩等级 | 9 | -| image-manager.compression.gif.colors | `number` | gif图片色彩 | 256 | -| image-manager.compression.svg.\* | `svgo 配置` | 压缩svg的配置,具体配置项功能请参考svgo官方文档 | - | -| image-manager.conversion.format | `string` | 转化图片格式 | '' | -| image-manager.conversion.keepOriginal | `boolean` | 转化图片格式后保留原图 | false | -| image-manager.conversion.icoSize | `number[]` | ico图标尺寸 | [16, 32] | -| image-manager.similarity.precision | `number` | 判断图片相似的精确度。值越小,判断越严格 | 10 | diff --git a/docs/zh/features/compress.md b/docs/zh/features/compress.md new file mode 100644 index 00000000..c0712545 --- /dev/null +++ b/docs/zh/features/compress.md @@ -0,0 +1,55 @@ +# 图片压缩 + +图片压缩支持 `'png', 'jpg', 'jpeg', 'webp', 'gif', 'tiff', 'tif', 'avif', 'heif', 'svg'` 格式。 + +其中 `svg` 压缩使用 [`svgo`](https://svgo.dev/) 压缩,其他格式使用 [`sharp`](https://sharp.pixelplumbing.com/) 压缩 + + +## 压缩选项 + +### 非svg + +![压缩选项](./images/compress-options.png) + +- **图片质量**:`0-100`,`0` 为最低质量,`100` 为最高质量。默认 `75`。 +- **图片尺寸**:按比例放大或缩小图片尺寸,默认 `100%`。 +- **图片格式**:可压缩时转化图片格式,默认 `原格式`。 +- **跳过已压缩图片**:是否跳过已压缩的图片,默认 `true`。 +- **保留原文件**:是否保留原文件,默认 `false`。 + +### svg + +![压缩选项](./images/svg-compress-options.png) + +- **跳过已压缩图片**:是否跳过已压缩的图片,默认 `true`。 +- **保留原文件**:是否保留原文件,默认 `false`。 + +点击 `svgo config` 按钮,可以配置 `svgo` 压缩选项,请参考 [svgo官方文档](https://svgo.dev/) + +## 查看压缩结果 + + + +![查看压缩结果](./images/compress-result.png) + +图片压缩后,会弹窗显示图片压缩结果,展示信息如上图所示。 + +### 撤销压缩 + +如果对压缩结果不满意,可以点击 `撤销` 按钮,恢复原图。 + +### 误差范围 + +如果图片体积增大超过误差范围,才会视为图片增大,否则都认为压缩成功。 + +为了保存图片是否已压缩的信息,扩展会在图片元信息中添加数据,所以可能会导致图片有轻微的误差。 + +## 查看压缩状态 + +有如下方式查看图片是否已压缩: + +1. 图片右下角显示 ✔ 图标 +2. 图片详情中展示 +3. hover图片时展示 + +因为部分图片无法写入元信息,所以判断不了是否已压缩 diff --git a/docs/zh/features/convert-format.md b/docs/zh/features/convert-format.md new file mode 100644 index 00000000..cedf0177 --- /dev/null +++ b/docs/zh/features/convert-format.md @@ -0,0 +1,8 @@ +# 格式转换 + +支持转换的格式有:`'png', 'jpg', 'jpeg', 'webp', 'gif', 'tiff', 'tif', 'avif', 'heif', 'svg'` + +![格式转换](./images/convert-format.png) + +- **转换格式**:可转换为的图片格式。 +- **保留原文件**:是否保留原文件,默认 `false`。 diff --git a/docs/zh/features/crop.md b/docs/zh/features/crop.md new file mode 100644 index 00000000..2fdaa28e --- /dev/null +++ b/docs/zh/features/crop.md @@ -0,0 +1,5 @@ +# 图片裁剪 + +图片裁剪使用了 `cropperjs` 裁剪,将结果使用 `canvas` 保存为图片。 + +![图片裁剪](./images/crop.png) diff --git a/docs/zh/features/customize.md b/docs/zh/features/customize.md new file mode 100644 index 00000000..a0c997f1 --- /dev/null +++ b/docs/zh/features/customize.md @@ -0,0 +1,22 @@ +# 自定义设置 + +可点击右上角设置按钮进行自定义设置 + + +## 查看器设置 + +![查看器设置](./images/customize-viewer.png) + +- **分组**:可按照目录/类型对图片进行分组展示,如果都关闭,则平铺展示所有图片 +- **布局**:紧凑布局会把无图片的目录收敛,避免嵌套过深 +- **排序**:可按照名称/大小对图片进行排序 +- **图片背景色**:可设置图片背景色 +- **悬停显示详情**:控制鼠标悬停图片上时,是否显示图片详情 + +## 通用设置 + +- 明亮/暗黑模式 +- 自定义主题色 +- 内置 4 种语言 + +![通用设置](./images/customize-general.png) diff --git a/docs/zh/features/filter.md b/docs/zh/features/filter.md new file mode 100644 index 00000000..eaf8186e --- /dev/null +++ b/docs/zh/features/filter.md @@ -0,0 +1,17 @@ +# 图片筛选 + +查看器右侧有一个筛选器,可以帮助你快速找到你想要的图片。 + +## 筛选入口 +![入口](./images/filter-entry.png) + +## 筛选选项 + +![筛选选项](./images/filter-options.png) + +- **文件类型**:根据图片类型筛选 +- **文件大小**:根据图片体积大小筛选 +- **Git 暂存状态**:根据 Git 暂存状态筛选 +- **压缩状态**:根据图片压缩状态筛选 + +若启用了筛选,筛选入口按钮会高亮显示。 diff --git a/docs/zh/features/images/compress-options.png b/docs/zh/features/images/compress-options.png new file mode 100644 index 00000000..7745a6af Binary files /dev/null and b/docs/zh/features/images/compress-options.png differ diff --git a/docs/zh/features/images/compress-result.png b/docs/zh/features/images/compress-result.png new file mode 100644 index 00000000..d3e59d9a Binary files /dev/null and b/docs/zh/features/images/compress-result.png differ diff --git a/docs/zh/features/images/convert-format.png b/docs/zh/features/images/convert-format.png new file mode 100644 index 00000000..c1848fc3 Binary files /dev/null and b/docs/zh/features/images/convert-format.png differ diff --git a/docs/zh/features/images/crop.png b/docs/zh/features/images/crop.png new file mode 100644 index 00000000..199a8e1c Binary files /dev/null and b/docs/zh/features/images/crop.png differ diff --git a/docs/zh/features/images/customize-general.png b/docs/zh/features/images/customize-general.png new file mode 100644 index 00000000..a4df7ca3 Binary files /dev/null and b/docs/zh/features/images/customize-general.png differ diff --git a/docs/zh/features/images/customize-viewer.png b/docs/zh/features/images/customize-viewer.png new file mode 100644 index 00000000..e83470d9 Binary files /dev/null and b/docs/zh/features/images/customize-viewer.png differ diff --git a/docs/zh/features/images/filter-entry.png b/docs/zh/features/images/filter-entry.png new file mode 100644 index 00000000..d7264887 Binary files /dev/null and b/docs/zh/features/images/filter-entry.png differ diff --git a/docs/zh/features/images/filter-options.png b/docs/zh/features/images/filter-options.png new file mode 100644 index 00000000..4d971015 Binary files /dev/null and b/docs/zh/features/images/filter-options.png differ diff --git a/docs/zh/features/images/preview-hover.png b/docs/zh/features/images/preview-hover.png new file mode 100644 index 00000000..effad716 Binary files /dev/null and b/docs/zh/features/images/preview-hover.png differ diff --git a/docs/zh/features/images/preview.png b/docs/zh/features/images/preview.png new file mode 100644 index 00000000..61c86885 Binary files /dev/null and b/docs/zh/features/images/preview.png differ diff --git a/docs/zh/features/images/search.png b/docs/zh/features/images/search.png new file mode 100644 index 00000000..bf07b851 Binary files /dev/null and b/docs/zh/features/images/search.png differ diff --git a/docs/zh/features/images/svg-compress-options.png b/docs/zh/features/images/svg-compress-options.png new file mode 100644 index 00000000..856f9e4e Binary files /dev/null and b/docs/zh/features/images/svg-compress-options.png differ diff --git a/docs/zh/features/preview.md b/docs/zh/features/preview.md new file mode 100644 index 00000000..0fb3b5dd --- /dev/null +++ b/docs/zh/features/preview.md @@ -0,0 +1,10 @@ +# 大图预览 + + +如果 `image-manager.viewer.showDetailsOnHover` 为 `true`,则鼠标悬停在图片上即可点击预览按钮查看大图。 + +![大图浏览](./images/preview-hover.png) + +如果 `image-manager.viewer.showDetailsOnHover` 为 `false`,双击图片或右键图片选择详情,然后点击预览按钮即可。 + +![大图浏览](./images/preview.png) diff --git a/docs/zh/features/search.md b/docs/zh/features/search.md new file mode 100644 index 00000000..0de8c25a --- /dev/null +++ b/docs/zh/features/search.md @@ -0,0 +1,13 @@ +# 图片搜索 + +Image Manager 提供了类似 VSCode 搜索的功能,可以搜索当前文件夹下的所有图片 + +![图片搜索](./images/search.png) + + +## 搜索选项 + +- **区分大小写** +- **全字匹配** +- **包含目录** +- **排除目录** diff --git a/docs/zh/guides/faq.md b/docs/zh/guides/faq.md new file mode 100644 index 00000000..26e602b6 --- /dev/null +++ b/docs/zh/guides/faq.md @@ -0,0 +1,39 @@ +# 常见问题 + +## 第一次打开插件慢? + +由于首次打开插件时需要下载必要的依赖,这个过程可能会比较慢,具体取决于您的网络环境。请耐心等待。 + +## 报错:依赖安装失败,请检查网络 + +如果您在中国大陆且网络环境不佳(你懂的),有两种解决方案: + +1. 切换镜像源 +2. 手动安装依赖 + +### 切换镜像源 + +使用命令面板,输入 `select mirror url` 并回车。 +![选择](./images/select-mirror-1.png) + +然后选择一个镜像源,重启 VS Code 并尝试重新下载依赖。 + +![选择](./images/select-mirror-2.png) + +### 手动安装依赖 + +1. 打开命令面板,输入 `Show Output Channel`,选择 Image Manager 对应的选项。 +2. 在输出中找到 `插件根目录 (Extension Root)`,之后需要用到。 +3. 下载 `Output Channel` 中打印的依赖地址。 +4. 将下载的文件放在步骤 2 的 `插件根目录`。 +5. 重启 VS Code 即可。 + +## 为什么压缩后文件反而变大了 + +- 由于压缩时添加了「是否已压缩」的元信息,可能导致小体积图片压缩后变大。 +- 您可以设置 `image-manager.compression.errorRange` 来调整压缩误差范围。 + +## 图片太多,感觉卡顿? + +- 可以配置 `image-manager.appearance.reduceMotion: 'on'` 来减少动画效果。 +- 可以使用右键文件夹的方式打开指定的目录,从而减少渲染的图片数量。 diff --git a/docs/zh/guides/feedback.md b/docs/zh/guides/feedback.md new file mode 100644 index 00000000..401fb470 --- /dev/null +++ b/docs/zh/guides/feedback.md @@ -0,0 +1,3 @@ +# 问题反馈 + +如果有任何问题或建议,请在 [GitHub Issues](https://github.com/hemengke1997/vscode-image-manager/issues) 中提交。 diff --git a/docs/zh/guides/get-started.md b/docs/zh/guides/get-started.md new file mode 100644 index 00000000..f95d66cd --- /dev/null +++ b/docs/zh/guides/get-started.md @@ -0,0 +1,75 @@ +# 快速开始 + +以下带你快速了解 Image Manager 的重要操作。 + +## 打开扩展 + +有 **3** 种方式打开扩展: + +### 1. 快捷键 + +- Windows: `Shift+Alt+J` +- macOS: `Cmd+Option+J` + +### 2. 右键菜单 + +在资源管理器中右键,选择 `Image Manager` 打开扩展(打开当前文件夹)。 + +![右键菜单](./images/contextmenu.png) + +### 3. 命令 + +在命令面板中输入 `Image Manager` 打开扩展。 + +![命令](./images/cmd.png) + +## 强大的右键菜单 + +Image Manager中,大部分操作都是通过右键图片或目录完成,非常方便。 + +### 右键图片 + +![右键图片](./images/contextmenu-image.png) + +### 右键目录 + +![右键目录](./images/contextmenu-dir.png) + + +## 快捷键 + +为了更高的效率,Image Manager也支持部分快捷键操作。 + +选中图片或目录后,按下快捷键即可完成操作。 + +### 重命名 + +- Windows: `F2` +- macOS: `⏎` + +### 删除 + +- Windows: `Delete` +- macOS: `⌘ + ⌫` + +### 复制图片名 + +- Windows: `Ctrl + C` +- macOS: `⌘ + C` + +### 查看图片详情 + +`左键双击` + +### 搜索图片 + +- Windows: `Ctrl + F` +- macOS: `⌘ + F` + +## 多选 + +与系统多选文件方式一样,按住 `Shift / ⇧` 或 `Ctrl / ⌘` 键多选图片 + +## 鼠标滚轮 + +在查看器中,按住 `Ctrl / ⌘` + 鼠标滚轮可以放大或缩小图片 diff --git a/docs/zh/guides/images/alipay.jpeg b/docs/zh/guides/images/alipay.jpeg new file mode 100644 index 00000000..f4401834 Binary files /dev/null and b/docs/zh/guides/images/alipay.jpeg differ diff --git a/docs/zh/guides/images/cmd.png b/docs/zh/guides/images/cmd.png new file mode 100644 index 00000000..18c59e67 Binary files /dev/null and b/docs/zh/guides/images/cmd.png differ diff --git a/docs/zh/guides/images/contextmenu-dir.png b/docs/zh/guides/images/contextmenu-dir.png new file mode 100644 index 00000000..9f48864c Binary files /dev/null and b/docs/zh/guides/images/contextmenu-dir.png differ diff --git a/docs/zh/guides/images/contextmenu-image.png b/docs/zh/guides/images/contextmenu-image.png new file mode 100644 index 00000000..f681f5d5 Binary files /dev/null and b/docs/zh/guides/images/contextmenu-image.png differ diff --git a/docs/zh/guides/images/contextmenu.png b/docs/zh/guides/images/contextmenu.png new file mode 100644 index 00000000..ed702f71 Binary files /dev/null and b/docs/zh/guides/images/contextmenu.png differ diff --git a/docs/zh/guides/images/select-mirror-1.png b/docs/zh/guides/images/select-mirror-1.png new file mode 100644 index 00000000..56ab6035 Binary files /dev/null and b/docs/zh/guides/images/select-mirror-1.png differ diff --git a/docs/zh/guides/images/select-mirror-2.png b/docs/zh/guides/images/select-mirror-2.png new file mode 100644 index 00000000..96e46e4d Binary files /dev/null and b/docs/zh/guides/images/select-mirror-2.png differ diff --git a/docs/zh/guides/images/wechatpay.jpeg b/docs/zh/guides/images/wechatpay.jpeg new file mode 100644 index 00000000..55c67909 Binary files /dev/null and b/docs/zh/guides/images/wechatpay.jpeg differ diff --git a/docs/zh/guides/introduction.md b/docs/zh/guides/introduction.md new file mode 100644 index 00000000..2fd2ec0b --- /dev/null +++ b/docs/zh/guides/introduction.md @@ -0,0 +1,19 @@ +# 介绍 + +VSCode Image Manager 是一个用于查看、压缩、裁剪、转换格式、搜索、过滤和查找相似图片的 VSCode 插件。 + + +此插件对图片的处理全部在本地进行,不会上传到任何服务器,确保了隐私和安全。请放心使用! + +## 功能 + +- **查看**:大图浏览,支持放大、缩小、旋转等功能 +- **压缩**:单图、多图、文件夹压缩,支持自定义压缩质量 +- **裁剪**:裁剪图片,支持自定义裁剪尺寸 +- **格式转换**:图片格式转换 +- **搜索**:搜索图片,支持按文件名、文件大小、文件类型搜索 +- **图片过滤**:按文件大小、文件类型等过滤图片 +- **查找相似图片**:查找相似图片(基于图片内容) +- **主题支持**:自定义主题,满足个性化需求 +- **国际化**:中文、英文、日文、繁中 +- **文件操作**:删除、重命名文件和目录 diff --git a/docs/zh/guides/support.md b/docs/zh/guides/support.md new file mode 100644 index 00000000..2d017832 --- /dev/null +++ b/docs/zh/guides/support.md @@ -0,0 +1,19 @@ +# 支持作者 + +如果您喜欢我的项目并且想要支持我,您可以通过以下方式: + +## 赞赏 + +| 微信 | 支付宝 | +| ------------------------------------- | ---------------------------------- | +| | | + + +## GitHub + +欢迎[点个 star](https://github.com/hemengke1997/vscode-image-manager) ⭐️ + +## VSCode市场 + +欢迎在 [Marketplace](https://marketplace.visualstudio.com/items?itemName=minko.image-manager&ssr=false#review-details) 中给予好评,非常感谢!您的支持是我开源的最大动力 + diff --git a/docs/zh/index.md b/docs/zh/index.md new file mode 100644 index 00000000..f7575d44 --- /dev/null +++ b/docs/zh/index.md @@ -0,0 +1,36 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "VSCode Image Manager" + text: "强大易用的VSCode图片管理插件" + actions: + - theme: brand + text: 开始使用 + link: /zh/guides/get-started + - theme: alt + text: 下载 + link: https://marketplace.visualstudio.com/items?itemName=minko.image-manager + +features: + - title: 绝对安全 + icon: 🔐 + details: 本地处理图片,不会上传到任何服务器 + - title: 效率至上 + icon: 🚀 + details: 不限量批量压缩图片 + - title: 功能强大 + icon: 💪 + details: 大图浏览、裁剪、格式转换、搜索、查找相似、筛选图片 + - title: 简洁易用 + icon: 🎨 + details: 界面简洁,操作简单 + - title: 主题支持 + icon: 🌈 + details: 自定义主题,满足个性化需求 + - title: 国际化 + icon: 🌍 + details: 内置中文、英文、日文、繁中支持 +--- + diff --git a/docs/zh/settings/vscode.md b/docs/zh/settings/vscode.md new file mode 100644 index 00000000..3ce465e6 --- /dev/null +++ b/docs/zh/settings/vscode.md @@ -0,0 +1,35 @@ +# VSCode 设置项 + + +| 配置项名称 | 数据类型 | 描述 | 默认值 | +| -------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | +| image-manager.file.root | `string[]` | 扫描图片的根目录 | 当前工作区 | +| image-manager.file.exclude | `string[]` | 排除目录 | `["**/node_modules/**","**/.git/**","**/dist/**","**/coverage/**","**/.next/**","**/.nuxt/**","**/.vercel/**","**/.idea/**"]` | +| image-manager.file.scan | `string[]` | 扫描的图片类型 | `["png","jpg","jpeg","webp","gif","tiff","tif","avif","heif","heic","apng","svg","bmp","ico"]` | +| image-manager.file.confirmDelete | `boolean` | 删除图片时是否询问 | true | +| image-manager.file.revealFileInOsDeeply | `boolean` | 在OS中显示文件夹时进入到文件夹中 | false | +| image-manager.appearance.theme | `dark \| light \| auto` | 主题 | `auto` | +| image-manager.appearance.language | `en \| zh-CN \| zh-TW \| ja \| auto` | 语言 | `auto` | +| image-manager.appearance.primaryColor | `string` | 主题色 | undefined | +| image-manager.viewer.warningSize | `number \| boolean` | 当图片体积大于此值时右上角展示警告点(KB) | 1024 | +| image-manager.viewer.imageWidth | `number` | 图片宽度(px) | 100 | +| image-manager.viewer.imageBackgroundColor | `string` | 图片背景色 | `#1a1a1a` | +| image-manager.viewer.imageRendering | `auto \| crisp-edges \| pixelated` | 图片渲染方式(可自行调整像素风) | `auto` | +| image-manager.viewer.showDetailsOnHover | `boolean` | 鼠标悬停时显示图片详情 | true | +| image-manager.mirror.enabled | `boolean` | 使用镜像下载依赖 | false | +| image-manager.mirror.url | `string` | 镜像地址(通常情况不需要自定义) | undefined | +| image-manager.compression.errorRange | `number` | 误差范围(KB),超出此误差视为图片压缩后增大 | 2 | +| image-manager.compression.keepOriginal | `boolean` | 压缩后保留原图 | false | +| image-manager.compression.fileSuffix | `string` | 压缩图片文件名添加后缀 | `.min` | +| image-manager.compression.skipCompressed | `boolean` | 跳过已压缩的图片 | true | +| image-manager.compression.quality | `number` | 压缩图片质量 | - | +| image-manager.compression.size | `number` | 图片尺寸(几倍图) | 1 | +| image-manager.compression.format | `string` | 压缩时转化图片的格式 | '' | +| image-manager.compression.png.compressionLevel | `number` | png图片压缩等级 | 9 | +| image-manager.compression.gif.colors | `number` | gif图片色彩 | 256 | +| image-manager.compression.svg.compressedAttribute | `string \| null` | svg压缩后添加「已压缩」属性。如果设置为 null,则禁用功能 | `c` | +| image-manager.compression.svg.removeDataAttributes | `boolean` | 删除svg中的 data-* 属性。除了 data-\[{compressedAttribute}\] | true | +| image-manager.conversion.format | `string` | 转化图片格式 | '' | +| image-manager.conversion.keepOriginal | `boolean` | 转化图片格式后保留原图 | false | +| image-manager.conversion.icoSize | `number[]` | ico图标尺寸 | [16, 32] | +| image-manager.similarity.precision | `number` | 判断图片相似的精确度。值越小,判断越严格 | 10 | diff --git a/locales/en.json5 b/locales/en.json5 index c8787270..8a03d7ff 100644 --- a/locales/en.json5 +++ b/locales/en.json5 @@ -95,6 +95,9 @@ reset_settings_success: 'Reset successful', reset_settings_fail: 'Reset failed', cancel_operation_tip: 'Operation canceled', + registry_mirror: 'Registry Mirror', + binary_mirror: 'Binary File Mirror', + cdn_mirror: 'CDN Binary File Mirror', }, core: { compress_fail: 'Compress Fail', diff --git a/locales/ja.json5 b/locales/ja.json5 index 284dfc4a..6353d547 100644 --- a/locales/ja.json5 +++ b/locales/ja.json5 @@ -96,6 +96,9 @@ reset_settings_success: 'リセット成功', reset_settings_fail: 'リセット失敗', cancel_operation_tip: '操作がキャンセルされました', + registry_mirror: 'レジストリサイトミラー', + binary_mirror: 'バイナリファイルミラー', + cdn_mirror: 'CDNバイナリファイルミラー', }, core: { compress_fail: '圧縮に失敗しました', diff --git a/locales/zh-CN.json5 b/locales/zh-CN.json5 index 3a57ea65..f4db7e9e 100644 --- a/locales/zh-CN.json5 +++ b/locales/zh-CN.json5 @@ -97,6 +97,9 @@ reset_settings_success: '重置成功', reset_settings_fail: '重置失败', cancel_operation_tip: '取消操作', + registry_mirror: 'Registry 站点镜像', + binary_mirror: '二进制文件镜像', + cdn_mirror: 'CDN 二进制文件镜像', }, // 核心代码 core: { diff --git a/locales/zh-TW.json5 b/locales/zh-TW.json5 index 17cdad7f..b3f95120 100644 --- a/locales/zh-TW.json5 +++ b/locales/zh-TW.json5 @@ -97,6 +97,9 @@ reset_settings_success: '重置成功', reset_settings_fail: '重置失敗', cancel_operation_tip: '取消操作', + registry_mirror: 'Registry 站點鏡像', + binary_mirror: '二進制文件鏡像', + cdn_mirror: 'CDN 二進制文件鏡像', }, // 核心代碼 core: { diff --git a/package-lock.json b/package-lock.json index 353620f5..764e0417 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "image-manager", - "version": "2.3.3", + "version": "2.3.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "image-manager", - "version": "2.3.3", + "version": "2.3.4", "hasInstallScript": true, "license": "MIT", "devDependencies": { @@ -25,7 +25,7 @@ "@types/markdown-it": "^14.1.2", "@types/micromatch": "^4.0.9", "@types/minimist": "^1.2.5", - "@types/node": "^22.8.5", + "@types/node": "^22.9.0", "@types/pump": "1.1.3", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", @@ -39,7 +39,7 @@ "ahooks": "^3.8.1", "ahooks-x": "^1.3.4", "antd": "^5.21.6", - "bumpp": "^9.8.0", + "bumpp": "^9.8.1", "consola": "^3.2.3", "context-state": "^3.1.2", "conventional-changelog-cli": "^5.0.0", @@ -50,7 +50,7 @@ "delay": "^6.0.0", "destr": "^2.0.3", "escape-string-regexp": "^5.0.0", - "eslint": "^9.13.0", + "eslint": "^9.14.0", "eventemitter3": "^5.0.1", "execa": "8.0.1", "exif-reader": "^2.0.1", @@ -118,6 +118,7 @@ "vite-plugin-html": "^3.2.2", "vite-plugin-i18n-ally": "^5.2.2", "vite-plugin-markdown": "^2.2.0", + "vitepress": "^1.5.0", "vitest": "^2.1.4" }, "engines": { @@ -129,6 +130,241 @@ "@swc/core": "1.7.4" } }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz", + "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-shared": "1.17.6" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia/node_modules/@algolia/autocomplete-shared": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz", + "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==", + "dev": true, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "dev": true, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.12.0.tgz", + "integrity": "sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.12.0.tgz", + "integrity": "sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.12.0.tgz", + "integrity": "sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q==", + "dev": true, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.12.0.tgz", + "integrity": "sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.12.0.tgz", + "integrity": "sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.12.0.tgz", + "integrity": "sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.12.0.tgz", + "integrity": "sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.12.0.tgz", + "integrity": "sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.12.0.tgz", + "integrity": "sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.12.0.tgz", + "integrity": "sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.12.0.tgz", + "integrity": "sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.12.0.tgz", + "integrity": "sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.12.0.tgz", + "integrity": "sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw==", + "dev": true, + "dependencies": { + "@algolia/client-common": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "dev": true, @@ -2589,6 +2825,54 @@ "node": ">=14" } }, + "node_modules/@docsearch/css": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.3.tgz", + "integrity": "sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA==", + "dev": true + }, + "node_modules/@docsearch/js": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.3.tgz", + "integrity": "sha512-2mBFomaN6VijyQQGwieERDu9GeE0hlv9TQRZBTOYsPQW7/vqtd4hnHEkbBbaBRiS4PYcy+UhikbMuDExJs63UA==", + "dev": true, + "dependencies": { + "@docsearch/react": "3.6.3", + "preact": "^10.0.0" + } + }, + "node_modules/@docsearch/react": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.3.tgz", + "integrity": "sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.17.6", + "@docsearch/css": "3.6.3", + "algoliasearch": "^5.11.0" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, "node_modules/@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", @@ -2999,9 +3283,10 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, - "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -3065,33 +3350,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "10.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "dev": true, @@ -3109,9 +3367,9 @@ "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", - "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3137,25 +3395,40 @@ } }, "node_modules/@humanfs/core": { - "version": "0.19.0", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.5", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.0", + "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "dev": true, @@ -3169,9 +3442,10 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz", + "integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -3188,6 +3462,21 @@ "node": ">=10.13.0" } }, + "node_modules/@iconify-json/simple-icons": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.11.tgz", + "integrity": "sha512-AHCGDtBRqP+JzAbBzgO8uN/08CXxEmuaC6lQQZ3b5burKhRU12AJnJczwbUw2K5Mb/U85EpSUNhYMG3F28b8NA==", + "dev": true, + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -3986,6 +4275,66 @@ "win32" ] }, + "node_modules/@shikijs/core": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.2.tgz", + "integrity": "sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==", + "dev": true, + "dependencies": { + "@shikijs/engine-javascript": "1.22.2", + "@shikijs/engine-oniguruma": "1.22.2", + "@shikijs/types": "1.22.2", + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.3" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz", + "integrity": "sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.22.2", + "@shikijs/vscode-textmate": "^9.3.0", + "oniguruma-to-js": "0.4.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz", + "integrity": "sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.22.2", + "@shikijs/vscode-textmate": "^9.3.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.2.tgz", + "integrity": "sha512-8f78OiBa6pZDoZ53lYTmuvpFPlWtevn23bzG+azpPVvZg7ITax57o/K3TC91eYL3OMJOO0onPbgnQyZjRos8XQ==", + "dev": true, + "dependencies": { + "shiki": "1.22.2" + } + }, + "node_modules/@shikijs/types": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.2.tgz", + "integrity": "sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==", + "dev": true, + "dependencies": { + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", + "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", + "dev": true + }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", "dev": true, @@ -4359,6 +4708,15 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "dev": true, @@ -4427,9 +4785,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.8.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.5.tgz", - "integrity": "sha512-5iYk6AMPtsMbkZqCO1UGF9W5L38twq11S2pYWkybGHH2ogPUvXWNlQqJBzuEZWKj/WRH+QTeiv6ySWqJtvIEgA==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "dev": true, "dependencies": { "undici-types": "~6.19.8" @@ -4526,6 +4884,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", @@ -4732,6 +5096,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vitejs/plugin-legacy": { "version": "5.4.1", "dev": true, @@ -4778,6 +5148,19 @@ "vite": "^4.2.0 || ^5.0.0" } }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz", + "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, "node_modules/@vitest/expect": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.4.tgz", @@ -5016,99 +5399,412 @@ "node": ">=0.8.0" } }, - "node_modules/@vscode/vsce/node_modules/glob": { - "version": "11.0.0", + "node_modules/@vscode/vsce/node_modules/glob": { + "version": "11.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/vsce/node_modules/jackspeak": { + "version": "4.0.1", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@vscode/vsce/node_modules/lru-cache": { + "version": "11.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@vscode/vsce/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vscode/vsce/node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@vscode/vsce/node_modules/path-scurry": { + "version": "2.0.0", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz", + "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.12", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz", + "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.5.12", + "@vue/shared": "3.5.12" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz", + "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.12", + "@vue/compiler-dom": "3.5.12", + "@vue/compiler-ssr": "3.5.12", + "@vue/shared": "3.5.12", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.47", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz", + "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.5.12", + "@vue/shared": "3.5.12" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.2.tgz", + "integrity": "sha512-NCT0ujqlwAhoFvCsAG7G5qS8w/A/dhvFSt2BhmNxyqgpYDrf9CG1zYyWLQkE3dsZ+5lCT6ULUic2VKNaE07Vzg==", + "dev": true, + "dependencies": { + "@vue/devtools-kit": "^7.6.2" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.2.tgz", + "integrity": "sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==", + "dev": true, + "dependencies": { + "@vue/devtools-shared": "^7.6.2", + "birpc": "^0.2.19", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.2.tgz", + "integrity": "sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==", + "dev": true, + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.12.tgz", + "integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==", + "dev": true, + "dependencies": { + "@vue/shared": "3.5.12" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.12.tgz", + "integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.5.12", + "@vue/shared": "3.5.12" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz", + "integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.5.12", + "@vue/runtime-core": "3.5.12", + "@vue/shared": "3.5.12", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.12.tgz", + "integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==", + "dev": true, + "dependencies": { + "@vue/compiler-ssr": "3.5.12", + "@vue/shared": "3.5.12" + }, + "peerDependencies": { + "vue": "3.5.12" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz", + "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==", + "dev": true + }, + "node_modules/@vueuse/core": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.2.0.tgz", + "integrity": "sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA==", + "dev": true, + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "11.2.0", + "@vueuse/shared": "11.2.0", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.2.0.tgz", + "integrity": "sha512-zGXz3dsxNHKwiD9jPMvR3DAxQEOV6VWIEYTGVSB9PNpk4pTWR+pXrHz9gvXWcP2sTk3W2oqqS6KwWDdntUvNVA==", + "dev": true, + "dependencies": { + "@vueuse/core": "11.2.0", + "@vueuse/shared": "11.2.0", + "vue-demi": ">=0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, + "hasInstallScript": true, "bin": { - "glob": "dist/esm/bin.mjs" + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" }, "engines": { - "node": "20 || >=22" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } } }, - "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": { - "version": "10.0.1", + "node_modules/@vueuse/metadata": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.2.0.tgz", + "integrity": "sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ==", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@vscode/vsce/node_modules/jackspeak": { - "version": "4.0.1", + "node_modules/@vueuse/shared": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.2.0.tgz", + "integrity": "sha512-VxFjie0EanOudYSgMErxXfq6fo8vhr5ICI+BuE3I9FnX7ePllEsVrRQ7O6Q1TLgApeLuPKcHQxAXpP+KnlrJsg==", "dev": true, - "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" + "vue-demi": ">=0.14.10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/@vscode/vsce/node_modules/lru-cache": { - "version": "11.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@vscode/vsce/node_modules/mime": { - "version": "1.6.0", + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@vscode/vsce/node_modules/minipass": { - "version": "7.1.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@vscode/vsce/node_modules/path-scurry": { - "version": "2.0.0", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" }, "engines": { - "node": "20 || >=22" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } } }, "node_modules/@yarnpkg/lockfile": { @@ -5117,9 +5813,10 @@ "license": "BSD-2-Clause" }, "node_modules/acorn": { - "version": "8.12.0", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5220,6 +5917,30 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/algoliasearch": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.12.0.tgz", + "integrity": "sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg==", + "dev": true, + "dependencies": { + "@algolia/client-abtesting": "5.12.0", + "@algolia/client-analytics": "5.12.0", + "@algolia/client-common": "5.12.0", + "@algolia/client-insights": "5.12.0", + "@algolia/client-personalization": "5.12.0", + "@algolia/client-query-suggestions": "5.12.0", + "@algolia/client-search": "5.12.0", + "@algolia/ingestion": "1.12.0", + "@algolia/monitoring": "1.12.0", + "@algolia/recommend": "5.12.0", + "@algolia/requester-browser-xhr": "5.12.0", + "@algolia/requester-fetch": "5.12.0", + "@algolia/requester-node-http": "5.12.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ansi-escapes": { "version": "7.0.0", "dev": true, @@ -5773,6 +6494,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/birpc": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz", + "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/bl": { "version": "4.1.0", "dev": true, @@ -5913,9 +6643,9 @@ } }, "node_modules/bumpp": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/bumpp/-/bumpp-9.8.0.tgz", - "integrity": "sha512-RKHjvOpN6RGhh7LNXGQCRRTPJ99PvVJRcX7EvKKpgj+3nKV8DWDM+8O1TMK0UvcGWhE74PRrQpISqFTcq8wPSg==", + "version": "9.8.1", + "resolved": "https://registry.npmjs.org/bumpp/-/bumpp-9.8.1.tgz", + "integrity": "sha512-25W55DZI/rq6FboM0Q5y8eHbUk9eNn9oZ4bg/I5kiWn8/rdZCw6iqML076akQiUOQGhrm6QDvSSn4PgQ48bS4A==", "dev": true, "dependencies": { "@jsdevtools/ez-spawn": "^3.0.4", @@ -6063,6 +6793,16 @@ } ] }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chai": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", @@ -6100,6 +6840,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", @@ -6413,6 +7163,16 @@ "node": ">= 0.8" } }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "6.2.1", "dev": true, @@ -6769,6 +7529,21 @@ "dev": true, "license": "MIT" }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/copy-to-clipboard": { "version": "3.3.3", "dev": true, @@ -7228,6 +8003,15 @@ "node": ">=0.4.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/destr": { "version": "2.0.3", "dev": true, @@ -7241,6 +8025,19 @@ "node": ">=8" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "dev": true, @@ -8027,21 +8824,21 @@ } }, "node_modules/eslint": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", - "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", + "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.18.0", "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.13.0", + "@eslint/js": "9.14.0", "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", + "@humanwhocodes/retry": "^0.4.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -8049,9 +8846,9 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -8785,9 +9582,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -8872,9 +9669,10 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.1.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -8994,14 +9792,14 @@ } }, "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9011,9 +9809,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9331,6 +10129,15 @@ "dev": true, "license": "ISC" }, + "node_modules/focus-trap": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz", + "integrity": "sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==", + "dev": true, + "dependencies": { + "tabbable": "^6.2.0" + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -9951,6 +10758,48 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", + "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/he": { "version": "1.2.0", "dev": true, @@ -9964,6 +10813,12 @@ "dev": true, "license": "MIT" }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true + }, "node_modules/hosted-git-info": { "version": "4.1.0", "dev": true, @@ -10040,6 +10895,16 @@ "void-elements": "3.1.0" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/htmlparser2": { "version": "8.0.2", "dev": true, @@ -10783,6 +11648,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "dev": true, @@ -11762,6 +12639,12 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true + }, "node_modules/markdown-it": { "version": "14.1.0", "dev": true, @@ -11795,6 +12678,36 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/mdast-util-to-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", @@ -11833,23 +12746,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-stream": { + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", "dev": true, "funding": [ { @@ -11862,10 +12831,43 @@ } ], "dependencies": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.8", "dev": true, @@ -11980,6 +12982,12 @@ "node": ">=8" } }, + "node_modules/minisearch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz", + "integrity": "sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==", + "dev": true + }, "node_modules/minizlib": { "version": "2.1.2", "dev": true, @@ -12008,6 +13016,12 @@ "dev": true, "license": "ISC" }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, "node_modules/mkdirp": { "version": "1.0.4", "dev": true, @@ -12573,6 +13587,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oniguruma-to-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", + "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "dev": true, + "dependencies": { + "regex": "^4.3.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/open": { "version": "8.4.2", "dev": true, @@ -13313,6 +14339,16 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/preact": { + "version": "10.24.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", + "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prebuild-install": { "version": "7.1.2", "dev": true, @@ -13502,6 +14538,16 @@ "react-is": "^16.13.1" } }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/psl": { "version": "1.9.0", "dev": true, @@ -14662,6 +15708,12 @@ "@babel/runtime": "^7.8.4" } }, + "node_modules/regex": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-4.4.0.tgz", + "integrity": "sha512-uCUSuobNVeqUupowbdZub6ggI5/JZkYyJdDogddJr60L764oxC2pMZov1fQ3wM9bdyzUILDG+Sqx6NAKAz9rKQ==", + "dev": true + }, "node_modules/regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", @@ -15207,6 +16259,13 @@ "compute-scroll-into-view": "^3.0.2" } }, + "node_modules/search-insights": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", + "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", + "dev": true, + "peer": true + }, "node_modules/semver": { "version": "7.6.3", "dev": true, @@ -15276,6 +16335,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/shiki": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.2.tgz", + "integrity": "sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==", + "dev": true, + "dependencies": { + "@shikijs/core": "1.22.2", + "@shikijs/engine-javascript": "1.22.2", + "@shikijs/engine-oniguruma": "1.22.2", + "@shikijs/types": "1.22.2", + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, "node_modules/side-channel": { "version": "1.0.6", "dev": true, @@ -15464,6 +16537,16 @@ "source-map": "^0.6.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "dev": true, @@ -15492,6 +16575,15 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/split2": { "version": "4.2.0", "dev": true, @@ -15676,6 +16768,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-entities/node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "dev": true, @@ -15828,6 +16944,18 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/superjson": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", + "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "dev": true, + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, @@ -16000,6 +17128,12 @@ "optional": true, "peer": true }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true + }, "node_modules/tag-inject": { "version": "1.0.0", "dev": true, @@ -16444,6 +17578,16 @@ "tree-kill": "cli.js" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -17766,6 +18910,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, "node_modules/unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", @@ -17779,6 +18961,47 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/unist-util-visit/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, "node_modules/universalify": { "version": "2.0.1", "dev": true, @@ -17863,6 +19086,59 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/vfile-message/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, "node_modules/vite": { "version": "5.4.10", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", @@ -18227,6 +19503,47 @@ "dev": true, "license": "MIT" }, + "node_modules/vitepress": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.5.0.tgz", + "integrity": "sha512-q4Q/G2zjvynvizdB3/bupdYkCJe2umSAMv9Ju4d92E6/NXJ59z70xB0q5p/4lpRyAwflDsbwy1mLV9Q5+nlB+g==", + "dev": true, + "dependencies": { + "@docsearch/css": "^3.6.2", + "@docsearch/js": "^3.6.2", + "@iconify-json/simple-icons": "^1.2.10", + "@shikijs/core": "^1.22.2", + "@shikijs/transformers": "^1.22.2", + "@shikijs/types": "^1.22.2", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^5.1.4", + "@vue/devtools-api": "^7.5.4", + "@vue/shared": "^3.5.12", + "@vueuse/core": "^11.1.0", + "@vueuse/integrations": "^11.1.0", + "focus-trap": "^7.6.0", + "mark.js": "8.11.1", + "minisearch": "^7.1.0", + "shiki": "^1.22.2", + "vite": "^5.4.10", + "vue": "^3.5.12" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, "node_modules/vitest": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.4.tgz", @@ -18300,6 +19617,27 @@ "node": ">=0.10.0" } }, + "node_modules/vue": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.12.tgz", + "integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.5.12", + "@vue/compiler-sfc": "3.5.12", + "@vue/runtime-dom": "3.5.12", + "@vue/server-renderer": "3.5.12", + "@vue/shared": "3.5.12" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/vue-eslint-parser": { "version": "9.4.3", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", @@ -18764,6 +20102,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index 87e69fc0..a9d0d6e9 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "name": "image-manager", "version": "2.3.4", "private": true, - "description": "View, compress, crop, convert format, search and find similary images in VS Code | 浏览、压缩、裁剪、转换格式、搜索、查找相似图片的 VS Code 插件", + "packageManager": "npm@10.5.2", + "description": "View, compress, crop, convert format, search, filter and find similary images in VS Code", "type": "commonjs", "keywords": [ "image", @@ -63,7 +64,10 @@ "bump": "bumpp package.json --no-commit --tag --no-push --all -x \"npm run changelog\"", "vscode:prepublish": "run-p build download-sharp-releases", "pack": "vsce package", - "publish": "vsce publish" + "publish": "vsce publish", + "docs:dev": "vitepress dev docs", + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs" }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.18.0", @@ -86,7 +90,7 @@ "@types/markdown-it": "^14.1.2", "@types/micromatch": "^4.0.9", "@types/minimist": "^1.2.5", - "@types/node": "^22.8.5", + "@types/node": "^22.9.0", "@types/pump": "1.1.3", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", @@ -100,7 +104,7 @@ "ahooks": "^3.8.1", "ahooks-x": "^1.3.4", "antd": "^5.21.6", - "bumpp": "^9.8.0", + "bumpp": "^9.8.1", "consola": "^3.2.3", "context-state": "^3.1.2", "conventional-changelog-cli": "^5.0.0", @@ -111,7 +115,7 @@ "delay": "^6.0.0", "destr": "^2.0.3", "escape-string-regexp": "^5.0.0", - "eslint": "^9.13.0", + "eslint": "^9.14.0", "eventemitter3": "^5.0.1", "execa": "8.0.1", "exif-reader": "^2.0.1", @@ -179,6 +183,7 @@ "vite-plugin-html": "^3.2.2", "vite-plugin-i18n-ally": "^5.2.2", "vite-plugin-markdown": "^2.2.0", + "vitepress": "^1.5.0", "vitest": "^2.1.4" }, "engines": { diff --git a/patches/rc-tooltip+6.2.1.patch b/patches/rc-tooltip+6.2.1.patch index be50f38a..38b5f1e9 100644 --- a/patches/rc-tooltip+6.2.1.patch +++ b/patches/rc-tooltip+6.2.1.patch @@ -1,15 +1,13 @@ diff --git a/node_modules/rc-tooltip/es/Tooltip.js b/node_modules/rc-tooltip/es/Tooltip.js -index daf1250..c7b345d 100644 +index daf1250..58bafc1 100644 --- a/node_modules/rc-tooltip/es/Tooltip.js +++ b/node_modules/rc-tooltip/es/Tooltip.js -@@ -71,8 +71,8 @@ var Tooltip = function Tooltip(props, ref) { +@@ -71,7 +71,7 @@ var Tooltip = function Tooltip(props, ref) { popupAnimation: animation, popupMotion: motion, defaultPopupVisible: defaultVisible, - autoDestroy: destroyTooltipOnHide, -- mouseLeaveDelay: mouseLeaveDelay, + autoDestroy: true, -+ mouseLeaveDelay: 0, + mouseLeaveDelay: mouseLeaveDelay, popupStyle: overlayStyle, mouseEnterDelay: mouseEnterDelay, - arrow: showArrow diff --git a/src/commands/mirror.ts b/src/commands/mirror.ts index 11451a44..03c6ca1a 100644 --- a/src/commands/mirror.ts +++ b/src/commands/mirror.ts @@ -5,20 +5,22 @@ import { i18n } from '~/i18n' import { type ExtensionModule } from '~/module' import { Commands } from '.' -export const mirrors = [ - { - label: 'registry站点镜像', - description: 'https://registry.npmmirror.com/-/binary', - }, - { - label: '二进制文件镜像', - description: 'https://npmmirror.com/mirrors', - }, - { - label: 'cdn二进制文件镜像', - description: 'https://cdn.npmmirror.com/binaries', - }, -] +export const mirrors = () => { + return [ + { + label: i18n.t('prompt.registry_mirror'), + description: 'https://registry.npmmirror.com/-/binary', + }, + { + label: i18n.t('prompt.binary_mirror'), + description: 'https://npmmirror.com/mirrors', + }, + { + label: i18n.t('prompt.cdn_mirror'), + description: 'https://cdn.npmmirror.com/binaries', + }, + ] +} export default function () { async function enableMirror() { @@ -40,7 +42,7 @@ export default function () { const previousMirrorUrl = Config.mirror_url const mirror = await window.showQuickPick( - mirrors.map( + mirrors().map( (t) => ({ label: t.label, @@ -53,7 +55,7 @@ export default function () { ) if (mirror) { - const selected = mirrors.find((t) => t.label === mirror.label)?.description + const selected = mirrors().find((t) => t.label === mirror.label)?.description await Promise.all([ Config.updateConfig(ConfigKey.mirror_url, selected, ConfigurationTarget.Global), Config.updateConfig(ConfigKey.mirror_enabled, true, ConfigurationTarget.Global), diff --git a/src/core/sharp/installer.ts b/src/core/sharp/installer.ts index e4d0bb05..eda54e8c 100644 --- a/src/core/sharp/installer.ts +++ b/src/core/sharp/installer.ts @@ -31,7 +31,7 @@ enum CacheType { extension = 'extension', } -const CNPM_BINARY_REGISTRY = mirrors[0].description +const CNPM_BINARY_REGISTRY = () => mirrors()[0].description const SHARP_LIBVIPS = 'sharp-libvips' const VENDOR = 'vendor' const BUILD = 'build' @@ -112,7 +112,7 @@ export class Installer { Channel.info(`${i18n.t('core.extension_root')}: ${this.cwd}`) Channel.info(`${i18n.t('core.tip')}: ${i18n.t('core.dep_url_tip')} ⬇️`) Channel.info( - `${i18n.t('core.dep_url')}: ${CNPM_BINARY_REGISTRY}/${SHARP_LIBVIPS}/v${SHARP_LIBVIPS_VERSION}/${this._libvips_bin}`, + `${i18n.t('core.dep_url')}: ${CNPM_BINARY_REGISTRY()}/${SHARP_LIBVIPS}/v${SHARP_LIBVIPS_VERSION}/${this._libvips_bin}`, ) Channel.divider() } @@ -493,7 +493,7 @@ export class Installer { try { const npm_config_sharp_libvips_binary_host = resolveMirrorUrl({ name: SHARP_LIBVIPS, - fallbackUrl: `${CNPM_BINARY_REGISTRY}/${SHARP_LIBVIPS}`, + fallbackUrl: `${CNPM_BINARY_REGISTRY()}/${SHARP_LIBVIPS}`, }) Channel.debug(`libvips binary host: ${npm_config_sharp_libvips_binary_host}`) diff --git a/src/webview/image-manager/components/image-collapse/components/single-label/index.tsx b/src/webview/image-manager/components/image-collapse/components/single-label/index.tsx index ba6615f8..41c5404a 100644 --- a/src/webview/image-manager/components/image-collapse/components/single-label/index.tsx +++ b/src/webview/image-manager/components/image-collapse/components/single-label/index.tsx @@ -3,6 +3,7 @@ import { useHotkeys } from 'react-hotkeys-hook' import { Key } from 'ts-key-enum' import { classNames } from 'tw-clsx' import useImageOperation from '~/webview/image-manager/hooks/use-image-operation' +import { OS } from '~/webview/ui-framework/src/utils/device' import { type EnableCollapseContextMenuType } from '../../../context-menus/components/collapse-context-menu' import useCollapseContextMenu from '../../../context-menus/components/collapse-context-menu/hooks/use-collapse-context-menu' @@ -27,19 +28,30 @@ function SingleLabel(props: SingleLabelProps) { [Key.Enter, `mod+${Key.Backspace}`, Key.Delete], (e) => { switch (e.key) { + case Key.F2: { + if (OS.isWindows) { + hideAll() + beginRenameDirProcess(dirPath) + } + return + } case Key.Enter: { - hideAll() - beginRenameDirProcess(dirPath) + if (!OS.isWindows) { + hideAll() + beginRenameDirProcess(dirPath) + } return } - // mac delete key case Key.Backspace: { - beginDeleteDirProcess(dirPath) + if (!OS.isWindows) { + beginDeleteDirProcess(dirPath) + } return } - // windows delete key case Key.Delete: { - beginDeleteDirProcess(dirPath) + if (OS.isWindows) { + beginDeleteDirProcess(dirPath) + } return } default: diff --git a/src/webview/image-manager/components/lazy-image/index.tsx b/src/webview/image-manager/components/lazy-image/index.tsx index 8311de5e..e0890c7f 100644 --- a/src/webview/image-manager/components/lazy-image/index.tsx +++ b/src/webview/image-manager/components/lazy-image/index.tsx @@ -18,6 +18,7 @@ import { classNames } from 'tw-clsx' import { DEFAULT_CONFIG } from '~/core/config/common' import { Compressed } from '~/enums' import { CmdToVscode } from '~/message/cmd' +import { OS } from '~/webview/ui-framework/src/utils/device' import { getAppRoot } from '~/webview/utils' import { vscodeApi } from '~/webview/vscode-api' import GlobalContext from '../../contexts/global-context' @@ -188,18 +189,31 @@ function LazyImage(props: LazyImageProps) { if (contextMenu?.enable?.fs) { switch (e.key) { case Key.Enter: { - hideAll() - beginRenameImageProcess(image) + if (!OS.isWindows) { + hideAll() + beginRenameImageProcess(image) + } + return + } + // windows rename key + case Key.F2: { + if (OS.isWindows) { + hideAll() + beginRenameImageProcess(image) + } return } - // mac delete key case Key.Backspace: { - handleDelete() + if (!OS.isWindows) { + handleDelete() + } return } // windows delete key case Key.Delete: { - handleDelete() + if (OS.isWindows) { + handleDelete() + } return } case 'c': { diff --git a/src/webview/image-manager/hooks/use-image-filter/use-image-filter.tsx b/src/webview/image-manager/hooks/use-image-filter/use-image-filter.tsx index f5aee2c0..32f558a7 100644 --- a/src/webview/image-manager/hooks/use-image-filter/use-image-filter.tsx +++ b/src/webview/image-manager/hooks/use-image-filter/use-image-filter.tsx @@ -1,4 +1,5 @@ import { useTranslation } from 'react-i18next' +import { upperFirst } from 'lodash-es' import useImperativeModal from '../use-imperative-modal' import ImageFilter from './image-filter' @@ -10,7 +11,7 @@ export default function useImageFilter() { const { showModal } = useImperativeModal({ modalProps: { width: 'fit-content', - title: t('im.filter'), + title: upperFirst(t('im.filter')), keyboard: true, }, FC: ImageFilter, diff --git a/src/webview/ui-framework/src/utils/device.ts b/src/webview/ui-framework/src/utils/device.ts index 6d19d074..5ce79fa2 100644 --- a/src/webview/ui-framework/src/utils/device.ts +++ b/src/webview/ui-framework/src/utils/device.ts @@ -5,6 +5,6 @@ function getUA() { } export const OS = { - isMac: () => os.isMac(getUA()), - isWindows: () => os.isWindows(getUA()), + isMac: os.isMac(getUA()), + isWindows: os.isWindows(getUA()), }