mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
feat(plugin-md-power): add qrcode syntax plugin for markdown (#777)
* feat(plugin-md-power): add qrcode syntax plugin for markdown * chore: tweak
This commit is contained in:
parent
07710247bb
commit
157281aec8
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -76,6 +76,7 @@
|
|||||||
"nprogress",
|
"nprogress",
|
||||||
"pnpm",
|
"pnpm",
|
||||||
"portfinder",
|
"portfinder",
|
||||||
|
"qrcode",
|
||||||
"shiki",
|
"shiki",
|
||||||
"shikiji",
|
"shikiji",
|
||||||
"shikijs",
|
"shikijs",
|
||||||
|
|||||||
@ -58,6 +58,7 @@ export const themeGuide: ThemeCollectionItem = defineCollection({
|
|||||||
'code-tree',
|
'code-tree',
|
||||||
'field',
|
'field',
|
||||||
'tabs',
|
'tabs',
|
||||||
|
'qrcode',
|
||||||
'timeline',
|
'timeline',
|
||||||
'demo-wrapper',
|
'demo-wrapper',
|
||||||
'flex',
|
'flex',
|
||||||
|
|||||||
@ -58,6 +58,7 @@ export const themeGuide: ThemeCollectionItem = defineCollection({
|
|||||||
'code-tree',
|
'code-tree',
|
||||||
'field',
|
'field',
|
||||||
'tabs',
|
'tabs',
|
||||||
|
'qrcode',
|
||||||
'timeline',
|
'timeline',
|
||||||
'demo-wrapper',
|
'demo-wrapper',
|
||||||
'flex',
|
'flex',
|
||||||
|
|||||||
@ -36,6 +36,7 @@ export const theme: Theme = plumeTheme({
|
|||||||
imageSize: 'all',
|
imageSize: 'all',
|
||||||
mark: 'lazy',
|
mark: 'lazy',
|
||||||
pdf: true,
|
pdf: true,
|
||||||
|
qrcode: true,
|
||||||
caniuse: true,
|
caniuse: true,
|
||||||
acfun: true,
|
acfun: true,
|
||||||
bilibili: true,
|
bilibili: true,
|
||||||
|
|||||||
238
docs/en/guide/markdown/qrcode.md
Normal file
238
docs/en/guide/markdown/qrcode.md
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
---
|
||||||
|
title: qrcode
|
||||||
|
icon: uiw:qrcode
|
||||||
|
createTime: 2025/12/05 16:16:06
|
||||||
|
permalink: /en/guide/markdown/qrcode/
|
||||||
|
badge: 新
|
||||||
|
---
|
||||||
|
|
||||||
|
@[qrcode](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
In Markdown, you can embed QR code images generated from text using simple syntax, allowing them to be scanned when needed.
|
||||||
|
|
||||||
|
The text can be:
|
||||||
|
|
||||||
|
- A remotely accessible link address
|
||||||
|
- A path to a `.md` file within the VuePress site _(both absolute and relative paths are supported)_
|
||||||
|
- Any plain text _(avoid overly long text)_
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
This feature is disabled by default. You need to enable it in the `theme` configuration.
|
||||||
|
|
||||||
|
```ts title=".vuepress/config.ts"
|
||||||
|
export default defineUserConfig({
|
||||||
|
theme: plumeTheme({
|
||||||
|
markdown: {
|
||||||
|
qrcode: true, // [!code ++]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
### Inline Syntax
|
||||||
|
|
||||||
|
Inline syntax is suitable for shorter `text`, such as links.
|
||||||
|
|
||||||
|
```md
|
||||||
|
<!-- Basic Syntax -->
|
||||||
|
@[qrcode](text)
|
||||||
|
<!-- With Attributes -->
|
||||||
|
@[qrcode card svg title="xxx" align="center"](text)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Syntax
|
||||||
|
|
||||||
|
Container syntax is suitable for longer `text`, such as paragraphs or multi-line text.
|
||||||
|
|
||||||
|
```md
|
||||||
|
::: qrcode card svg title="xxx" align="center"
|
||||||
|
text
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
::: warning QR codes generated from overly long text may be truncated and potentially unscannable.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
:::: field-group
|
||||||
|
::: field name="card" type="boolean" optional default="false"
|
||||||
|
Whether to enable the card style.
|
||||||
|
:::
|
||||||
|
::: field name="svg" type="boolean" optional default="false"
|
||||||
|
Whether to render the QR code in SVG format. The default format is PNG.
|
||||||
|
:::
|
||||||
|
::: field name="title" type="string" optional
|
||||||
|
The title of the QR code.
|
||||||
|
:::
|
||||||
|
::: field name="align" type="'left' | 'center' | 'right'" optional default="left"
|
||||||
|
The alignment of the QR code.
|
||||||
|
:::
|
||||||
|
::: field name="width" type="number" optional default="300"
|
||||||
|
The width of the QR code.
|
||||||
|
:::
|
||||||
|
::::
|
||||||
|
|
||||||
|
The following attribute configurations directly affect the final rendering of the QR code.
|
||||||
|
Usually, the default values are sufficient and do not require configuration.
|
||||||
|
|
||||||
|
:::: field-group
|
||||||
|
::: field name="light" type="string" optional default="#ffffffff"
|
||||||
|
The color for the light parts of the QR code, i.e., the background color.
|
||||||
|
:::
|
||||||
|
::: field name="dark" type="string" optional default="#000000ff"
|
||||||
|
The color for the dark parts of the QR code, i.e., the QR code color.
|
||||||
|
:::
|
||||||
|
::: field name="margin" type="number" optional default="2"
|
||||||
|
The margin of the QR code.
|
||||||
|
:::
|
||||||
|
::: field name="level" type="'L' | 'M' | 'Q' | 'H'" optional default="M"
|
||||||
|
**Error Correction Level**
|
||||||
|
|
||||||
|
Error correction allows the QR code to be successfully scanned even if it is dirty or damaged.
|
||||||
|
Four levels are available depending on the operating environment.
|
||||||
|
|
||||||
|
Higher levels provide better error resistance but reduce the data capacity of the symbol.
|
||||||
|
|
||||||
|
If the QR code symbol is unlikely to be damaged, lower error correction levels like Low or Medium can be safely used.
|
||||||
|
:::
|
||||||
|
::: field name="version" type="number" optional
|
||||||
|
**QR Code Version**
|
||||||
|
|
||||||
|
If not specified, a more suitable value will be automatically calculated. Valid range: `1-40`.
|
||||||
|
:::
|
||||||
|
::: field name="scale" type="number" optional default="4"
|
||||||
|
Scaling factor. A value of 1 means 1 pixel per module (black dot).
|
||||||
|
:::
|
||||||
|
::: field name="mask" type="1 | 2 | 3 | 4 | 5 | 6 | 7" optional
|
||||||
|
The mask pattern used to mask the symbol.
|
||||||
|
|
||||||
|
If not specified, a more suitable value will be automatically calculated.
|
||||||
|
::::
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Accessible Remote Link
|
||||||
|
|
||||||
|
**Input:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
|
||||||
|
@[qrcode](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
|
||||||
|
### Internal Page Path
|
||||||
|
|
||||||
|
**Input:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode](.) <!-- `.` represents the current page address -->
|
||||||
|
@[qrcode](./steps.md) <!-- Relative path -->
|
||||||
|
@[qrcode](/guide/markdown/qrcode.md) <!-- Absolute path -->
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
|
||||||
|
::: flex
|
||||||
|
@[qrcode](.)
|
||||||
|
@[qrcode](./steps.md)
|
||||||
|
@[qrcode](/guide/markdown/qrcode.md)
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Arbitrary Text
|
||||||
|
|
||||||
|
**Input:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode](vuepress-theme-plume is an open-source VuePress theme)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
|
||||||
|
@[qrcode](vuepress-theme-plume is an open-source VuePress theme)
|
||||||
|
|
||||||
|
**Input:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
::: qrcode title="The Road Not Taken · by Robert Frost"
|
||||||
|
Two roads diverged in a yellow wood,
|
||||||
|
And sorry I could not travel both
|
||||||
|
And be one traveler, long I stood
|
||||||
|
And looked down one as far as I could
|
||||||
|
To where it bent in the undergrowth;
|
||||||
|
|
||||||
|
Then took the other, as just as fair,
|
||||||
|
And having perhaps the better claim,
|
||||||
|
Because it was grassy and wanted wear;
|
||||||
|
Though as for that the passing there
|
||||||
|
Had worn them really about the same,
|
||||||
|
|
||||||
|
And both that morning equally lay
|
||||||
|
In leaves no step had trodden black.
|
||||||
|
Oh, I kept the first for another day!
|
||||||
|
Yet knowing how way leads on to way,
|
||||||
|
I doubted if I should ever come back.
|
||||||
|
|
||||||
|
I shall be telling this with a sigh
|
||||||
|
Somewhere ages and ages hence:
|
||||||
|
Two roads diverged in a wood, and I—
|
||||||
|
I took the one less traveled by,
|
||||||
|
And that has made all the difference.
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
|
||||||
|
::: qrcode title="The Road Not Taken · by Robert Frost"
|
||||||
|
Two roads diverged in a yellow wood,
|
||||||
|
And sorry I could not travel both
|
||||||
|
And be one traveler, long I stood
|
||||||
|
And looked down one as far as I could
|
||||||
|
To where it bent in the undergrowth;
|
||||||
|
|
||||||
|
Then took the other, as just as fair,
|
||||||
|
And having perhaps the better claim,
|
||||||
|
Because it was grassy and wanted wear;
|
||||||
|
Though as for that the passing there
|
||||||
|
Had worn them really about the same,
|
||||||
|
|
||||||
|
And both that morning equally lay
|
||||||
|
In leaves no step had trodden black.
|
||||||
|
Oh, I kept the first for another day!
|
||||||
|
Yet knowing how way leads on to way,
|
||||||
|
I doubted if I should ever come back.
|
||||||
|
|
||||||
|
I shall be telling this with a sigh
|
||||||
|
Somewhere ages and ages hence:
|
||||||
|
Two roads diverged in a wood, and I—
|
||||||
|
I took the one less traveled by,
|
||||||
|
And that has made all the difference.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### QR Code Card with Information
|
||||||
|
|
||||||
|
**Input:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode card title="vuepress-theme-plume"](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
```
|
||||||
|
|
||||||
|
Equivalent to:
|
||||||
|
|
||||||
|
```md
|
||||||
|
::: qrcode card title="vuepress-theme-plume"
|
||||||
|
https://github.com/pengzhanbo/vuepress-theme-plume
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
|
||||||
|
@[qrcode card title="vuepress-theme-plume"](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
204
docs/guide/markdown/qrcode.md
Normal file
204
docs/guide/markdown/qrcode.md
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
---
|
||||||
|
title: 二维码
|
||||||
|
icon: uiw:qrcode
|
||||||
|
createTime: 2025/12/05 10:37:43
|
||||||
|
permalink: /guide/markdown/qrcode/
|
||||||
|
badge: 新
|
||||||
|
---
|
||||||
|
|
||||||
|
@[qrcode](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
在 Markdown 中,通过简单的语法,可以在文档中插入由文本转换成的二维码图片,以便在需要时进行扫描。
|
||||||
|
|
||||||
|
文本可以是:
|
||||||
|
|
||||||
|
- 远程可访问的链接地址
|
||||||
|
- vuepress 站点内的 `.md` 文件路径 _(绝对路径 或相对路径 均支持)_
|
||||||
|
- 任意普通文本 (避免过长的文本)
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
该功能默认不启用,你需要在 `theme` 配置中启用。
|
||||||
|
|
||||||
|
```ts title=".vuepress/config.ts"
|
||||||
|
export default defineUserConfig({
|
||||||
|
theme: plumeTheme({
|
||||||
|
markdown: {
|
||||||
|
qrcode: true, // [!code ++]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## 语法
|
||||||
|
|
||||||
|
### 单行语法
|
||||||
|
|
||||||
|
单行语法适用于 `text` 文本较短时,比如 链接 等。
|
||||||
|
|
||||||
|
```md
|
||||||
|
<!-- 基础语法-->
|
||||||
|
@[qrcode](text)
|
||||||
|
<!-- 添加属性 -->
|
||||||
|
@[qrcode card svg title="xxx" align="center"](text)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 容器语法
|
||||||
|
|
||||||
|
容器语法适用于 `text` 文本较长时,比如 段落,多行文本 等。
|
||||||
|
|
||||||
|
```md
|
||||||
|
::: qrcode card svg title="xxx" align="center"
|
||||||
|
text
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
::: warning 过长的文本生成的二维码可能会被截断,且可能无法扫描
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 属性
|
||||||
|
|
||||||
|
:::: field-group
|
||||||
|
::: field name="card" type="boolean" optional default="false"
|
||||||
|
是否启用卡片样式。
|
||||||
|
:::
|
||||||
|
::: field name="svg" type="boolean" optional default="false"
|
||||||
|
是否将二维码渲染为 SVG 格式。默认渲染为 PNG 格式。
|
||||||
|
:::
|
||||||
|
::: field name="title" type="string" optional
|
||||||
|
二维码标题。
|
||||||
|
:::
|
||||||
|
::: field name="align" type="'left' | 'center' | 'right'" optional default="left"
|
||||||
|
二维码对齐方式。
|
||||||
|
:::
|
||||||
|
::: field name="width" type="number" optional default="300"
|
||||||
|
二维码宽度。
|
||||||
|
:::
|
||||||
|
::::
|
||||||
|
|
||||||
|
以下属性配置将直接影响二维码的最终渲染效果,通常使用默认值即可,无需配置。
|
||||||
|
|
||||||
|
:::: field-group
|
||||||
|
::: field name="light" type="string" optional default="#ffffffff"
|
||||||
|
二维码亮色部分颜色,即背景色
|
||||||
|
:::
|
||||||
|
::: field name="dark" type="string" optional default="#000000ff"
|
||||||
|
二维码暗色部分颜色,即二维码颜色
|
||||||
|
:::
|
||||||
|
::: field name="margin" type="number" optional default="2"
|
||||||
|
二维码边距
|
||||||
|
:::
|
||||||
|
::: field name="level" type="'L' | 'M' | 'Q' | 'H'" optional default="M"
|
||||||
|
**纠错等级**
|
||||||
|
|
||||||
|
纠错能力使得即使二维码符号被污染或损坏,也能成功扫描。根据操作环境,有四个级别可供选择。
|
||||||
|
|
||||||
|
更高级别提供更好的抗错能力,但会降低符号的容量。
|
||||||
|
|
||||||
|
如果二维码符号可能被损坏的几率较低,则可以安全使用低纠错级别,如低或中。
|
||||||
|
:::
|
||||||
|
::: field name="version" type="number" optional
|
||||||
|
**二维码版本**
|
||||||
|
|
||||||
|
若未指定,将自动计算更合适的值。取值范围 `1-40`。
|
||||||
|
:::
|
||||||
|
::: field name="scale" type="number" optional default="4"
|
||||||
|
缩放因子。值为 1 表示每个模块(黑点)对应 1 像素。
|
||||||
|
:::
|
||||||
|
::: field name="mask" type="1 | 2 | 3 | 4 | 5 | 6 | 7" optional
|
||||||
|
用于遮蔽符号的掩码模式。
|
||||||
|
|
||||||
|
若未指定,将自动计算更合适的值。
|
||||||
|
::::
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
|
||||||
|
### 可访问的远程链接
|
||||||
|
|
||||||
|
**输入:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
```
|
||||||
|
|
||||||
|
**输出:**
|
||||||
|
|
||||||
|
@[qrcode](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
|
||||||
|
### 站内的页面路径
|
||||||
|
|
||||||
|
**输入:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode](.) <!-- `.` 表示当前页面地址 -->
|
||||||
|
@[qrcode](./steps.md) <!-- 相对路径 -->
|
||||||
|
@[qrcode](/guide/markdown/qrcode.md) <!-- 绝对路径 -->
|
||||||
|
```
|
||||||
|
|
||||||
|
**输出:**
|
||||||
|
|
||||||
|
::: flex
|
||||||
|
@[qrcode](.)
|
||||||
|
@[qrcode](./steps.md)
|
||||||
|
@[qrcode](/guide/markdown/qrcode.md)
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 任意文本
|
||||||
|
|
||||||
|
**输入:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode](vuepress-theme-plume 是一款开源的 VuePress 主题)
|
||||||
|
```
|
||||||
|
|
||||||
|
**输出:**
|
||||||
|
|
||||||
|
@[qrcode](vuepress-theme-plume 是一款开源的 VuePress 主题)
|
||||||
|
|
||||||
|
**输入:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
::: qrcode title="宣州谢朓楼饯别校书叔云 <唐·李白>"
|
||||||
|
弃我去者,昨日之日不可留。
|
||||||
|
乱我心者,今日之日多烦忧。
|
||||||
|
长风万里送秋雁,对此可以酣高楼。
|
||||||
|
蓬莱文章建安骨,中间小谢又清发。
|
||||||
|
俱怀逸兴壮思飞,欲上青天览明月。
|
||||||
|
抽刀断水水更流,举杯消愁愁更愁。
|
||||||
|
人生在世不称意,明朝散发弄扁舟。
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
**输出:**
|
||||||
|
|
||||||
|
::: qrcode title="宣州谢朓楼饯别校书叔云 <唐·李白>"
|
||||||
|
弃我去者,昨日之日不可留。
|
||||||
|
乱我心者,今日之日多烦忧。
|
||||||
|
长风万里送秋雁,对此可以酣高楼。
|
||||||
|
蓬莱文章建安骨,中间小谢又清发。
|
||||||
|
俱怀逸兴壮思飞,欲上青天览明月。
|
||||||
|
抽刀断水水更流,举杯消愁愁更愁。
|
||||||
|
人生在世不称意,明朝散发弄扁舟。
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 带信息的二维码卡片
|
||||||
|
|
||||||
|
**输入:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
@[qrcode card title="vuepress-theme-plume"](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
|
```
|
||||||
|
|
||||||
|
等同于:
|
||||||
|
|
||||||
|
```md
|
||||||
|
::: qrcode card title="vuepress-theme-plume"
|
||||||
|
https://github.com/pengzhanbo/vuepress-theme-plume
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
**输出:**
|
||||||
|
|
||||||
|
@[qrcode card title="vuepress-theme-plume"](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||||
@ -50,6 +50,7 @@
|
|||||||
"@types/minimist": "catalog:dev",
|
"@types/minimist": "catalog:dev",
|
||||||
"@types/node": "catalog:dev",
|
"@types/node": "catalog:dev",
|
||||||
"@types/picomatch": "catalog:dev",
|
"@types/picomatch": "catalog:dev",
|
||||||
|
"@types/qrcode": "catalog:dev",
|
||||||
"@types/stylus": "catalog:dev",
|
"@types/stylus": "catalog:dev",
|
||||||
"@types/three": "catalog:dev",
|
"@types/three": "catalog:dev",
|
||||||
"@types/webpack-env": "catalog:dev",
|
"@types/webpack-env": "catalog:dev",
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`qrcodePlugin > should not work with container syntax 1`] = `"<VPQRCode text="text" mode="img" />"`;
|
||||||
|
|
||||||
|
exports[`qrcodePlugin > should not work with container syntax 2`] = `"<VPQRCode text="text" svg mode="card" />"`;
|
||||||
|
|
||||||
|
exports[`qrcodePlugin > should not work with container syntax 3`] = `"<VPQRCode text="text" title="title" mode="img" />"`;
|
||||||
|
|
||||||
|
exports[`qrcodePlugin > should work with embed syntax 1`] = `"<VPQRCode text="text" mode="img" />"`;
|
||||||
|
|
||||||
|
exports[`qrcodePlugin > should work with embed syntax 2`] = `"<VPQRCode text="text" svg mode="card" />"`;
|
||||||
|
|
||||||
|
exports[`qrcodePlugin > should work with embed syntax 3`] = `"<VPQRCode text="text" title="title" mode="img" />"`;
|
||||||
27
plugins/plugin-md-power/__test__/qrcodePlugin.spec.ts
Normal file
27
plugins/plugin-md-power/__test__/qrcodePlugin.spec.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import MarkdownIt from 'markdown-it'
|
||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import { qrcodePlugin } from '../src/node/embed/qrcode.js'
|
||||||
|
|
||||||
|
describe('qrcodePlugin', () => {
|
||||||
|
it('should work with embed syntax', () => {
|
||||||
|
const md = MarkdownIt().use((md) => {
|
||||||
|
md.block.ruler.before('code', 'import_code', () => false)
|
||||||
|
md.renderer.rules.import_code = () => ''
|
||||||
|
}).use(qrcodePlugin)
|
||||||
|
|
||||||
|
expect(md.render('@[qrcode](text)')).toMatchSnapshot()
|
||||||
|
expect(md.render('@[qrcode svg card](text)')).toMatchSnapshot()
|
||||||
|
expect(md.render('@[qrcode title="title"](text)')).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not work with container syntax', () => {
|
||||||
|
const md = MarkdownIt().use((md) => {
|
||||||
|
md.block.ruler.before('code', 'import_code', () => false)
|
||||||
|
md.renderer.rules.import_code = () => ''
|
||||||
|
}).use(qrcodePlugin)
|
||||||
|
|
||||||
|
expect(md.render(':::qrcode\ntext\n:::')).toMatchSnapshot()
|
||||||
|
expect(md.render(':::qrcode svg card\ntext\n:::')).toMatchSnapshot()
|
||||||
|
expect(md.render(':::qrcode title="title"\ntext\n:::')).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -103,6 +103,7 @@
|
|||||||
"markdown-it-cjk-friendly": "catalog:prod",
|
"markdown-it-cjk-friendly": "catalog:prod",
|
||||||
"markdown-it-container": "catalog:prod",
|
"markdown-it-container": "catalog:prod",
|
||||||
"nanoid": "catalog:prod",
|
"nanoid": "catalog:prod",
|
||||||
|
"qrcode": "catalog:prod",
|
||||||
"shiki": "catalog:prod",
|
"shiki": "catalog:prod",
|
||||||
"tm-grammars": "catalog:prod",
|
"tm-grammars": "catalog:prod",
|
||||||
"tm-themes": "catalog:prod",
|
"tm-themes": "catalog:prod",
|
||||||
|
|||||||
228
plugins/plugin-md-power/src/client/components/VPQRCode.vue
Normal file
228
plugins/plugin-md-power/src/client/components/VPQRCode.vue
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { QRCodeToDataURLOptions, QRCodeToStringOptions } from 'qrcode'
|
||||||
|
import type { QRCodeProps } from '../../shared/index.js'
|
||||||
|
import { isLinkWithProtocol } from '@vuepress/helper/client'
|
||||||
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
|
import { resolveRoute, usePage, withBase } from 'vuepress/client'
|
||||||
|
|
||||||
|
const { title, text, mode, align = 'left', reverse = false, svg = false, width, level, version, mask, margin = 2, scale = 4, light, dark } = defineProps<QRCodeProps>()
|
||||||
|
|
||||||
|
const page = usePage()
|
||||||
|
|
||||||
|
let qr: typeof import('qrcode') | null = null
|
||||||
|
|
||||||
|
const qrcode = ref('')
|
||||||
|
const parsedText = ref('')
|
||||||
|
const isLink = ref(false)
|
||||||
|
|
||||||
|
const styles = computed(() => {
|
||||||
|
const size = typeof width === 'number' ? width : width ? Number.parseInt(width) : undefined
|
||||||
|
return size ? { '--vp-qrcode-size': `${size}px` } : undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
function parseText(): string | void {
|
||||||
|
isLink.value = false
|
||||||
|
if (!text || __VUEPRESS_SSR__)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
if (text === '.') {
|
||||||
|
isLink.value = true
|
||||||
|
return location.href.split(/[?#]/)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLinkWithProtocol(text)) {
|
||||||
|
isLink.value = true
|
||||||
|
return text.startsWith('//') ? `${location.protocol}${text}` : text
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.startsWith('/') || text.startsWith('./')) {
|
||||||
|
const [routePath, ...rest] = text.split(/([?#])/)
|
||||||
|
const currentPath = page.value.filePathRelative ? `/${page.value.filePathRelative}` : undefined
|
||||||
|
const { notFound, path } = resolveRoute(routePath, currentPath)
|
||||||
|
if (notFound) {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
isLink.value = true
|
||||||
|
return new URL(`${withBase(path)}${rest.join('')}`, location.href).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const callback = (_: any, url: string) => qrcode.value = url
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [text, svg, level, version, mask, margin, scale, light, dark],
|
||||||
|
async () => {
|
||||||
|
const text = parseText()
|
||||||
|
parsedText.value = text || ''
|
||||||
|
if (!text) {
|
||||||
|
qrcode.value = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
qr ??= (await import('qrcode' /* webpackChunkName: "qrcode" */)).default
|
||||||
|
const opts: QRCodeToDataURLOptions & QRCodeToStringOptions = {
|
||||||
|
version,
|
||||||
|
maskPattern: mask,
|
||||||
|
errorCorrectionLevel: (level ? level.toUpperCase() : 'M') as any,
|
||||||
|
width: 300 * Math.round(window.devicePixelRatio || 1),
|
||||||
|
margin,
|
||||||
|
scale,
|
||||||
|
color: { dark, light },
|
||||||
|
}
|
||||||
|
|
||||||
|
if (svg)
|
||||||
|
qr.toString(text, { type: 'svg', ...opts }, callback)
|
||||||
|
else
|
||||||
|
qr.toDataURL(text, { type: 'image/png', ...opts }, callback)
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
qr = null
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="qrcode" class="vp-qrcode" :class="{ card: mode === 'card', reverse, [align]: true }">
|
||||||
|
<div class="qrcode-content">
|
||||||
|
<div v-if="svg" class="qrcode-svg" :style="styles" :title="parsedText" v-html="qrcode" />
|
||||||
|
<img v-else class="qrcode-img" :src="qrcode" :alt="parsedText" :title="parsedText" :style="styles">
|
||||||
|
<div v-if="title && mode !== 'card'" class="qrcode-label">
|
||||||
|
{{ title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="mode === 'card'" class="qrcode-info">
|
||||||
|
<p v-if="title" class="qrcode-title">
|
||||||
|
{{ title }}
|
||||||
|
</p>
|
||||||
|
<p v-if="parsedText">
|
||||||
|
<a v-if="isLink" :href="parsedText" rel="noopener noreferrer" target="_blank">
|
||||||
|
{{ parsedText }}
|
||||||
|
</a>
|
||||||
|
<span v-else v-html="parsedText.replaceAll('\n', '<br>')" />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.vp-qrcode {
|
||||||
|
--vp-qrcode-size: 128px;
|
||||||
|
|
||||||
|
margin: 16px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.vp-qrcode {
|
||||||
|
--vp-qrcode-size: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode:not(.card).center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode:not(.card).right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: max-content;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--vp-c-text-2);
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px 20px;
|
||||||
|
background-color: var(--vp-c-bg-soft);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-svg,
|
||||||
|
.vp-qrcode .qrcode-img {
|
||||||
|
width: var(--vp-qrcode-size);
|
||||||
|
max-width: 100%;
|
||||||
|
height: var(--vp-qrcode-size);
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-svg :deep(svg) {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-info {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-info > p {
|
||||||
|
margin: 0;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode .qrcode-info .qrcode-title {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 960px) {
|
||||||
|
.vp-qrcode.card {
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode.card .qrcode-info {
|
||||||
|
align-self: center;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode.card:where(.reverse, .right) {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode.card:where(.reverse, .right) .qrcode-info {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode.card.center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-qrcode.card.center .qrcode-info {
|
||||||
|
flex: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -7,6 +7,7 @@ import { codeSandboxPlugin } from './code/codeSandbox.js'
|
|||||||
import { jsfiddlePlugin } from './code/jsfiddle.js'
|
import { jsfiddlePlugin } from './code/jsfiddle.js'
|
||||||
import { replitPlugin } from './code/replit.js'
|
import { replitPlugin } from './code/replit.js'
|
||||||
import { pdfPlugin } from './pdf.js'
|
import { pdfPlugin } from './pdf.js'
|
||||||
|
import { qrcodePlugin } from './qrcode.js'
|
||||||
import { acfunPlugin } from './video/acfun.js'
|
import { acfunPlugin } from './video/acfun.js'
|
||||||
import { artPlayerPlugin } from './video/artPlayer.js'
|
import { artPlayerPlugin } from './video/artPlayer.js'
|
||||||
import { bilibiliPlugin } from './video/bilibili.js'
|
import { bilibiliPlugin } from './video/bilibili.js'
|
||||||
@ -70,4 +71,9 @@ export function embedSyntaxPlugin(md: Markdown, options: MarkdownPowerPluginOpti
|
|||||||
// @[jsfiddle](user/id)
|
// @[jsfiddle](user/id)
|
||||||
md.use(jsfiddlePlugin)
|
md.use(jsfiddlePlugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.qrcode) {
|
||||||
|
// @[qrcode svg card title="xxx"](text)
|
||||||
|
md.use(qrcodePlugin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
plugins/plugin-md-power/src/node/embed/qrcode.ts
Normal file
37
plugins/plugin-md-power/src/node/embed/qrcode.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* @[qrcode svg card title="xxx"](text)
|
||||||
|
*/
|
||||||
|
import type { PluginWithOptions } from 'markdown-it'
|
||||||
|
import type { QRCodeMeta, QRCodeProps } from '../../shared/index.js'
|
||||||
|
import { omit } from '@pengzhanbo/utils'
|
||||||
|
import { createContainerSyntaxPlugin } from '../container/createContainer.js'
|
||||||
|
import { resolveAttrs } from '../utils/resolveAttrs.js'
|
||||||
|
import { stringifyAttrs } from '../utils/stringifyAttrs.js'
|
||||||
|
import { createEmbedRuleBlock } from './createEmbedRuleBlock.js'
|
||||||
|
|
||||||
|
export const qrcodePlugin: PluginWithOptions<never> = (md) => {
|
||||||
|
createEmbedRuleBlock<QRCodeMeta>(md, {
|
||||||
|
type: 'qrcode',
|
||||||
|
syntaxPattern: /^@\[qrcode([^\]]*)\]\(([^)]*)\)/,
|
||||||
|
meta([, info, text]) {
|
||||||
|
const { attrs } = resolveAttrs<QRCodeMeta>(info)
|
||||||
|
const { card, ...rest } = omit(attrs, ['text'])
|
||||||
|
|
||||||
|
return {
|
||||||
|
text,
|
||||||
|
...rest,
|
||||||
|
mode: rest.mode || (card ? 'card' : 'img'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content(meta) {
|
||||||
|
return `<VPQRCode${stringifyAttrs(meta)} />`
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
createContainerSyntaxPlugin(md, 'qrcode', (tokens, index) => {
|
||||||
|
const { content, meta } = tokens[index]
|
||||||
|
const { card, ...rest } = omit(meta, ['text'])
|
||||||
|
const props: QRCodeProps = { text: content?.trim(), ...rest, mode: rest.mode || (card ? 'card' : 'img') }
|
||||||
|
return `<VPQRCode ${stringifyAttrs(props)} />`
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -42,6 +42,9 @@ export function markdownPowerPlugin(
|
|||||||
['artplayer', 'dashjs', 'hls.js', 'mpegts.js/dist/mpegts.js'],
|
['artplayer', 'dashjs', 'hls.js', 'mpegts.js/dist/mpegts.js'],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (options.qrcode) {
|
||||||
|
addViteOptimizeDepsInclude(bundlerOptions, app, ['qrcode'])
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
extendsMarkdown: async (md, app) => {
|
extendsMarkdown: async (md, app) => {
|
||||||
|
|||||||
@ -131,15 +131,19 @@ export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOp
|
|||||||
enhances.add(`app.component('VPTable', VPTable)`)
|
enhances.add(`app.component('VPTable', VPTable)`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.qrcode) {
|
||||||
|
imports.add(`import VPQRCode from '${CLIENT_FOLDER}components/VPQRCode.vue'`)
|
||||||
|
enhances.add(`app.component('VPQRCode', VPQRCode)`)
|
||||||
|
}
|
||||||
|
|
||||||
const setupIcon = prepareIcon(imports, options.icon)
|
const setupIcon = prepareIcon(imports, options.icon)
|
||||||
const setupStmts: string[] = []
|
const setupStmts: string[] = []
|
||||||
const iconSetup = setupIcon.trim()
|
const iconSetup = setupIcon.trim()
|
||||||
if (iconSetup)
|
if (iconSetup)
|
||||||
setupStmts.push(iconSetup)
|
setupStmts.push(iconSetup)
|
||||||
|
|
||||||
const markMode = options.mark === 'lazy' ? 'lazy' : 'eager'
|
|
||||||
imports.add(`import { setupMarkHighlight } from '${CLIENT_FOLDER}composables/mark.js'`)
|
imports.add(`import { setupMarkHighlight } from '${CLIENT_FOLDER}composables/mark.js'`)
|
||||||
setupStmts.push(`setupMarkHighlight(${JSON.stringify(markMode)})`)
|
setupStmts.push(`setupMarkHighlight(${JSON.stringify(options.mark === 'lazy' ? 'lazy' : 'eager')})`)
|
||||||
|
|
||||||
const setupContent = setupStmts.length
|
const setupContent = setupStmts.length
|
||||||
? ` ${setupStmts.join('\n ')}\n`
|
? ` ${setupStmts.join('\n ')}\n`
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export * from './npmTo.js'
|
|||||||
export * from './pdf.js'
|
export * from './pdf.js'
|
||||||
export * from './plot.js'
|
export * from './plot.js'
|
||||||
export * from './plugin.js'
|
export * from './plugin.js'
|
||||||
|
export * from './qrcode.js'
|
||||||
export * from './repl.js'
|
export * from './repl.js'
|
||||||
export * from './replit.js'
|
export * from './replit.js'
|
||||||
export * from './size.js'
|
export * from './size.js'
|
||||||
|
|||||||
@ -256,6 +256,13 @@ export interface MarkdownPowerPluginOptions {
|
|||||||
*/
|
*/
|
||||||
table?: boolean | TableContainerOptions
|
table?: boolean | TableContainerOptions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用 二维码 嵌入语法
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
qrcode?: boolean
|
||||||
|
|
||||||
// enhance
|
// enhance
|
||||||
/**
|
/**
|
||||||
* 是否启用 自动填充 图片宽高属性
|
* 是否启用 自动填充 图片宽高属性
|
||||||
|
|||||||
89
plugins/plugin-md-power/src/shared/qrcode.ts
Normal file
89
plugins/plugin-md-power/src/shared/qrcode.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
export interface QRCodeMeta extends QRCodeProps {
|
||||||
|
/**
|
||||||
|
* mode: 'card' 的别名
|
||||||
|
*/
|
||||||
|
card?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QRCodeProps {
|
||||||
|
/**
|
||||||
|
* 二维码标题
|
||||||
|
* 作为 HTML 标签的 `title` 属性、`alt` 属性
|
||||||
|
*/
|
||||||
|
title?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二维码内容
|
||||||
|
*/
|
||||||
|
text?: string
|
||||||
|
/**
|
||||||
|
* 二维码宽度
|
||||||
|
*/
|
||||||
|
width?: number | string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示模式
|
||||||
|
* - img: 以图片的形式显示二维码
|
||||||
|
* - card: 以卡片的形式显示,卡片以左右布局,左侧二维码,右侧 标题 + 内容
|
||||||
|
* @default 'img'
|
||||||
|
*/
|
||||||
|
mode?: 'img' | 'card'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在 card 模式下是否翻转布局
|
||||||
|
*/
|
||||||
|
reverse?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二维码的对齐方式
|
||||||
|
* @default 'left'
|
||||||
|
*/
|
||||||
|
align?: 'left' | 'center' | 'right'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否渲染为 SVG 格式的二维码
|
||||||
|
* 默认输出为 PNG 格式的 dataURL
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
svg?: boolean
|
||||||
|
/**
|
||||||
|
* 纠错等级。
|
||||||
|
* 可能的取值为低、中、四分位、高,分别对应 L、M、Q、H。
|
||||||
|
* @default 'M'
|
||||||
|
*/
|
||||||
|
level?: 'L' | 'M' | 'Q' | 'H' | 'l' | 'm' | 'q' | 'h'
|
||||||
|
/**
|
||||||
|
* 二维码版本。若未指定,将自动计算更合适的值。
|
||||||
|
* 取值范围 1-40
|
||||||
|
*/
|
||||||
|
version?: number
|
||||||
|
/**
|
||||||
|
* 用于遮蔽符号的掩码模式。
|
||||||
|
* 可能的取值为0、1、2、3、4、5、6、7。
|
||||||
|
* 若未指定,系统将自动计算更合适的值。
|
||||||
|
*/
|
||||||
|
mask?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||||
|
/**
|
||||||
|
* 定义静区应有多宽。
|
||||||
|
* @default 4
|
||||||
|
*/
|
||||||
|
margin?: number
|
||||||
|
/**
|
||||||
|
* 缩放因子。值为1表示每个模块(黑点)对应1像素。
|
||||||
|
*/
|
||||||
|
scale?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暗色模块的颜色。值必须为十六进制格式(RGBA)。
|
||||||
|
* 注意:暗色应始终比浅色模块的颜色更深。
|
||||||
|
* @default '#000000ff'
|
||||||
|
*/
|
||||||
|
light?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 亮色模块的颜色。值必须为十六进制格式(RGBA)。
|
||||||
|
* 注意:亮色应始终比暗色模块的颜色更浅。
|
||||||
|
* @default '#ffffffff'
|
||||||
|
*/
|
||||||
|
dark?: string
|
||||||
|
}
|
||||||
165
pnpm-lock.yaml
generated
165
pnpm-lock.yaml
generated
@ -45,6 +45,9 @@ catalogs:
|
|||||||
'@types/picomatch':
|
'@types/picomatch':
|
||||||
specifier: ^4.0.2
|
specifier: ^4.0.2
|
||||||
version: 4.0.2
|
version: 4.0.2
|
||||||
|
'@types/qrcode':
|
||||||
|
specifier: ^1.5.6
|
||||||
|
version: 1.5.6
|
||||||
'@types/stylus':
|
'@types/stylus':
|
||||||
specifier: ^0.48.43
|
specifier: ^0.48.43
|
||||||
version: 0.48.43
|
version: 0.48.43
|
||||||
@ -293,6 +296,9 @@ catalogs:
|
|||||||
picomatch:
|
picomatch:
|
||||||
specifier: ^4.0.3
|
specifier: ^4.0.3
|
||||||
version: 4.0.3
|
version: 4.0.3
|
||||||
|
qrcode:
|
||||||
|
specifier: ^1.5.4
|
||||||
|
version: 1.5.4
|
||||||
shiki:
|
shiki:
|
||||||
specifier: ^3.17.0
|
specifier: ^3.17.0
|
||||||
version: 3.17.0
|
version: 3.17.0
|
||||||
@ -423,6 +429,9 @@ importers:
|
|||||||
'@types/picomatch':
|
'@types/picomatch':
|
||||||
specifier: catalog:dev
|
specifier: catalog:dev
|
||||||
version: 4.0.2
|
version: 4.0.2
|
||||||
|
'@types/qrcode':
|
||||||
|
specifier: catalog:dev
|
||||||
|
version: 1.5.6
|
||||||
'@types/stylus':
|
'@types/stylus':
|
||||||
specifier: catalog:dev
|
specifier: catalog:dev
|
||||||
version: 0.48.43
|
version: 0.48.43
|
||||||
@ -703,6 +712,9 @@ importers:
|
|||||||
pyodide:
|
pyodide:
|
||||||
specifier: catalog:peer
|
specifier: catalog:peer
|
||||||
version: 0.29.0
|
version: 0.29.0
|
||||||
|
qrcode:
|
||||||
|
specifier: catalog:prod
|
||||||
|
version: 1.5.4
|
||||||
sass:
|
sass:
|
||||||
specifier: catalog:peer
|
specifier: catalog:peer
|
||||||
version: 1.94.2
|
version: 1.94.2
|
||||||
@ -754,7 +766,7 @@ importers:
|
|||||||
version: 14.1.0(vue@3.5.25(typescript@5.9.3))
|
version: 14.1.0(vue@3.5.25(typescript@5.9.3))
|
||||||
'@vueuse/integrations':
|
'@vueuse/integrations':
|
||||||
specifier: catalog:prod
|
specifier: catalog:prod
|
||||||
version: 14.1.0(axios@1.13.2)(change-case@5.4.4)(focus-trap@7.6.6)(vue@3.5.25(typescript@5.9.3))
|
version: 14.1.0(axios@1.13.2)(change-case@5.4.4)(focus-trap@7.6.6)(qrcode@1.5.4)(vue@3.5.25(typescript@5.9.3))
|
||||||
chokidar:
|
chokidar:
|
||||||
specifier: ^5.0.0
|
specifier: ^5.0.0
|
||||||
version: 5.0.0
|
version: 5.0.0
|
||||||
@ -2630,6 +2642,9 @@ packages:
|
|||||||
'@types/picomatch@4.0.2':
|
'@types/picomatch@4.0.2':
|
||||||
resolution: {integrity: sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA==}
|
resolution: {integrity: sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA==}
|
||||||
|
|
||||||
|
'@types/qrcode@1.5.6':
|
||||||
|
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
|
||||||
|
|
||||||
'@types/qs@6.14.0':
|
'@types/qs@6.14.0':
|
||||||
resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
|
resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
|
||||||
|
|
||||||
@ -3394,6 +3409,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
camelcase@5.3.1:
|
||||||
|
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001733:
|
caniuse-lite@1.0.30001733:
|
||||||
resolution: {integrity: sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q==}
|
resolution: {integrity: sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q==}
|
||||||
|
|
||||||
@ -3504,6 +3523,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
|
resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
|
cliui@6.0.0:
|
||||||
|
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
||||||
|
|
||||||
cliui@8.0.1:
|
cliui@8.0.1:
|
||||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -3965,6 +3987,10 @@ packages:
|
|||||||
supports-color:
|
supports-color:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
decamelize@1.2.0:
|
||||||
|
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
decode-named-character-reference@1.2.0:
|
decode-named-character-reference@1.2.0:
|
||||||
resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
|
resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
|
||||||
|
|
||||||
@ -4034,6 +4060,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==}
|
resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==}
|
||||||
engines: {node: '>=0.3.1'}
|
engines: {node: '>=0.3.1'}
|
||||||
|
|
||||||
|
dijkstrajs@1.0.3:
|
||||||
|
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||||
|
|
||||||
dir-glob@3.0.1:
|
dir-glob@3.0.1:
|
||||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -4526,6 +4555,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
|
resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
find-up@4.1.0:
|
||||||
|
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
find-up@5.0.0:
|
find-up@5.0.0:
|
||||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -5416,6 +5449,10 @@ packages:
|
|||||||
localforage@1.10.0:
|
localforage@1.10.0:
|
||||||
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
|
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
|
||||||
|
|
||||||
|
locate-path@5.0.0:
|
||||||
|
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
locate-path@6.0.0:
|
locate-path@6.0.0:
|
||||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -5982,6 +6019,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
p-limit@2.3.0:
|
||||||
|
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
p-limit@3.1.0:
|
p-limit@3.1.0:
|
||||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -5990,6 +6031,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
|
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
|
p-locate@4.1.0:
|
||||||
|
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
p-locate@5.0.0:
|
p-locate@5.0.0:
|
||||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -6006,6 +6051,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==}
|
resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
p-try@2.2.0:
|
||||||
|
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
package-json-from-dist@1.0.1:
|
package-json-from-dist@1.0.1:
|
||||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||||
|
|
||||||
@ -6134,6 +6183,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
pngjs@5.0.0:
|
||||||
|
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
pnpm-workspace-yaml@1.3.0:
|
pnpm-workspace-yaml@1.3.0:
|
||||||
resolution: {integrity: sha512-Krb5q8Totd5mVuLx7we+EFHq/AfxA75nbfTm25Q1pIf606+RlaKUG+PXH8SDihfe5b5k4H09gE+sL47L1t5lbw==}
|
resolution: {integrity: sha512-Krb5q8Totd5mVuLx7we+EFHq/AfxA75nbfTm25Q1pIf606+RlaKUG+PXH8SDihfe5b5k4H09gE+sL47L1t5lbw==}
|
||||||
|
|
||||||
@ -6251,6 +6304,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-7gJ6mxcQb9vUBOtbKm5mDevbe2uRcOEVp1g4gb/Q+oLntB3HY8eBhOYRxFI2mlDFlY1e4DOSCptzxarXRvzxCA==}
|
resolution: {integrity: sha512-7gJ6mxcQb9vUBOtbKm5mDevbe2uRcOEVp1g4gb/Q+oLntB3HY8eBhOYRxFI2mlDFlY1e4DOSCptzxarXRvzxCA==}
|
||||||
engines: {node: '>=20'}
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
|
qrcode@1.5.4:
|
||||||
|
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
qs@6.14.0:
|
qs@6.14.0:
|
||||||
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
|
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
|
||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
@ -6346,6 +6404,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
require-main-filename@2.0.0:
|
||||||
|
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||||
|
|
||||||
requires-port@1.0.0:
|
requires-port@1.0.0:
|
||||||
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
||||||
|
|
||||||
@ -6619,6 +6680,9 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
set-blocking@2.0.0:
|
||||||
|
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||||
|
|
||||||
set-function-length@1.2.2:
|
set-function-length@1.2.2:
|
||||||
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -7469,6 +7533,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
|
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
which-module@2.0.1:
|
||||||
|
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
|
||||||
|
|
||||||
which-typed-array@1.1.19:
|
which-typed-array@1.1.19:
|
||||||
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
|
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -7497,6 +7564,10 @@ packages:
|
|||||||
wordwrap@1.0.0:
|
wordwrap@1.0.0:
|
||||||
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
|
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
|
||||||
|
|
||||||
|
wrap-ansi@6.2.0:
|
||||||
|
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
wrap-ansi@7.0.0:
|
wrap-ansi@7.0.0:
|
||||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -7532,6 +7603,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
y18n@4.0.3:
|
||||||
|
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||||
|
|
||||||
y18n@5.0.8:
|
y18n@5.0.8:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -7548,10 +7622,18 @@ packages:
|
|||||||
engines: {node: '>= 14.6'}
|
engines: {node: '>= 14.6'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
yargs-parser@18.1.3:
|
||||||
|
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
yargs-parser@21.1.1:
|
yargs-parser@21.1.1:
|
||||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
yargs@15.4.1:
|
||||||
|
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
yargs@17.7.2:
|
yargs@17.7.2:
|
||||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -9233,7 +9315,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/jsonfile@6.1.4':
|
'@types/jsonfile@6.1.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 24.10.0
|
'@types/node': 24.10.1
|
||||||
|
|
||||||
'@types/less@3.0.8': {}
|
'@types/less@3.0.8': {}
|
||||||
|
|
||||||
@ -9272,6 +9354,10 @@ snapshots:
|
|||||||
|
|
||||||
'@types/picomatch@4.0.2': {}
|
'@types/picomatch@4.0.2': {}
|
||||||
|
|
||||||
|
'@types/qrcode@1.5.6':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 24.10.1
|
||||||
|
|
||||||
'@types/qs@6.14.0': {}
|
'@types/qs@6.14.0': {}
|
||||||
|
|
||||||
'@types/range-parser@1.2.7': {}
|
'@types/range-parser@1.2.7': {}
|
||||||
@ -9976,7 +10062,7 @@ snapshots:
|
|||||||
'@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3))
|
'@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3))
|
||||||
vue: 3.5.25(typescript@5.9.3)
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
|
||||||
'@vueuse/integrations@14.1.0(axios@1.13.2)(change-case@5.4.4)(focus-trap@7.6.6)(vue@3.5.25(typescript@5.9.3))':
|
'@vueuse/integrations@14.1.0(axios@1.13.2)(change-case@5.4.4)(focus-trap@7.6.6)(qrcode@1.5.4)(vue@3.5.25(typescript@5.9.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vueuse/core': 14.1.0(vue@3.5.25(typescript@5.9.3))
|
'@vueuse/core': 14.1.0(vue@3.5.25(typescript@5.9.3))
|
||||||
'@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3))
|
'@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3))
|
||||||
@ -9985,6 +10071,7 @@ snapshots:
|
|||||||
axios: 1.13.2
|
axios: 1.13.2
|
||||||
change-case: 5.4.4
|
change-case: 5.4.4
|
||||||
focus-trap: 7.6.6
|
focus-trap: 7.6.6
|
||||||
|
qrcode: 1.5.4
|
||||||
|
|
||||||
'@vueuse/metadata@14.1.0': {}
|
'@vueuse/metadata@14.1.0': {}
|
||||||
|
|
||||||
@ -10323,6 +10410,8 @@ snapshots:
|
|||||||
|
|
||||||
callsites@3.1.0: {}
|
callsites@3.1.0: {}
|
||||||
|
|
||||||
|
camelcase@5.3.1: {}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001733: {}
|
caniuse-lite@1.0.30001733: {}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001752: {}
|
caniuse-lite@1.0.30001752: {}
|
||||||
@ -10447,6 +10536,12 @@ snapshots:
|
|||||||
|
|
||||||
cli-width@3.0.0: {}
|
cli-width@3.0.0: {}
|
||||||
|
|
||||||
|
cliui@6.0.0:
|
||||||
|
dependencies:
|
||||||
|
string-width: 4.2.3
|
||||||
|
strip-ansi: 6.0.1
|
||||||
|
wrap-ansi: 6.2.0
|
||||||
|
|
||||||
cliui@8.0.1:
|
cliui@8.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
string-width: 4.2.3
|
string-width: 4.2.3
|
||||||
@ -10962,6 +11057,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
|
||||||
|
decamelize@1.2.0: {}
|
||||||
|
|
||||||
decode-named-character-reference@1.2.0:
|
decode-named-character-reference@1.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
character-entities: 2.0.2
|
character-entities: 2.0.2
|
||||||
@ -11017,6 +11114,8 @@ snapshots:
|
|||||||
|
|
||||||
diff@8.0.2: {}
|
diff@8.0.2: {}
|
||||||
|
|
||||||
|
dijkstrajs@1.0.3: {}
|
||||||
|
|
||||||
dir-glob@3.0.1:
|
dir-glob@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-type: 4.0.0
|
path-type: 4.0.0
|
||||||
@ -11649,6 +11748,11 @@ snapshots:
|
|||||||
|
|
||||||
find-up-simple@1.0.1: {}
|
find-up-simple@1.0.1: {}
|
||||||
|
|
||||||
|
find-up@4.1.0:
|
||||||
|
dependencies:
|
||||||
|
locate-path: 5.0.0
|
||||||
|
path-exists: 4.0.0
|
||||||
|
|
||||||
find-up@5.0.0:
|
find-up@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
locate-path: 6.0.0
|
locate-path: 6.0.0
|
||||||
@ -12621,6 +12725,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lie: 3.1.1
|
lie: 3.1.1
|
||||||
|
|
||||||
|
locate-path@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
p-locate: 4.1.0
|
||||||
|
|
||||||
locate-path@6.0.0:
|
locate-path@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-locate: 5.0.0
|
p-locate: 5.0.0
|
||||||
@ -13411,6 +13519,10 @@ snapshots:
|
|||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
safe-push-apply: 1.0.0
|
safe-push-apply: 1.0.0
|
||||||
|
|
||||||
|
p-limit@2.3.0:
|
||||||
|
dependencies:
|
||||||
|
p-try: 2.2.0
|
||||||
|
|
||||||
p-limit@3.1.0:
|
p-limit@3.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
yocto-queue: 0.1.0
|
yocto-queue: 0.1.0
|
||||||
@ -13419,6 +13531,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yocto-queue: 1.2.1
|
yocto-queue: 1.2.1
|
||||||
|
|
||||||
|
p-locate@4.1.0:
|
||||||
|
dependencies:
|
||||||
|
p-limit: 2.3.0
|
||||||
|
|
||||||
p-locate@5.0.0:
|
p-locate@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-limit: 3.1.0
|
p-limit: 3.1.0
|
||||||
@ -13431,6 +13547,8 @@ snapshots:
|
|||||||
|
|
||||||
p-map@7.0.4: {}
|
p-map@7.0.4: {}
|
||||||
|
|
||||||
|
p-try@2.2.0: {}
|
||||||
|
|
||||||
package-json-from-dist@1.0.1: {}
|
package-json-from-dist@1.0.1: {}
|
||||||
|
|
||||||
package-manager-detector@1.5.0: {}
|
package-manager-detector@1.5.0: {}
|
||||||
@ -13538,6 +13656,8 @@ snapshots:
|
|||||||
|
|
||||||
pluralize@8.0.0: {}
|
pluralize@8.0.0: {}
|
||||||
|
|
||||||
|
pngjs@5.0.0: {}
|
||||||
|
|
||||||
pnpm-workspace-yaml@1.3.0:
|
pnpm-workspace-yaml@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
yaml: 2.8.1
|
yaml: 2.8.1
|
||||||
@ -13637,6 +13757,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
hookified: 1.13.0
|
hookified: 1.13.0
|
||||||
|
|
||||||
|
qrcode@1.5.4:
|
||||||
|
dependencies:
|
||||||
|
dijkstrajs: 1.0.3
|
||||||
|
pngjs: 5.0.0
|
||||||
|
yargs: 15.4.1
|
||||||
|
|
||||||
qs@6.14.0:
|
qs@6.14.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
side-channel: 1.1.0
|
side-channel: 1.1.0
|
||||||
@ -13768,6 +13894,8 @@ snapshots:
|
|||||||
|
|
||||||
require-from-string@2.0.2: {}
|
require-from-string@2.0.2: {}
|
||||||
|
|
||||||
|
require-main-filename@2.0.0: {}
|
||||||
|
|
||||||
requires-port@1.0.0: {}
|
requires-port@1.0.0: {}
|
||||||
|
|
||||||
reserved-identifiers@1.2.0: {}
|
reserved-identifiers@1.2.0: {}
|
||||||
@ -14052,6 +14180,8 @@ snapshots:
|
|||||||
|
|
||||||
semver@7.7.3: {}
|
semver@7.7.3: {}
|
||||||
|
|
||||||
|
set-blocking@2.0.0: {}
|
||||||
|
|
||||||
set-function-length@1.2.2:
|
set-function-length@1.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
define-data-property: 1.1.4
|
define-data-property: 1.1.4
|
||||||
@ -14982,6 +15112,8 @@ snapshots:
|
|||||||
is-weakmap: 2.0.2
|
is-weakmap: 2.0.2
|
||||||
is-weakset: 2.0.4
|
is-weakset: 2.0.4
|
||||||
|
|
||||||
|
which-module@2.0.1: {}
|
||||||
|
|
||||||
which-typed-array@1.1.19:
|
which-typed-array@1.1.19:
|
||||||
dependencies:
|
dependencies:
|
||||||
available-typed-arrays: 1.0.7
|
available-typed-arrays: 1.0.7
|
||||||
@ -15011,6 +15143,12 @@ snapshots:
|
|||||||
|
|
||||||
wordwrap@1.0.0: {}
|
wordwrap@1.0.0: {}
|
||||||
|
|
||||||
|
wrap-ansi@6.2.0:
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: 4.3.0
|
||||||
|
string-width: 4.2.3
|
||||||
|
strip-ansi: 6.0.1
|
||||||
|
|
||||||
wrap-ansi@7.0.0:
|
wrap-ansi@7.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
@ -15040,6 +15178,8 @@ snapshots:
|
|||||||
|
|
||||||
xml-name-validator@4.0.0: {}
|
xml-name-validator@4.0.0: {}
|
||||||
|
|
||||||
|
y18n@4.0.3: {}
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
@ -15051,8 +15191,27 @@ snapshots:
|
|||||||
|
|
||||||
yaml@2.8.1: {}
|
yaml@2.8.1: {}
|
||||||
|
|
||||||
|
yargs-parser@18.1.3:
|
||||||
|
dependencies:
|
||||||
|
camelcase: 5.3.1
|
||||||
|
decamelize: 1.2.0
|
||||||
|
|
||||||
yargs-parser@21.1.1: {}
|
yargs-parser@21.1.1: {}
|
||||||
|
|
||||||
|
yargs@15.4.1:
|
||||||
|
dependencies:
|
||||||
|
cliui: 6.0.0
|
||||||
|
decamelize: 1.2.0
|
||||||
|
find-up: 4.1.0
|
||||||
|
get-caller-file: 2.0.5
|
||||||
|
require-directory: 2.1.1
|
||||||
|
require-main-filename: 2.0.0
|
||||||
|
set-blocking: 2.0.0
|
||||||
|
string-width: 4.2.3
|
||||||
|
which-module: 2.0.1
|
||||||
|
y18n: 4.0.3
|
||||||
|
yargs-parser: 18.1.3
|
||||||
|
|
||||||
yargs@17.7.2:
|
yargs@17.7.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
cliui: 8.0.1
|
cliui: 8.0.1
|
||||||
|
|||||||
@ -30,6 +30,7 @@ catalogs:
|
|||||||
'@types/minimist': ^1.2.5
|
'@types/minimist': ^1.2.5
|
||||||
'@types/node': ^24.10.1
|
'@types/node': ^24.10.1
|
||||||
'@types/picomatch': ^4.0.2
|
'@types/picomatch': ^4.0.2
|
||||||
|
'@types/qrcode': ^1.5.6
|
||||||
'@types/stylus': ^0.48.43
|
'@types/stylus': ^0.48.43
|
||||||
'@types/three': ^0.181.0
|
'@types/three': ^0.181.0
|
||||||
'@types/webpack-env': ^1.18.8
|
'@types/webpack-env': ^1.18.8
|
||||||
@ -118,6 +119,7 @@ catalogs:
|
|||||||
package-manager-detector: ^1.6.0
|
package-manager-detector: ^1.6.0
|
||||||
picocolors: ^1.1.1
|
picocolors: ^1.1.1
|
||||||
picomatch: ^4.0.3
|
picomatch: ^4.0.3
|
||||||
|
qrcode: ^1.5.4
|
||||||
shiki: ^3.17.0
|
shiki: ^3.17.0
|
||||||
sort-package-json: ^3.5.0
|
sort-package-json: ^3.5.0
|
||||||
tm-grammars: ^1.26.0
|
tm-grammars: ^1.26.0
|
||||||
|
|||||||
@ -64,6 +64,7 @@ export const MARKDOWN_POWER_FIELDS: (keyof MarkdownPowerPluginOptions)[] = [
|
|||||||
'collapse',
|
'collapse',
|
||||||
'chat',
|
'chat',
|
||||||
'youtube',
|
'youtube',
|
||||||
|
'qrcode',
|
||||||
]
|
]
|
||||||
|
|
||||||
export const MARKDOWN_SUPPORT_FIELDS: (keyof MarkdownOptions)[] = [
|
export const MARKDOWN_SUPPORT_FIELDS: (keyof MarkdownOptions)[] = [
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user