@fuxishi/vitepress-theme 2.0.0-alpha.1 → 2.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -9
- package/README_EN.md +140 -0
- package/dist/chunk/{FxCodeBlockFold-C7zqZ39g.js → FxCodeBlockFold-DGFv2bTG.js} +17 -17
- package/dist/chunk/{FxHeroImageBg-CiY3qciK.js → FxHeroImageBg-BWDDLukW.js} +77 -104
- package/dist/chunk/{FxMusicBall-DwxRT1yK.js → FxMusicBall-B2TF7Q7J.js} +69 -66
- package/dist/chunk/{icons-DtAsNqxj.js → icons-BLv72Cfw.js} +1 -1
- package/dist/config.d.ts +9 -4
- package/dist/config.js +126 -19
- package/dist/index.d.ts +14 -3
- package/dist/index.js +118 -53
- package/dist/style.css +1 -1
- package/package.json +24 -23
- /package/dist/chunk/{FxConfetti-DFRD5KKS.js → FxConfetti-C8bEZxL7.js} +0 -0
- /package/dist/chunk/{FxHomeFeatureBefore-Cd9m9wit.js → FxHomeFeatureBefore-BHzR4SeT.js} +0 -0
package/README.md
CHANGED
|
@@ -10,16 +10,14 @@
|
|
|
10
10
|
- 🎊 **点击彩纸** — 全局点击彩纸特效,支持金色星星、彩色纸片和自定义 Emoji
|
|
11
11
|
- 🎨 **Hero 图片取色** — 自动提取首页 hero 图片颜色,动态应用到背景光晕、标题渐变、代码块光束和音乐球
|
|
12
12
|
- ✨ **Feature 光效** — 首页 Feature 卡片鼠标追踪光晕效果
|
|
13
|
-
- ✨ **光束边框** —
|
|
13
|
+
- ✨ **光束边框** — 暗色模式下代码块、代码组和导航 hover 时展示紫青品牌色光束旋转边框
|
|
14
14
|
- 🔄 **主题切换动画** — View Transition API 实现亮暗模式圆形扩散动画
|
|
15
15
|
- 📜 **平滑滚动** — 右侧大纲导航点击时平滑滚动,指示条丝滑过渡
|
|
16
16
|
- 🎨 **标题装饰** — h1-h4 各有不同颜色的下划线装饰
|
|
17
17
|
- 📦 **代码块折叠** — 超过指定行数的代码块自动折叠,底部毛玻璃模糊遮罩,可配置折叠行数阈值
|
|
18
18
|
- ⚙️ **类型安全** — 完整的 TypeScript 类型定义,IDE 友好
|
|
19
19
|
|
|
20
|
-
> **注意:** `
|
|
21
|
-
>
|
|
22
|
-
> ⚠️ `1.0.10` 版本的代码块折叠展开功能存在问题,已废弃,请升级到 `1.0.11` 及以上版本。
|
|
20
|
+
> **注意:** 本版本(v2.x)基于 VitePress `2.0` 开发,不向下兼容 VitePress 1.x。
|
|
23
21
|
|
|
24
22
|
## 安装
|
|
25
23
|
|
|
@@ -51,11 +49,14 @@ export default FxTheme
|
|
|
51
49
|
创建 `.vitepress/config.mts`:
|
|
52
50
|
|
|
53
51
|
```ts
|
|
54
|
-
import {
|
|
52
|
+
import { defineConfig } from "vitepress"
|
|
53
|
+
import type { DefaultTheme } from "vitepress"
|
|
55
54
|
import fxConfig from "@fuxishi/vitepress-theme/config"
|
|
56
|
-
import type {
|
|
55
|
+
import type { FxThemeCustomConfig } from "@fuxishi/vitepress-theme"
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
type ThemeConfig = DefaultTheme.Config & FxThemeCustomConfig
|
|
58
|
+
|
|
59
|
+
export default defineConfig<ThemeConfig>({
|
|
59
60
|
extends: fxConfig,
|
|
60
61
|
lang: "zh-CN",
|
|
61
62
|
title: "我的文档站",
|
|
@@ -97,9 +98,9 @@ npx vitepress dev
|
|
|
97
98
|
|
|
98
99
|
## 配置
|
|
99
100
|
|
|
100
|
-
###
|
|
101
|
+
### FxThemeCustomConfig
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
通过 `DefaultTheme.Config & FxThemeCustomConfig` 交叉类型扩展 VitePress 默认主题配置,新增以下字段:
|
|
103
104
|
|
|
104
105
|
| 配置项 | 类型 | 默认值 | 说明 |
|
|
105
106
|
| --------------------- | --------------------------- | -------- | ------------------------------------------------------ |
|
package/README_EN.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @fuxishi/vitepress-theme
|
|
2
|
+
|
|
3
|
+
A beautiful VitePress theme extension with frosted glass effects, purple-blue gradients, rich animations, and ready to use.
|
|
4
|
+
|
|
5
|
+
[中文](./README.md)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🎵 **Floating Music Ball** — Frosted glass floating player with single/playlist mode, purple-blue gradient progress ring and four playback animations
|
|
10
|
+
- 🎊 **Click Confetti** — Global click confetti effect with gold stars, colored paper pieces, and custom Emoji
|
|
11
|
+
- 🎨 **Hero Image Color** — Auto-extract colors from hero image for background glow, title gradient, code block beams, and music ball
|
|
12
|
+
- ✨ **Feature Glow** — Mouse-tracking glow effect on homepage Feature cards
|
|
13
|
+
- ✨ **Beam Border** — Purple-cyan brand color beam border on code blocks, code groups, and navigation in dark mode on hover
|
|
14
|
+
- 🔄 **Theme Switch Animation** — Circular spread animation for light/dark mode switching using View Transition API
|
|
15
|
+
- 📜 **Smooth Scroll** — Smooth scrolling when clicking outline navigation with silky marker transition
|
|
16
|
+
- 🎨 **Heading Decorations** — Different colored underlines for h1-h4 headings
|
|
17
|
+
- 📦 **Code Block Fold** — Auto-fold code blocks exceeding a line threshold with frosted glass blur overlay, configurable fold line count
|
|
18
|
+
- ⚙️ **Type-safe** — Complete TypeScript type definitions, IDE friendly
|
|
19
|
+
|
|
20
|
+
> **Note:** This version (v2.x) is built on VitePress `2.0` and is not backward compatible with VitePress 1.x.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @fuxishi/vitepress-theme
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Install peerDependencies:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install vitepress
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### 1. Register Theme
|
|
37
|
+
|
|
38
|
+
Create `.vitepress/theme/index.ts`:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import FxTheme from "@fuxishi/vitepress-theme"
|
|
42
|
+
import "@fuxishi/vitepress-theme/style.css"
|
|
43
|
+
|
|
44
|
+
export default FxTheme
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Extend Configuration
|
|
48
|
+
|
|
49
|
+
Create `.vitepress/config.mts`:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { defineConfig } from "vitepress"
|
|
53
|
+
import type { DefaultTheme } from "vitepress"
|
|
54
|
+
import fxConfig from "@fuxishi/vitepress-theme/config"
|
|
55
|
+
import type { FxThemeCustomConfig } from "@fuxishi/vitepress-theme"
|
|
56
|
+
|
|
57
|
+
type ThemeConfig = DefaultTheme.Config & FxThemeCustomConfig
|
|
58
|
+
|
|
59
|
+
export default defineConfig<ThemeConfig>({
|
|
60
|
+
extends: fxConfig,
|
|
61
|
+
lang: "en",
|
|
62
|
+
title: "My Docs",
|
|
63
|
+
themeConfig: {
|
|
64
|
+
nav: [{ text: "Guide", link: "/guide/" }],
|
|
65
|
+
sidebar: {
|
|
66
|
+
"/guide/": [{ text: "Getting Started", link: "/guide/" }],
|
|
67
|
+
},
|
|
68
|
+
// Enable music ball
|
|
69
|
+
musicBall: {
|
|
70
|
+
enable: true,
|
|
71
|
+
autoplay: false,
|
|
72
|
+
loop: true,
|
|
73
|
+
src: "/music/my-song.mp3",
|
|
74
|
+
},
|
|
75
|
+
// Enable confetti
|
|
76
|
+
confetti: true,
|
|
77
|
+
// Colored paper pieces
|
|
78
|
+
// confetti: { shape: "colored-paper" },
|
|
79
|
+
// Custom Emoji
|
|
80
|
+
// confetti: { shapes: ["🌸", "🎀"] },
|
|
81
|
+
// Enable hero image color extraction
|
|
82
|
+
heroImageColor: true,
|
|
83
|
+
// Enable smooth scroll
|
|
84
|
+
smoothScroll: true,
|
|
85
|
+
// Code block fold (enabled by default, 10 lines threshold)
|
|
86
|
+
codeBlockFold: true,
|
|
87
|
+
// Custom fold line threshold
|
|
88
|
+
// codeBlockFold: { lines: 20 },
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Start Dev Server
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx vitepress dev
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Configuration
|
|
100
|
+
|
|
101
|
+
### FxThemeCustomConfig
|
|
102
|
+
|
|
103
|
+
Extends VitePress `DefaultTheme.Config` via intersection type `DefaultTheme.Config & FxThemeCustomConfig`, adding the following fields:
|
|
104
|
+
|
|
105
|
+
| Option | Type | Default | Description |
|
|
106
|
+
| --------------------- | --------------------------- | -------- | ----------------------------------------------------------------- |
|
|
107
|
+
| `musicBall.enable` | `boolean` | `true` | Enable music ball |
|
|
108
|
+
| `musicBall.visible` | `boolean` | `true` | Visibility |
|
|
109
|
+
| `musicBall.autoplay` | `boolean` | `false` | Autoplay |
|
|
110
|
+
| `musicBall.loop` | `boolean` | `true` | Loop playback (single mode) |
|
|
111
|
+
| `musicBall.src` | `string` | `''` | Single music URL |
|
|
112
|
+
| `musicBall.list` | `MusicItem[]` | — | Multi-song playlist |
|
|
113
|
+
| `confetti` | `boolean \| object` | `true` | Enable confetti |
|
|
114
|
+
| `confetti.shape` | `'star' \| 'colored-paper'` | `'star'` | Preset shape |
|
|
115
|
+
| `confetti.shapes` | `string \| string[]` | — | Custom Emoji shapes |
|
|
116
|
+
| `confetti.secondary` | `boolean` | `true` | Whether to add secondary particles |
|
|
117
|
+
| `heroImageColor` | `boolean` | `false` | Auto-extract hero image colors (affects glow, title, beams, ball) |
|
|
118
|
+
| `smoothScroll` | `boolean` | `false` | Enable smooth scrolling and outline marker transition |
|
|
119
|
+
| `codeBlockFold` | `boolean \| object` | `true` | Enable code block folding |
|
|
120
|
+
| `codeBlockFold.lines` | `number` | `10` | Line count threshold for folding |
|
|
121
|
+
|
|
122
|
+
## Exports
|
|
123
|
+
|
|
124
|
+
| Export Path | Description |
|
|
125
|
+
| ------------------------------------ | ---------------------------- |
|
|
126
|
+
| `@fuxishi/vitepress-theme` | Theme (Layout + Styles) |
|
|
127
|
+
| `@fuxishi/vitepress-theme/config` | VitePress base config preset |
|
|
128
|
+
| `@fuxishi/vitepress-theme/style.css` | Standalone style file |
|
|
129
|
+
|
|
130
|
+
## Documentation
|
|
131
|
+
|
|
132
|
+
Full documentation:
|
|
133
|
+
|
|
134
|
+
[https://fuxishi-vitepress-theme.fuxizjxzy.cn](https://fuxishi-vitepress-theme.fuxizjxzy.cn)
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
[MIT](./LICENSE)
|
|
139
|
+
|
|
140
|
+
> Will be open-sourced on GitHub in the future.
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { t as e } from "./icons-
|
|
1
|
+
import { t as e } from "./icons-BLv72Cfw.js";
|
|
2
2
|
import { defineComponent as t, nextTick as n, onBeforeUnmount as r, onMounted as i, watch as a } from "vue";
|
|
3
3
|
import { useRoute as o } from "vitepress";
|
|
4
4
|
//#region .vitepress/components/FxCodeBlockFold.ts
|
|
5
|
-
var s = "fx-code-folded", c = "fx-code-fold-overlay", l = t({
|
|
5
|
+
var s = "fx-code-folded", c = "fx-code-fold-overlay", l = "div[class*='language-']", u = t({
|
|
6
6
|
props: { lines: {
|
|
7
7
|
type: Number,
|
|
8
8
|
default: 10
|
|
9
9
|
} },
|
|
10
10
|
setup(t) {
|
|
11
|
-
function
|
|
11
|
+
function u() {
|
|
12
12
|
let n = t.lines ?? 10;
|
|
13
|
-
document.querySelectorAll(
|
|
13
|
+
document.querySelectorAll(l).forEach((t) => {
|
|
14
14
|
if (t.classList.contains(c) || t.classList.contains("vp-code-group")) return;
|
|
15
|
-
let r = t.querySelector("pre.
|
|
15
|
+
let r = t.querySelector("pre.shiki code");
|
|
16
16
|
if (!r) return;
|
|
17
17
|
if (r.querySelectorAll(".line").length <= n) {
|
|
18
18
|
t.classList.add("fx-code-no-fold");
|
|
@@ -29,29 +29,29 @@ var s = "fx-code-folded", c = "fx-code-fold-overlay", l = t({
|
|
|
29
29
|
}), t.appendChild(i);
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
let
|
|
33
|
-
function
|
|
34
|
-
|
|
32
|
+
let d = null;
|
|
33
|
+
function f() {
|
|
34
|
+
d?.disconnect();
|
|
35
35
|
let e = document.querySelector(".vp-doc");
|
|
36
|
-
e && (
|
|
37
|
-
requestAnimationFrame(
|
|
38
|
-
}),
|
|
36
|
+
e && (d = new MutationObserver(() => {
|
|
37
|
+
requestAnimationFrame(u);
|
|
38
|
+
}), d.observe(e, {
|
|
39
39
|
childList: !0,
|
|
40
40
|
subtree: !0
|
|
41
41
|
}));
|
|
42
42
|
}
|
|
43
43
|
i(() => {
|
|
44
|
-
|
|
44
|
+
u(), f();
|
|
45
45
|
});
|
|
46
|
-
let
|
|
47
|
-
return a(() =>
|
|
46
|
+
let p = o();
|
|
47
|
+
return a(() => p.path, () => {
|
|
48
48
|
n(() => {
|
|
49
|
-
|
|
49
|
+
u(), f();
|
|
50
50
|
});
|
|
51
51
|
}), r(() => {
|
|
52
|
-
|
|
52
|
+
d?.disconnect();
|
|
53
53
|
}), () => null;
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
//#endregion
|
|
57
|
-
export {
|
|
57
|
+
export { u as default };
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { defineComponent as e, nextTick as t, onBeforeUnmount as n, onMounted as r, watch as i } from "vue";
|
|
2
|
-
import { useData as a, useRoute as o } from "vitepress";
|
|
3
|
-
import { Vibrant as
|
|
2
|
+
import { useData as a, useRoute as o, withBase as s } from "vitepress";
|
|
3
|
+
import { Vibrant as c } from "node-vibrant/browser";
|
|
4
4
|
//#region .vitepress/components/FxHeroImageBg.ts
|
|
5
|
-
var
|
|
6
|
-
function
|
|
5
|
+
var l = "fx-hero-colors";
|
|
6
|
+
function u() {
|
|
7
7
|
try {
|
|
8
|
-
let e = localStorage.getItem(
|
|
8
|
+
let e = localStorage.getItem(l);
|
|
9
9
|
return e ? JSON.parse(e) : null;
|
|
10
10
|
} catch {
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function d(e) {
|
|
15
15
|
try {
|
|
16
|
-
localStorage.setItem(
|
|
16
|
+
localStorage.setItem(l, JSON.stringify(e));
|
|
17
17
|
} catch {}
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function f(e) {
|
|
20
20
|
return [
|
|
21
21
|
e.Vibrant,
|
|
22
22
|
e.DarkVibrant,
|
|
@@ -26,63 +26,63 @@ function d(e) {
|
|
|
26
26
|
e.LightMuted
|
|
27
27
|
].filter(Boolean);
|
|
28
28
|
}
|
|
29
|
-
function
|
|
29
|
+
function p(e) {
|
|
30
30
|
return e.slice().sort((e, t) => e.hsl[0] - t.hsl[0]).map((e) => e.hex);
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
let t =
|
|
32
|
+
function m(e) {
|
|
33
|
+
let t = f(e);
|
|
34
34
|
if (t.length === 0) return "-webkit-linear-gradient(-45deg, #bd34fe 50%, #47caff 50%)";
|
|
35
|
-
let n =
|
|
35
|
+
let n = p(t);
|
|
36
36
|
return `conic-gradient(from 0deg, ${[...n, n[0]].join(", ")})`;
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function h(e, t) {
|
|
39
39
|
let n = Math.abs(e - t);
|
|
40
40
|
return Math.min(n, 360 - n);
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
let t =
|
|
42
|
+
function g(e) {
|
|
43
|
+
let t = f(e);
|
|
44
44
|
if (t.length < 2) return "linear-gradient(120deg, #bd34fe, #41d1ff)";
|
|
45
45
|
let n = -1, r = [t[0].hex, t[1].hex];
|
|
46
46
|
for (let e = 0; e < t.length; e++) for (let i = e + 1; i < t.length; i++) {
|
|
47
|
-
let a =
|
|
47
|
+
let a = h(t[e].hsl[0], t[i].hsl[0]);
|
|
48
48
|
a > n && (n = a, r = [t[e].hex, t[i].hex]);
|
|
49
49
|
}
|
|
50
50
|
return `linear-gradient(120deg, ${r[0]}, ${r[1]})`;
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function _(e) {
|
|
53
53
|
return `${parseInt(e.slice(1, 3), 16)}, ${parseInt(e.slice(3, 5), 16)}, ${parseInt(e.slice(5, 7), 16)}`;
|
|
54
54
|
}
|
|
55
|
-
function
|
|
56
|
-
let t =
|
|
55
|
+
function v(e) {
|
|
56
|
+
let t = f(e);
|
|
57
57
|
if (t.length < 2) return ["189, 52, 254", "65, 209, 255"];
|
|
58
58
|
let n = -1, r = [t[0], t[1]];
|
|
59
59
|
for (let e = 0; e < t.length; e++) for (let i = e + 1; i < t.length; i++) {
|
|
60
|
-
let a =
|
|
60
|
+
let a = h(t[e].hsl[0], t[i].hsl[0]);
|
|
61
61
|
a > n && (n = a, r = [t[e], t[i]]);
|
|
62
62
|
}
|
|
63
|
-
return [
|
|
63
|
+
return [_(r[0].hex), _(r[1].hex)];
|
|
64
64
|
}
|
|
65
|
-
function
|
|
65
|
+
function y() {
|
|
66
66
|
return document.documentElement.classList.contains("dark");
|
|
67
67
|
}
|
|
68
|
-
function
|
|
69
|
-
let [t, n] =
|
|
68
|
+
function b(e) {
|
|
69
|
+
let [t, n] = v(e);
|
|
70
70
|
return {
|
|
71
|
-
imageGradient:
|
|
72
|
-
nameGradient:
|
|
71
|
+
imageGradient: m(e),
|
|
72
|
+
nameGradient: g(e),
|
|
73
73
|
beamC1: t,
|
|
74
74
|
beamC2: n
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
function
|
|
77
|
+
function x(e) {
|
|
78
78
|
let t = document.documentElement;
|
|
79
79
|
t.style.setProperty("--vp-home-hero-image-background-image", e.imageGradient), t.style.setProperty("--vp-home-hero-name-background", e.nameGradient), t.style.setProperty("--fx-beam-c1", e.beamC1), t.style.setProperty("--fx-beam-c2", e.beamC2);
|
|
80
80
|
}
|
|
81
|
-
function
|
|
81
|
+
function S(e) {
|
|
82
82
|
let t = document.documentElement;
|
|
83
83
|
t.style.setProperty("--fx-beam-c1", e.beamC1), t.style.setProperty("--fx-beam-c2", e.beamC2);
|
|
84
84
|
}
|
|
85
|
-
var
|
|
85
|
+
var C = e({
|
|
86
86
|
props: { heroImageColor: {
|
|
87
87
|
type: Boolean,
|
|
88
88
|
default: !1
|
|
@@ -90,127 +90,100 @@ var S = e({
|
|
|
90
90
|
render: () => null,
|
|
91
91
|
setup(e) {
|
|
92
92
|
if (!e.heroImageColor) return;
|
|
93
|
-
let
|
|
94
|
-
function
|
|
93
|
+
let f = null, p = o(), { frontmatter: m, site: h } = a();
|
|
94
|
+
function g() {
|
|
95
95
|
let e = document.documentElement;
|
|
96
96
|
e.style.removeProperty("--vp-home-hero-image-background-image"), e.style.removeProperty("--vp-home-hero-name-background"), e.style.removeProperty("--fx-beam-c1"), e.style.removeProperty("--fx-beam-c2");
|
|
97
97
|
}
|
|
98
|
-
function
|
|
99
|
-
return
|
|
98
|
+
function _(e) {
|
|
99
|
+
return y() ? e.dark || e.light : e.light || e.dark;
|
|
100
100
|
}
|
|
101
|
-
function
|
|
102
|
-
let t =
|
|
103
|
-
return !t || !t.images ? !1 : e && (e.light && t.images.light && e.light !== t.images.light || e.dark && t.images.dark && e.dark !== t.images.dark) ? (localStorage.removeItem(
|
|
101
|
+
function v(e) {
|
|
102
|
+
let t = u();
|
|
103
|
+
return !t || !t.images ? !1 : e && (e.light && t.images.light && e.light !== t.images.light || e.dark && t.images.dark && e.dark !== t.images.dark) ? (localStorage.removeItem(l), !0) : !1;
|
|
104
104
|
}
|
|
105
|
-
function
|
|
106
|
-
let e =
|
|
107
|
-
if (!e) return !1;
|
|
108
|
-
let t = h(e);
|
|
109
|
-
return t ? (b(t), !0) : !1;
|
|
110
|
-
}
|
|
111
|
-
function S() {
|
|
112
|
-
let e = l();
|
|
105
|
+
function C() {
|
|
106
|
+
let e = u();
|
|
113
107
|
if (!e) return !1;
|
|
114
|
-
let t =
|
|
108
|
+
let t = _(e);
|
|
115
109
|
return t ? (x(t), !0) : !1;
|
|
116
110
|
}
|
|
117
|
-
function
|
|
118
|
-
|
|
111
|
+
function w() {
|
|
112
|
+
let e = u();
|
|
113
|
+
if (!e) return !1;
|
|
114
|
+
let t = _(e);
|
|
115
|
+
return t ? (S(t), !0) : !1;
|
|
119
116
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
let e = await import(
|
|
123
|
-
/* @vite-ignore */
|
|
124
|
-
"/index.md"
|
|
125
|
-
), t = (typeof e.__pageData == "string" ? JSON.parse(e.__pageData) : e.__pageData)?.frontmatter?.hero?.image;
|
|
126
|
-
return t ? typeof t == "string" ? {
|
|
127
|
-
light: t,
|
|
128
|
-
dark: t
|
|
129
|
-
} : {
|
|
130
|
-
light: t.light,
|
|
131
|
-
dark: t.dark
|
|
132
|
-
} : null;
|
|
133
|
-
} catch {
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
117
|
+
function T() {
|
|
118
|
+
return m.value.fxHeroImages || {};
|
|
136
119
|
}
|
|
137
|
-
async function
|
|
120
|
+
async function E(e, t) {
|
|
138
121
|
let n = e.src;
|
|
139
122
|
if (n) try {
|
|
140
|
-
let e =
|
|
141
|
-
(
|
|
142
|
-
let r =
|
|
143
|
-
r[t] = e, r.images ||= {}, r.images[t] = n,
|
|
123
|
+
let e = b(await c.from(n).quality(1).getPalette());
|
|
124
|
+
(y() && t === "dark" || !y() && t === "light") && x(e);
|
|
125
|
+
let r = u() || {};
|
|
126
|
+
r[t] = e, r.images ||= {}, r.images[t] = n, d(r);
|
|
144
127
|
} catch {}
|
|
145
128
|
}
|
|
146
|
-
async function
|
|
129
|
+
async function D(e, t) {
|
|
147
130
|
try {
|
|
148
|
-
let n =
|
|
149
|
-
return r[t] = n, r.images ||= {}, r.images[t] = e,
|
|
131
|
+
let n = b(await c.from(e).quality(1).getPalette()), r = u() || {};
|
|
132
|
+
return r[t] = n, r.images ||= {}, r.images[t] = e, d(r), n;
|
|
150
133
|
} catch {
|
|
151
134
|
return null;
|
|
152
135
|
}
|
|
153
136
|
}
|
|
154
|
-
async function
|
|
137
|
+
async function O(e, t = !0) {
|
|
155
138
|
if (!e.light && !e.dark) return;
|
|
156
|
-
let
|
|
139
|
+
let n = {};
|
|
157
140
|
if (e.light) {
|
|
158
|
-
let
|
|
159
|
-
|
|
141
|
+
let r = await D(t ? s(e.light) : e.light, "light");
|
|
142
|
+
r && (n.light = r);
|
|
160
143
|
}
|
|
161
144
|
if (e.dark) {
|
|
162
|
-
let
|
|
163
|
-
|
|
145
|
+
let r = await D(t ? s(e.dark) : e.dark, "dark");
|
|
146
|
+
r && (n.dark = r);
|
|
164
147
|
}
|
|
165
|
-
if (
|
|
166
|
-
let e =
|
|
167
|
-
e &&
|
|
148
|
+
if (n.light || n.dark) {
|
|
149
|
+
let e = y() ? n.dark || n.light : n.light || n.dark;
|
|
150
|
+
e && x(e);
|
|
168
151
|
}
|
|
169
152
|
}
|
|
170
|
-
async function
|
|
171
|
-
let e =
|
|
153
|
+
async function k() {
|
|
154
|
+
let e = T();
|
|
172
155
|
if (e.light || e.dark) {
|
|
173
|
-
await
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
let t = await w();
|
|
177
|
-
if (t) {
|
|
178
|
-
await D(t);
|
|
156
|
+
await O(e);
|
|
179
157
|
return;
|
|
180
158
|
}
|
|
181
159
|
try {
|
|
182
|
-
let e = await (await fetch(window.location.origin +
|
|
160
|
+
let e = await (await fetch(window.location.origin + h.value.base)).text(), t = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".VPHero .image-container img.VPImage"), n = {};
|
|
183
161
|
t.forEach((e) => {
|
|
184
162
|
let t = e.getAttribute("src");
|
|
185
163
|
t && (e.classList.contains("dark") ? n.dark = t : n.light = t);
|
|
186
|
-
}), (n.light || n.dark) && await
|
|
164
|
+
}), (n.light || n.dark) && await O(n, !1);
|
|
187
165
|
} catch {}
|
|
188
166
|
}
|
|
189
|
-
function
|
|
167
|
+
function A() {
|
|
190
168
|
let e = document.querySelector(".VPHero .image-container img.VPImage.light"), t = document.querySelector(".VPHero .image-container img.VPImage.dark");
|
|
191
|
-
e || t ? (e && e.complete && e.naturalWidth > 0 ?
|
|
192
|
-
if (e && (e.light || e.dark)) {
|
|
193
|
-
let t = l();
|
|
194
|
-
t?.images && (e.light && t.images.light && e.light !== t.images.light || e.dark && t.images.dark && e.dark !== t.images.dark) && (localStorage.removeItem(c), D(e));
|
|
195
|
-
}
|
|
196
|
-
}), O());
|
|
169
|
+
e || t ? (e && e.complete && e.naturalWidth > 0 ? E(e, "light") : e && e.addEventListener("load", () => E(e, "light"), { once: !0 }), t && t.complete && t.naturalWidth > 0 ? E(t, "dark") : t && t.addEventListener("load", () => E(t, "dark"), { once: !0 })) : (g(), w(), k());
|
|
197
170
|
}
|
|
198
171
|
r(() => {
|
|
199
|
-
|
|
172
|
+
v(T()), C() || k(), A(), f = new MutationObserver((e) => {
|
|
200
173
|
for (let t of e) if (t.attributeName === "class") {
|
|
201
|
-
|
|
174
|
+
w(), A();
|
|
202
175
|
break;
|
|
203
176
|
}
|
|
204
|
-
}),
|
|
177
|
+
}), f.observe(document.documentElement, {
|
|
205
178
|
attributes: !0,
|
|
206
179
|
attributeFilter: ["class"]
|
|
207
180
|
});
|
|
208
|
-
}), i(() =>
|
|
209
|
-
t(
|
|
181
|
+
}), i(() => p.path, () => {
|
|
182
|
+
t(A);
|
|
210
183
|
}), n(() => {
|
|
211
|
-
|
|
184
|
+
f?.disconnect(), g();
|
|
212
185
|
});
|
|
213
186
|
}
|
|
214
187
|
});
|
|
215
188
|
//#endregion
|
|
216
|
-
export {
|
|
189
|
+
export { C as default };
|