yuwen
2025-11-13 3b79071bbb1be6a7cc8a4c98f23debea5c9fce4a
feat: Add loading SVG icon and integrate Iconify for dynamic icon management

- Integrated Iconify plugin into the main application for icon management.
- Created a new plugin to automatically generate Iconify JSON from SVG files.
- Implemented a watcher to regenerate icons on file changes during development.
- Added a build validator plugin to ensure icons are generated and TypeScript checks are passed before build.
- Updated Vite configuration to include the new plugins.
修改5個檔案
新增7個檔案
1245 ■■■■■ 已變更過的檔案
.gitignore 4 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
docs/icon-setup.md 208 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
package-lock.json 798 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
package.json 3 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
src/assets/icons/colored/redmine.svg 13 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
src/assets/icons/example/loading.svg 4 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
src/main.ts 2 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
src/plugins/icons/index.ts 9 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
vite-plugins/auto-generate-icon/generateIconifyJson.ts 97 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
vite-plugins/auto-generate-icon/index.ts 55 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
vite-plugins/build-validator/index.ts 47 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
vite.config.ts 5 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
.gitignore
@@ -37,3 +37,7 @@
test-results/
playwright-report/
# Icon integration files
iconifyIcons.auto.json
icons.auto.ts
docs/icon-setup.md
比對新檔案
@@ -0,0 +1,208 @@
# Iconify 圖標整合指南
本專案提供自動化的流程來處理並載入 SVG 圖標,將其轉換為 `Iconify JSON` 格式,並在 Vue 應用中使用。以下是專案中與圖標相關的設置和流程說明。
---
## 基本設定方法
### 1. 在 vite.config.ts 中引入 Vite 插件
要啟用圖標自動生成功能,需要在 `vite.config.ts` 中加入 autoGenerateIcon 插件和 buildValidator 插件:
```typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import autoGenerateIcon from './vite-plugins/auto-generate-icon'
import buildValidator from './vite-plugins/build-validator'
// ...其他引入
export default defineConfig({
  plugins: [
    vue(),
    autoGenerateIcon(),
    buildValidator(),
    // ...其他插件
  ],
  // ...其他配置
})
```
> **說明**:
>
> - `autoGenerateIcon`: 在開發模式下監聽 SVG 圖標變化並自動生成 Iconify JSON
> - `buildValidator`: 在建置階段確保圖標檔案已更新並進行類型檢查
### 2. 在 main.ts 中引入圖標插件
要在 Vue 應用中使用生成的圖標,需要在 `main.ts` 中引入並使用圖標插件:
```typescript
import { createApp } from 'vue'
import App from './App.vue'
import iconifyPlugin from '@/plugins/icons'
// ...其他引入
const app = createApp(App)
app.use(iconifyPlugin)
// ...其他設定
app.mount('#app')
```
### 3. 在組件中使用圖標
安裝完成後,您可以在任何 Vue 組件中使用 `<Icon />` 組件來顯示圖標:
```vue
<script setup lang="ts">
import { Icon } from '@iconify/vue'
</script>
<template>
  <Icon icon="example-loading" class="h-6 w-6" />
</template>
```
> **型別安全**:專案透過 TypeScript 模組擴展自動約束 `icon` 屬性必須是專案中定義的圖標名稱,提供完整的型別檢查和自動補全支援。
---
## 檔案介紹
### Vite 插件(建置與開發階段)
這些插件位於 `/vite-plugins` 目錄,用於處理圖標的自動化生成流程:
- **Icon 生成器** (`/vite-plugins/auto-generate-icon/generateIconifyJson.ts`):
  核心功能模組,負責掃描 SVG 檔案並轉換為 Iconify JSON 格式。
- **開發環境監控插件** (`/vite-plugins/auto-generate-icon/index.ts`):
  在開發模式下監聽圖標變化並自動重新生成。
- **建置檢查插件** (`/vite-plugins/build-validator/index.ts`):
  在建置階段確保圖標是最新的並進行類型檢查。
### 前端應用插件(執行階段)
這些檔案位於 `/src` 目錄,用於在前端應用中載入和使用圖標:
- **圖標整合模組** (`/src/plugins/icons/index.ts`):
  負責在 Vue 應用中註冊 Iconify 圖標集合。
- **應用入口** (`/src/main.ts`):
  在應用啟動時載入圖標插件。
### 自動生成的檔案
這些檔案由系統自動產生,不應手動編輯:
- **圖標資料檔** (`/src/assets/icons/iconifyIcons.auto.json`):
  包含所有圖標的 JSON 資料。
- **類型定義檔** (`/src/types/icons.auto.ts`):
  提供圖標名稱的 TypeScript 型別定義,並透過模組擴展自動約束 `@iconify/vue` 的 `Icon` 元件型別。
## 圖標轉換流程
整個圖標系統的工作流程分為三個主要階段:
1. **圖標生成階段**:
   由**Icon 生成器**負責將 SVG 檔案轉換為 Iconify JSON 格式,自動處理檔案名稱正規化和顏色設定。
2. **自動化觸發階段**:
   - 開發時:**開發環境監控插件**實時監控圖標變化並自動觸發更新
   - 建置時:**建置檢查插件**確保所有圖標已更新且沒有類型錯誤
3. **前端應用階段**:
   **圖標整合模組**在 Vue 應用啟動時註冊所有圖標,開發者可直接從 `@iconify/vue` 引入 `Icon` 元件並使用,型別系統會自動檢查圖標名稱的正確性。
## 專案插件說明
### Vite 插件
專案使用兩個 Vite 插件來確保圖標系統的自動化運作:
#### 1. **開發環境監控插件** (`autoGenerateIcon`)
此插件在開發模式下運行,實現以下功能:
- 監聽 SVG 文件的變化(新增、修改、刪除)
- 使用去抖動技術避免頻繁更新
- 自動執行 Icon 生成器
- 自動刷新開發伺服器
#### 2. **建置檢查插件** (`buildValidator`)
此插件在建置階段運行,執行以下任務:
- 確保所有圖標已更新至最新狀態
- 進行 Vue TypeScript 類型檢查
- 在發現錯誤時中斷建置並提供明確錯誤信息
### 前端圖標插件
**圖標整合模組**在 Vue 應用中啟用 Iconify 圖標系統:
- 透過 `@iconify/vue` 的 `addCollection` 註冊圖標集合
- 確保所有自定義圖標在應用中可用
- 配合 TypeScript 模組擴展,提供完整的型別安全和自動補全支援
## 圖標名稱
在生成 Iconify JSON 的過程中,圖標的 `name` 是根據其檔案路徑及資料夾結構來自動生成的。這樣的命名方式使得圖標在應用中更具可讀性和一致性。命名原則如下:
### 命名格式:`<folder-name>-<file-name>`
- `<folder-name>`:包含 SVG 檔案的資料夾名稱。這樣有助於組織圖標並進一步區分圖標類別。
- `<file-name>`:圖標文件名稱,不含檔案後綴,且會轉換為小寫並用破折號 (`-`) 連接。
### 例子
- 如果 `abc.svg` 文件位於 `/src/assets/icons/mps/` 資料夾下,則其生成的 `name` 會是 `mps-abc`。
- 如果 `def.svg` 文件位於 `/src/assets/icons/` 資料夾下,則其生成的 `name` 會是 `def`。
- 如果 `xyz_abc.svg` 文件位於 `/src/assets/icons/colored/` 資料夾下,則其生成的 `name` 會是 `colored-xyz-abc`。
這樣的命名規則使得每個圖標的名稱都可以清楚地反映其所屬的資料夾及用途,並有助於管理和維護。
## 自動生成的型別支援
在生成 Iconify JSON 的同時,模組亦自動生成一個 TypeScript 型別檔案,描述所有圖標名稱,為開發者提供更好的型別支援和自動補全功能。
### 型別檔案位置
- **檔案名稱**:`icons.auto.ts`
- **存放路徑**:`/src/types`
此檔案會導出一個名為 `GeneratedIconNames` 的型別,列出所有已生成的圖標名稱。
### 型別結構
範例:
```typescript
export type GeneratedIconNames = 'mps-abc' | 'colored-xyz-abc' | 'def'
// 擴展 @iconify/vue 的 Icon 元件型別
declare module '@iconify/vue' {
  export interface IconProps {
    icon: GeneratedIconNames
  }
}
```
此型別檔案透過 TypeScript 模組擴展功能,自動約束從 `@iconify/vue` 引入的 `Icon` 元件的 `icon` 屬性必須是專案中定義的圖標名稱。
# 注意事項
- **自動生成檔案不可手動編輯**:
  `iconifyIcons.auto.json` 和 `icons.auto.ts` 檔案由系統自動生成,任何手動修改將在下次生成時被覆蓋。這些檔案已加入 `.gitignore`,不會被版本控制系統追蹤。
- **顏色處理特殊規則**:
  位於 `/src/assets/icons/colored/` 資料夾的 SVG 文件將保留原始顏色,不會被轉換為 `currentColor`,適合用於多色圖標。
- **圖標命名規範**:
  圖標檔名必須符合 Iconify 規範(僅允許小寫字母 a-z、數字和連字符 `-`)。更多資訊請參閱 [Iconify 圖標命名規則](https://iconify.design/docs/icons/icon-basics.html#icon-names)。
- **更多參考資料**:
  完整的 Iconify 文件可在[官方網站](https://iconify.design/)查閱。
package-lock.json
@@ -8,6 +8,8 @@
      "name": "vue-project",
      "version": "0.0.0",
      "dependencies": {
        "@iconify/tools": "^4.1.4",
        "@iconify/vue": "^5.0.0",
        "@tailwindcss/vite": "^4.1.16",
        "axios": "^1.13.2",
        "pinia": "^3.0.3",
@@ -32,6 +34,7 @@
        "@vue/eslint-config-typescript": "^14.6.0",
        "@vue/test-utils": "^2.4.6",
        "@vue/tsconfig": "^0.8.1",
        "chokidar": "^4.0.3",
        "eslint": "^9.37.0",
        "eslint-plugin-playwright": "^2.2.2",
        "eslint-plugin-vue": "~10.5.0",
@@ -66,6 +69,37 @@
      "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/@antfu/install-pkg": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
      "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
      "license": "MIT",
      "dependencies": {
        "package-manager-detector": "^1.3.0",
        "tinyexec": "^1.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/@antfu/install-pkg/node_modules/tinyexec": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
      "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
      "license": "MIT",
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@antfu/utils": {
      "version": "8.1.1",
      "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz",
      "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==",
      "license": "MIT",
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/@asamuzakjp/css-color": {
      "version": "4.0.5",
@@ -1372,6 +1406,114 @@
        "url": "https://github.com/sponsors/nzakas"
      }
    },
    "node_modules/@iconify/tools": {
      "version": "4.1.4",
      "resolved": "https://registry.npmjs.org/@iconify/tools/-/tools-4.1.4.tgz",
      "integrity": "sha512-s6BcNUcCxQ3S6cvhlsoWzOuBt8qKXdVyXB9rT57uSJ/ARHD7dVM43+5ERBWn3tmkMWXeJ/s9DPVc3dUasayzeA==",
      "license": "MIT",
      "dependencies": {
        "@iconify/types": "^2.0.0",
        "@iconify/utils": "^2.3.0",
        "@types/tar": "^6.1.13",
        "axios": "^1.12.1",
        "cheerio": "1.0.0",
        "domhandler": "^5.0.3",
        "extract-zip": "^2.0.1",
        "local-pkg": "^0.5.1",
        "pathe": "^1.1.2",
        "svgo": "^3.3.2",
        "tar": "^6.2.1"
      }
    },
    "node_modules/@iconify/tools/node_modules/pathe": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
      "license": "MIT"
    },
    "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==",
      "license": "MIT"
    },
    "node_modules/@iconify/utils": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz",
      "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==",
      "license": "MIT",
      "dependencies": {
        "@antfu/install-pkg": "^1.0.0",
        "@antfu/utils": "^8.1.0",
        "@iconify/types": "^2.0.0",
        "debug": "^4.4.0",
        "globals": "^15.14.0",
        "kolorist": "^1.8.0",
        "local-pkg": "^1.0.0",
        "mlly": "^1.7.4"
      }
    },
    "node_modules/@iconify/utils/node_modules/confbox": {
      "version": "0.2.2",
      "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
      "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
      "license": "MIT"
    },
    "node_modules/@iconify/utils/node_modules/globals": {
      "version": "15.15.0",
      "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
      "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
      "license": "MIT",
      "engines": {
        "node": ">=18"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/@iconify/utils/node_modules/local-pkg": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
      "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
      "license": "MIT",
      "dependencies": {
        "mlly": "^1.7.4",
        "pkg-types": "^2.3.0",
        "quansync": "^0.2.11"
      },
      "engines": {
        "node": ">=14"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/@iconify/utils/node_modules/pkg-types": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
      "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
      "license": "MIT",
      "dependencies": {
        "confbox": "^0.2.2",
        "exsolve": "^1.0.7",
        "pathe": "^2.0.3"
      }
    },
    "node_modules/@iconify/vue": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/@iconify/vue/-/vue-5.0.0.tgz",
      "integrity": "sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg==",
      "license": "MIT",
      "dependencies": {
        "@iconify/types": "^2.0.0"
      },
      "funding": {
        "url": "https://github.com/sponsors/cyberalien"
      },
      "peerDependencies": {
        "vue": ">=3"
      }
    },
    "node_modules/@inquirer/ansi": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz",
@@ -2397,6 +2539,15 @@
        "deep-equal": "^2.0.5"
      }
    },
    "node_modules/@trysound/sax": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
      "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
      "license": "ISC",
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/@tsconfig/node22": {
      "version": "22.0.2",
      "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.2.tgz",
@@ -2458,7 +2609,6 @@
      "version": "22.19.1",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
      "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
      "devOptional": true,
      "license": "MIT",
      "dependencies": {
        "undici-types": "~6.21.0"
@@ -2471,12 +2621,41 @@
      "dev": true,
      "license": "MIT"
    },
    "node_modules/@types/tar": {
      "version": "6.1.13",
      "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.13.tgz",
      "integrity": "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==",
      "license": "MIT",
      "dependencies": {
        "@types/node": "*",
        "minipass": "^4.0.0"
      }
    },
    "node_modules/@types/tar/node_modules/minipass": {
      "version": "4.2.8",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
      "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
      "license": "ISC",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/@types/tough-cookie": {
      "version": "4.0.5",
      "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
      "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/@types/yauzl": {
      "version": "2.10.3",
      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
      "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
      "license": "MIT",
      "optional": true,
      "dependencies": {
        "@types/node": "*"
      }
    },
    "node_modules/@typescript-eslint/eslint-plugin": {
      "version": "8.46.4",
@@ -3342,7 +3521,6 @@
      "version": "8.15.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
      "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
      "dev": true,
      "license": "MIT",
      "peer": true,
      "bin": {
@@ -3565,7 +3743,6 @@
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
      "dev": true,
      "license": "ISC"
    },
    "node_modules/brace-expansion": {
@@ -3624,6 +3801,15 @@
      },
      "engines": {
        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
      }
    },
    "node_modules/buffer-crc32": {
      "version": "0.2.13",
      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
      "license": "MIT",
      "engines": {
        "node": "*"
      }
    },
    "node_modules/bundle-name": {
@@ -3774,6 +3960,73 @@
      "license": "MIT",
      "engines": {
        "node": ">= 16"
      }
    },
    "node_modules/cheerio": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
      "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
      "license": "MIT",
      "dependencies": {
        "cheerio-select": "^2.1.0",
        "dom-serializer": "^2.0.0",
        "domhandler": "^5.0.3",
        "domutils": "^3.1.0",
        "encoding-sniffer": "^0.2.0",
        "htmlparser2": "^9.1.0",
        "parse5": "^7.1.2",
        "parse5-htmlparser2-tree-adapter": "^7.0.0",
        "parse5-parser-stream": "^7.1.2",
        "undici": "^6.19.5",
        "whatwg-mimetype": "^4.0.0"
      },
      "engines": {
        "node": ">=18.17"
      },
      "funding": {
        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
      }
    },
    "node_modules/cheerio-select": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
      "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
      "license": "BSD-2-Clause",
      "dependencies": {
        "boolbase": "^1.0.0",
        "css-select": "^5.1.0",
        "css-what": "^6.1.0",
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.3",
        "domutils": "^3.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/chokidar": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "readdirp": "^4.0.1"
      },
      "engines": {
        "node": ">= 14.16.0"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/chownr": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
      "license": "ISC",
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/cli-cursor": {
@@ -3970,6 +4223,12 @@
      "dev": true,
      "license": "MIT"
    },
    "node_modules/confbox": {
      "version": "0.1.8",
      "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
      "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
      "license": "MIT"
    },
    "node_modules/config-chain": {
      "version": "1.1.13",
      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
@@ -4028,6 +4287,22 @@
        "node": ">= 8"
      }
    },
    "node_modules/css-select": {
      "version": "5.2.2",
      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
      "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
      "license": "BSD-2-Clause",
      "dependencies": {
        "boolbase": "^1.0.0",
        "css-what": "^6.1.0",
        "domhandler": "^5.0.2",
        "domutils": "^3.0.1",
        "nth-check": "^2.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/css-tree": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
@@ -4040,6 +4315,18 @@
      },
      "engines": {
        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
      }
    },
    "node_modules/css-what": {
      "version": "6.2.2",
      "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
      "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
      "license": "BSD-2-Clause",
      "engines": {
        "node": ">= 6"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/css.escape": {
@@ -4061,6 +4348,39 @@
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/csso": {
      "version": "5.0.5",
      "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
      "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
      "license": "MIT",
      "dependencies": {
        "css-tree": "~2.2.0"
      },
      "engines": {
        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/csso/node_modules/css-tree": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
      "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
      "license": "MIT",
      "dependencies": {
        "mdn-data": "2.0.28",
        "source-map-js": "^1.0.1"
      },
      "engines": {
        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/csso/node_modules/mdn-data": {
      "version": "2.0.28",
      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
      "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
      "license": "CC0-1.0"
    },
    "node_modules/cssstyle": {
      "version": "5.3.3",
@@ -4101,7 +4421,6 @@
      "version": "4.4.3",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "ms": "^2.1.3"
@@ -4286,6 +4605,61 @@
      "dev": true,
      "license": "MIT"
    },
    "node_modules/dom-serializer": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
      "license": "MIT",
      "dependencies": {
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.2",
        "entities": "^4.2.0"
      },
      "funding": {
        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
      }
    },
    "node_modules/domelementtype": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/fb55"
        }
      ],
      "license": "BSD-2-Clause"
    },
    "node_modules/domhandler": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
      "license": "BSD-2-Clause",
      "dependencies": {
        "domelementtype": "^2.3.0"
      },
      "engines": {
        "node": ">= 4"
      },
      "funding": {
        "url": "https://github.com/fb55/domhandler?sponsor=1"
      }
    },
    "node_modules/domutils": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
      "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
      "license": "BSD-2-Clause",
      "dependencies": {
        "dom-serializer": "^2.0.0",
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.3"
      },
      "funding": {
        "url": "https://github.com/fb55/domutils?sponsor=1"
      }
    },
    "node_modules/dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -4368,6 +4742,28 @@
      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/encoding-sniffer": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
      "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
      "license": "MIT",
      "dependencies": {
        "iconv-lite": "^0.6.3",
        "whatwg-encoding": "^3.1.1"
      },
      "funding": {
        "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
      }
    },
    "node_modules/end-of-stream": {
      "version": "1.4.5",
      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
      "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
      "license": "MIT",
      "dependencies": {
        "once": "^1.4.0"
      }
    },
    "node_modules/enhanced-resolve": {
      "version": "5.18.3",
@@ -4905,6 +5301,32 @@
        "node": ">=12.0.0"
      }
    },
    "node_modules/exsolve": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
      "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
      "license": "MIT"
    },
    "node_modules/extract-zip": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
      "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
      "license": "BSD-2-Clause",
      "dependencies": {
        "debug": "^4.1.1",
        "get-stream": "^5.1.0",
        "yauzl": "^2.10.0"
      },
      "bin": {
        "extract-zip": "cli.js"
      },
      "engines": {
        "node": ">= 10.17.0"
      },
      "optionalDependencies": {
        "@types/yauzl": "^2.9.1"
      }
    },
    "node_modules/fast-deep-equal": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4971,6 +5393,15 @@
      "license": "ISC",
      "dependencies": {
        "reusify": "^1.0.4"
      }
    },
    "node_modules/fd-slicer": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
      "license": "MIT",
      "dependencies": {
        "pend": "~1.2.0"
      }
    },
    "node_modules/file-entry-cache": {
@@ -5106,6 +5537,36 @@
        "node": ">= 6"
      }
    },
    "node_modules/fs-minipass": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
      "license": "ISC",
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/fs-minipass/node_modules/minipass": {
      "version": "3.3.6",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
      "license": "ISC",
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/fs-minipass/node_modules/yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
      "license": "ISC"
    },
    "node_modules/fsevents": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -5207,6 +5668,21 @@
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/get-stream": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
      "license": "MIT",
      "dependencies": {
        "pump": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/glob": {
@@ -5392,6 +5868,25 @@
        "node": ">=18"
      }
    },
    "node_modules/htmlparser2": {
      "version": "9.1.0",
      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
      "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
      "funding": [
        "https://github.com/fb55/htmlparser2?sponsor=1",
        {
          "type": "github",
          "url": "https://github.com/sponsors/fb55"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.3",
        "domutils": "^3.1.0",
        "entities": "^4.5.0"
      }
    },
    "node_modules/http-proxy-agent": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -5440,7 +5935,6 @@
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -6123,7 +6617,6 @@
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
      "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/levn": {
@@ -6498,6 +6991,22 @@
        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
      }
    },
    "node_modules/local-pkg": {
      "version": "0.5.1",
      "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz",
      "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==",
      "license": "MIT",
      "dependencies": {
        "mlly": "^1.7.3",
        "pkg-types": "^1.2.1"
      },
      "engines": {
        "node": ">=14"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/locate-path": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -6752,11 +7261,66 @@
        "node": ">=16 || 14 >=14.17"
      }
    },
    "node_modules/minizlib": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
      "license": "MIT",
      "dependencies": {
        "minipass": "^3.0.0",
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/minizlib/node_modules/minipass": {
      "version": "3.3.6",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
      "license": "ISC",
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minizlib/node_modules/yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
      "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==",
      "license": "MIT"
    },
    "node_modules/mkdirp": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
      "license": "MIT",
      "bin": {
        "mkdirp": "bin/cmd.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/mlly": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
      "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
      "license": "MIT",
      "dependencies": {
        "acorn": "^8.15.0",
        "pathe": "^2.0.3",
        "pkg-types": "^1.3.1",
        "ufo": "^1.6.1"
      }
    },
    "node_modules/mrmime": {
      "version": "2.0.1",
@@ -6772,7 +7336,6 @@
      "version": "2.1.3",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/msw": {
@@ -6992,7 +7555,6 @@
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
      "dev": true,
      "license": "BSD-2-Clause",
      "dependencies": {
        "boolbase": "^1.0.0"
@@ -7068,6 +7630,15 @@
      "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
      "license": "ISC",
      "dependencies": {
        "wrappy": "1"
      }
    },
    "node_modules/onetime": {
      "version": "7.0.0",
@@ -7168,6 +7739,12 @@
      "dev": true,
      "license": "BlueOak-1.0.0"
    },
    "node_modules/package-manager-detector": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.5.0.tgz",
      "integrity": "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==",
      "license": "MIT"
    },
    "node_modules/parent-module": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -7185,10 +7762,34 @@
      "version": "7.3.0",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "entities": "^6.0.0"
      },
      "funding": {
        "url": "https://github.com/inikulin/parse5?sponsor=1"
      }
    },
    "node_modules/parse5-htmlparser2-tree-adapter": {
      "version": "7.1.0",
      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
      "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
      "license": "MIT",
      "dependencies": {
        "domhandler": "^5.0.3",
        "parse5": "^7.0.0"
      },
      "funding": {
        "url": "https://github.com/inikulin/parse5?sponsor=1"
      }
    },
    "node_modules/parse5-parser-stream": {
      "version": "7.1.2",
      "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
      "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
      "license": "MIT",
      "dependencies": {
        "parse5": "^7.0.0"
      },
      "funding": {
        "url": "https://github.com/inikulin/parse5?sponsor=1"
@@ -7198,7 +7799,6 @@
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
      "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
      "dev": true,
      "license": "BSD-2-Clause",
      "engines": {
        "node": ">=0.12"
@@ -7269,7 +7869,6 @@
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
      "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/pathval": {
@@ -7281,6 +7880,12 @@
      "engines": {
        "node": ">= 14.16"
      }
    },
    "node_modules/pend": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
      "license": "MIT"
    },
    "node_modules/perfect-debounce": {
      "version": "1.0.0",
@@ -7340,6 +7945,17 @@
        "typescript": {
          "optional": true
        }
      }
    },
    "node_modules/pkg-types": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
      "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
      "license": "MIT",
      "dependencies": {
        "confbox": "^0.1.8",
        "mlly": "^1.7.4",
        "pathe": "^2.0.1"
      }
    },
    "node_modules/playwright": {
@@ -7586,6 +8202,16 @@
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
      "license": "MIT"
    },
    "node_modules/pump": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
      "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
      "license": "MIT",
      "dependencies": {
        "end-of-stream": "^1.1.0",
        "once": "^1.3.1"
      }
    },
    "node_modules/punycode": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -7595,6 +8221,22 @@
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/quansync": {
      "version": "0.2.11",
      "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
      "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
      "funding": [
        {
          "type": "individual",
          "url": "https://github.com/sponsors/antfu"
        },
        {
          "type": "individual",
          "url": "https://github.com/sponsors/sxzz"
        }
      ],
      "license": "MIT"
    },
    "node_modules/queue-microtask": {
      "version": "1.2.3",
@@ -7636,6 +8278,20 @@
      },
      "engines": {
        "node": "^18.17.0 || >=20.5.0"
      }
    },
    "node_modules/readdirp": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 14.18.0"
      },
      "funding": {
        "type": "individual",
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/redent": {
@@ -7844,7 +8500,6 @@
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/saxes": {
@@ -8332,6 +8987,59 @@
        "node": ">=8"
      }
    },
    "node_modules/svgo": {
      "version": "3.3.2",
      "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz",
      "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==",
      "license": "MIT",
      "dependencies": {
        "@trysound/sax": "0.2.0",
        "commander": "^7.2.0",
        "css-select": "^5.1.0",
        "css-tree": "^2.3.1",
        "css-what": "^6.1.0",
        "csso": "^5.0.5",
        "picocolors": "^1.0.0"
      },
      "bin": {
        "svgo": "bin/svgo"
      },
      "engines": {
        "node": ">=14.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/svgo"
      }
    },
    "node_modules/svgo/node_modules/commander": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
      "license": "MIT",
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/svgo/node_modules/css-tree": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
      "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
      "license": "MIT",
      "dependencies": {
        "mdn-data": "2.0.30",
        "source-map-js": "^1.0.1"
      },
      "engines": {
        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
      }
    },
    "node_modules/svgo/node_modules/mdn-data": {
      "version": "2.0.30",
      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
      "license": "CC0-1.0"
    },
    "node_modules/symbol-tree": {
      "version": "3.2.4",
      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -8383,6 +9091,38 @@
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/tar": {
      "version": "6.2.1",
      "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
      "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
      "license": "ISC",
      "dependencies": {
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "minipass": "^5.0.0",
        "minizlib": "^2.1.1",
        "mkdirp": "^1.0.3",
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/tar/node_modules/minipass": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
      "license": "ISC",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/tar/node_modules/yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
      "license": "ISC"
    },
    "node_modules/tinybench": {
      "version": "2.9.0",
@@ -8621,11 +9361,25 @@
        "typescript": ">=4.8.4 <6.0.0"
      }
    },
    "node_modules/ufo": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
      "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
      "license": "MIT"
    },
    "node_modules/undici": {
      "version": "6.22.0",
      "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz",
      "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==",
      "license": "MIT",
      "engines": {
        "node": ">=18.17"
      }
    },
    "node_modules/undici-types": {
      "version": "6.21.0",
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
      "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
      "devOptional": true,
      "license": "MIT"
    },
    "node_modules/unplugin-utils": {
@@ -9250,7 +10004,6 @@
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
      "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "iconv-lite": "0.6.3"
@@ -9263,7 +10016,6 @@
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
      "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=18"
@@ -9482,6 +10234,12 @@
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
      "license": "ISC"
    },
    "node_modules/ws": {
      "version": "8.18.3",
      "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
@@ -9641,6 +10399,16 @@
        "node": ">=8"
      }
    },
    "node_modules/yauzl": {
      "version": "2.10.0",
      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
      "license": "MIT",
      "dependencies": {
        "buffer-crc32": "~0.2.3",
        "fd-slicer": "~1.1.0"
      }
    },
    "node_modules/yocto-queue": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
package.json
@@ -19,6 +19,8 @@
    "prepare": "husky"
  },
  "dependencies": {
    "@iconify/tools": "^4.1.4",
    "@iconify/vue": "^5.0.0",
    "@tailwindcss/vite": "^4.1.16",
    "axios": "^1.13.2",
    "pinia": "^3.0.3",
@@ -43,6 +45,7 @@
    "@vue/eslint-config-typescript": "^14.6.0",
    "@vue/test-utils": "^2.4.6",
    "@vue/tsconfig": "^0.8.1",
    "chokidar": "^4.0.3",
    "eslint": "^9.37.0",
    "eslint-plugin-playwright": "^2.2.2",
    "eslint-plugin-vue": "~10.5.0",
src/assets/icons/colored/redmine.svg
比對新檔案
@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22" fill="none">
  <path d="M2.32041 2.16353C2.47087 2.15526 2.57985 2.18313 2.71505 2.24717C2.93799 2.35272 3.49375 2.66091 3.65789 2.81629C3.72326 2.87818 3.772 2.95947 3.80016 3.04476C3.80628 3.06386 3.81139 3.08324 3.8155 3.10289C3.81961 3.12255 3.82268 3.14235 3.82472 3.16231C3.82676 3.18226 3.82777 3.20227 3.82774 3.22234C3.82768 3.24241 3.82659 3.26242 3.82447 3.28237C3.82235 3.30233 3.81919 3.32212 3.815 3.34174C3.81084 3.36137 3.80566 3.38073 3.79946 3.39983C3.79326 3.41891 3.78608 3.43762 3.77792 3.45598C3.76976 3.47431 3.76068 3.49217 3.75067 3.50957C3.66054 3.66941 3.5162 3.74581 3.34553 3.79129C3.05752 3.80969 2.84298 3.65675 2.60313 3.51903C2.33298 3.36395 1.92759 3.20142 1.8468 2.87128C1.81071 2.72388 1.84093 2.55147 1.92131 2.42256C2.0126 2.27611 2.15784 2.20161 2.32041 2.16353Z" fill="#333333"/>
  <path d="M3.2133 11.5862C3.32489 11.5837 3.42871 11.5988 3.52843 11.6514C3.54588 11.6604 3.56283 11.6703 3.57929 11.681C3.59577 11.6917 3.61166 11.7032 3.62696 11.7155C3.64226 11.7278 3.65691 11.7409 3.67091 11.7547C3.68491 11.7685 3.69818 11.7829 3.71073 11.798C3.72327 11.8132 3.73501 11.8289 3.74595 11.8452C3.75692 11.8615 3.76704 11.8783 3.7763 11.8956C3.78559 11.9129 3.79397 11.9307 3.80144 11.9488C3.80893 11.967 3.81549 11.9855 3.82112 12.0043C3.82658 12.0223 3.8311 12.0406 3.83468 12.0591C3.83823 12.0776 3.84083 12.0962 3.84245 12.115C3.84411 12.1337 3.84477 12.1525 3.84444 12.1713C3.84413 12.1901 3.84285 12.2089 3.84059 12.2276C3.8383 12.2463 3.83506 12.2648 3.83088 12.2832C3.82671 12.3015 3.82159 12.3196 3.8155 12.3374C3.80943 12.3553 3.80246 12.3727 3.79457 12.3898C3.78672 12.4069 3.77798 12.4236 3.76836 12.4398C3.63176 12.6734 2.74945 13.1638 2.48339 13.2298C2.34013 13.2336 2.22184 13.2169 2.09752 13.1385C2.08106 13.1282 2.06517 13.1171 2.04985 13.1051C2.03449 13.0932 2.01979 13.0805 2.00573 13.0671C1.99167 13.0537 1.97832 13.0396 1.96567 13.0249C1.95304 13.0101 1.94118 12.9948 1.93007 12.9788C1.91896 12.9629 1.90869 12.9464 1.89927 12.9295C1.88981 12.9125 1.88124 12.8951 1.87355 12.8772C1.86586 12.8594 1.85908 12.8412 1.85321 12.8227C1.84734 12.8041 1.84242 12.7854 1.83845 12.7664C1.80752 12.6147 1.84552 12.4608 1.93147 12.3335C2.06291 12.1387 2.98044 11.625 3.2133 11.5862Z" fill="#333333"/>
  <path d="M19.5137 2.16215C19.6508 2.15703 19.7657 2.16939 19.8871 2.24129C20.02 2.32001 20.1215 2.45215 20.1581 2.60277C20.1946 2.75302 20.1656 2.90538 20.0837 3.0357C19.9506 3.24763 19.07 3.74067 18.821 3.80112C18.6964 3.80815 18.5892 3.79938 18.4756 3.74063C18.4574 3.7314 18.4398 3.72123 18.4226 3.71012C18.4055 3.69904 18.389 3.68709 18.3732 3.67427C18.3573 3.66146 18.3421 3.64785 18.3277 3.63347C18.3132 3.61908 18.2996 3.60396 18.2867 3.58811C18.2738 3.57229 18.2618 3.55585 18.2507 3.53879C18.2395 3.5217 18.2293 3.50408 18.22 3.48595C18.2107 3.46778 18.2023 3.44919 18.195 3.43017C18.1876 3.41115 18.1812 3.3918 18.1759 3.37212C18.1709 3.35366 18.167 3.33498 18.1639 3.3161C18.1609 3.29725 18.1589 3.27827 18.1579 3.25917C18.1569 3.24009 18.1568 3.22101 18.1577 3.2019C18.1587 3.1828 18.1607 3.16381 18.1636 3.14493C18.1665 3.12605 18.1704 3.10736 18.1753 3.08887C18.1802 3.0704 18.186 3.05222 18.1928 3.03433C18.1995 3.01647 18.2072 2.999 18.2158 2.98191C18.2244 2.96484 18.2338 2.94826 18.2442 2.93217C18.3783 2.71928 19.2639 2.21892 19.5137 2.16215Z" fill="#333333"/>
  <path d="M18.6989 11.586C18.9118 11.5821 19.0905 11.6958 19.2692 11.7977C19.5589 11.9629 20.0674 12.1753 20.1528 12.518C20.1573 12.5368 20.1609 12.5557 20.1636 12.5749C20.1662 12.594 20.1679 12.6132 20.1687 12.6326C20.1694 12.6519 20.1692 12.6712 20.1681 12.6905C20.1669 12.7098 20.1648 12.729 20.1618 12.7481C20.1587 12.7672 20.1548 12.7861 20.1498 12.8048C20.1449 12.8235 20.1391 12.8419 20.1324 12.86C20.1257 12.8781 20.1181 12.8959 20.1096 12.9133C20.1011 12.9306 20.0918 12.9475 20.0817 12.964C19.9842 13.1213 19.836 13.1889 19.6638 13.2312C19.5968 13.2312 19.5263 13.2337 19.4614 13.2145C19.2147 13.141 18.7077 12.834 18.4828 12.6849C18.3241 12.5796 18.197 12.4396 18.1642 12.2453C18.1379 12.0895 18.1821 11.9426 18.275 11.817C18.3835 11.6705 18.5245 11.6123 18.6989 11.586Z" fill="#333333"/>
  <path d="M19.8777 7.12272C20.1404 7.10875 20.7582 7.08539 20.998 7.12739C21.093 7.14401 21.1823 7.17329 21.2632 7.22745C21.3826 7.30741 21.4602 7.42896 21.487 7.56962C21.5186 7.73475 21.494 7.88798 21.3973 8.02711C21.2954 8.17388 21.1586 8.2359 20.9885 8.26654C20.7504 8.27882 20.0929 8.29949 19.8832 8.26989C19.7932 8.25715 19.7056 8.23077 19.6282 8.18232C19.6117 8.17209 19.5958 8.16105 19.5805 8.1492C19.5651 8.13735 19.5504 8.12475 19.5363 8.11141C19.5223 8.09807 19.5089 8.08404 19.4963 8.06932C19.4836 8.05463 19.4718 8.03933 19.4607 8.02343C19.4496 8.00749 19.4394 7.99105 19.43 7.9741C19.4205 7.95715 19.412 7.93977 19.4044 7.92196C19.3967 7.90413 19.39 7.88597 19.3842 7.86747C19.3785 7.84895 19.3736 7.83019 19.3697 7.8112C19.3657 7.79221 19.3627 7.77305 19.3606 7.75373C19.3585 7.73444 19.3574 7.71509 19.3573 7.69568C19.3571 7.67625 19.358 7.65687 19.3598 7.63755C19.3616 7.61823 19.3644 7.59904 19.3681 7.58C19.3718 7.56092 19.3765 7.5421 19.3821 7.52352C19.3877 7.50494 19.3942 7.48668 19.4017 7.46874C19.4091 7.45082 19.4174 7.43331 19.4266 7.41619C19.4358 7.3991 19.4459 7.38251 19.4567 7.36641C19.5587 7.21839 19.7059 7.15046 19.8777 7.12272Z" fill="#333333"/>
  <path d="M1.02092 7.12304C1.27002 7.1084 1.91472 7.08822 2.14303 7.12668C2.2265 7.14073 2.30651 7.16777 2.37857 7.21276C2.39489 7.2229 2.41067 7.23384 2.42591 7.24558C2.44113 7.25735 2.45571 7.26985 2.46966 7.28308C2.48358 7.29631 2.49681 7.31022 2.50935 7.3248C2.52189 7.33938 2.53364 7.35457 2.54461 7.37036C2.55561 7.38613 2.56577 7.40242 2.57509 7.41923C2.58443 7.43605 2.59289 7.45329 2.60047 7.47096C2.60802 7.48863 2.61468 7.50664 2.62044 7.525C2.62618 7.54335 2.63097 7.56195 2.63483 7.58077C2.63866 7.59918 2.64158 7.61775 2.64359 7.63646C2.64561 7.65518 2.6467 7.67395 2.64686 7.69278C2.647 7.7116 2.64621 7.73037 2.6445 7.74909C2.6428 7.76783 2.64016 7.78645 2.63661 7.80494C2.63308 7.82341 2.62863 7.84167 2.62325 7.85973C2.61791 7.87775 2.61168 7.89549 2.60457 7.91294C2.59745 7.93036 2.5895 7.94738 2.58071 7.964C2.57192 7.98065 2.56232 7.99681 2.55193 8.0125C2.44981 8.16415 2.30469 8.23535 2.13058 8.26698C1.88561 8.28 1.20598 8.30171 0.97953 8.26226C0.939481 8.2557 0.90052 8.24513 0.862648 8.23055C0.824775 8.21597 0.788791 8.19768 0.754695 8.17569C0.738708 8.16513 0.7233 8.1538 0.708471 8.1417C0.693669 8.12957 0.679502 8.11673 0.665968 8.10317C0.652462 8.08961 0.639673 8.0754 0.6276 8.06054C0.615527 8.04568 0.60424 8.03025 0.593738 8.01423C0.583236 7.99822 0.573575 7.98172 0.564755 7.96474C0.555934 7.94774 0.54801 7.93033 0.540981 7.91253C0.533925 7.89472 0.527806 7.87661 0.522624 7.8582C0.517414 7.83976 0.513156 7.82111 0.509848 7.80226C0.50632 7.78332 0.503743 7.76425 0.502117 7.74504C0.50049 7.72585 0.499801 7.70663 0.500049 7.68736C0.500325 7.66809 0.501538 7.64888 0.503688 7.62972C0.505838 7.61059 0.508925 7.5916 0.512949 7.57275C0.516973 7.55392 0.521921 7.53533 0.527792 7.51697C0.533663 7.49862 0.540416 7.48059 0.548051 7.46289C0.555686 7.44523 0.564176 7.42796 0.57352 7.41109C0.582864 7.39425 0.593007 7.3779 0.60395 7.36205C0.707892 7.21354 0.848632 7.15165 1.02092 7.12304Z" fill="#333333"/>
  <path d="M10.8435 0.503904C11.3059 0.486576 11.7809 0.527973 12.2363 0.60729C12.2945 0.617414 12.3525 0.628252 12.4104 0.639804C12.4683 0.651356 12.526 0.663617 12.5836 0.676589C12.6412 0.689561 12.6986 0.703241 12.7558 0.717627C12.8131 0.732016 12.8701 0.747105 12.927 0.762895C12.9839 0.778687 13.0405 0.795176 13.097 0.812361C13.1535 0.829548 13.2097 0.847427 13.2657 0.865999C13.3218 0.88457 13.3775 0.903829 13.4331 0.923773C13.4886 0.943718 13.5439 0.964343 13.599 0.985649C13.654 1.00696 13.7088 1.02894 13.7633 1.05159C13.8178 1.07425 13.872 1.09757 13.9259 1.12156C13.9799 1.14555 14.0335 1.1702 14.0868 1.19551C14.1401 1.22082 14.1931 1.24678 14.2458 1.27338C14.2985 1.30002 14.3508 1.32728 14.4029 1.35518C14.4549 1.38309 14.5065 1.41162 14.5578 1.44079C14.6091 1.46996 14.6601 1.49976 14.7107 1.5302C14.7612 1.56064 14.8114 1.59168 14.8612 1.62333C14.911 1.65501 14.9604 1.68728 15.0095 1.72015C15.0585 1.75304 15.1071 1.78652 15.1553 1.8206C15.2035 1.85468 15.2512 1.88935 15.2986 1.92461C15.3459 1.95987 15.3928 1.9957 15.4393 2.0321C15.4857 2.06852 15.5317 2.10549 15.5773 2.14301C15.6228 2.18056 15.6679 2.21866 15.7125 2.25732C15.7571 2.29597 15.8012 2.33516 15.8449 2.37489C15.8885 2.41465 15.9317 2.45493 15.9743 2.49573C16.017 2.53651 16.0591 2.57783 16.1008 2.61968C16.1424 2.6615 16.1835 2.70385 16.2241 2.74672C16.2647 2.78957 16.3047 2.83291 16.3443 2.87675C16.3838 2.92058 16.4228 2.9649 16.4612 3.0097C16.4996 3.05448 16.5375 3.09974 16.5748 3.14548C16.6121 3.19121 16.6489 3.23739 16.6851 3.28402C16.7213 3.33067 16.7569 3.37774 16.7919 3.42525C16.8269 3.47275 16.8613 3.52068 16.8952 3.56904C16.929 3.61726 16.9622 3.6659 16.9947 3.71494C17.0273 3.76399 17.0593 3.81344 17.0906 3.86329C17.122 3.91311 17.1527 3.96331 17.1829 4.0139C17.213 4.0645 17.2425 4.11546 17.2714 4.1668C17.3002 4.21811 17.3285 4.26976 17.3561 4.32176C17.3837 4.37378 17.4107 4.42612 17.437 4.47878C17.4633 4.53147 17.489 4.58446 17.514 4.63776C17.539 4.69105 17.5634 4.74465 17.587 4.79855C17.6108 4.85245 17.6338 4.90664 17.6561 4.96112C17.6785 5.0156 17.7002 5.07034 17.7212 5.12534C17.7422 5.18034 17.7626 5.2356 17.7822 5.29109C17.8019 5.34659 17.8209 5.40233 17.8392 5.4583C17.8575 5.51426 17.8751 5.57044 17.892 5.62682C17.9089 5.68323 17.9251 5.73983 17.9406 5.79663C17.9562 5.85342 17.971 5.91041 17.9851 5.96759C17.9992 6.02475 18.0127 6.08208 18.0254 6.13959C18.0381 6.19708 18.0501 6.25471 18.0613 6.3125C18.0727 6.37029 18.0832 6.4282 18.0931 6.48624C18.103 6.5443 18.1121 6.60247 18.1206 6.66076C18.129 6.71901 18.1367 6.77738 18.1437 6.83586C18.1507 6.89431 18.157 6.95284 18.1626 7.01145C18.1682 7.07007 18.173 7.12875 18.1771 7.1875C18.1813 7.24623 18.1847 7.30501 18.1874 7.36385C18.19 7.42265 18.192 7.4815 18.1932 7.54039C18.1944 7.59926 18.195 7.65813 18.1948 7.71702C18.1945 7.77589 18.1936 7.83475 18.1919 7.89361C18.1903 7.95248 18.1879 8.01131 18.1848 8.07012C18.1817 8.1289 18.1778 8.18765 18.1733 8.24638C18.1687 8.30508 18.1635 8.36372 18.1575 8.42231C18.1515 8.48087 18.1448 8.53936 18.1374 8.59778C18.1299 8.65617 18.1218 8.71448 18.1129 8.77271C18.104 8.83091 18.0945 8.889 18.0842 8.94699C18.0755 8.9954 18.0664 9.04373 18.0568 9.09198C18.0472 9.14023 18.0371 9.18837 18.0265 9.23639C18.0159 9.28442 18.0048 9.33234 17.9932 9.38015C17.9816 9.42795 17.9696 9.47562 17.957 9.52316C17.9444 9.57071 17.9314 9.61815 17.9179 9.66546C17.9043 9.71274 17.8903 9.75989 17.8759 9.8069C17.8614 9.8539 17.8464 9.90075 17.831 9.94742C17.8155 9.99413 17.7996 10.0407 17.7832 10.087C17.7668 10.1334 17.7499 10.1796 17.7326 10.2257C17.7152 10.2717 17.6974 10.3175 17.6791 10.3632C17.6609 10.4089 17.6421 10.4543 17.6229 10.4996C17.6037 10.5449 17.584 10.59 17.5639 10.6348C17.5438 10.6797 17.5232 10.7244 17.5021 10.7688C17.4811 10.8133 17.4596 10.8575 17.4376 10.9015C17.4157 10.9456 17.3933 10.9894 17.3705 11.0329C17.3476 11.0765 17.3243 11.1198 17.3006 11.1629C17.2769 11.206 17.2527 11.2488 17.2281 11.2914C17.2035 11.334 17.1784 11.3763 17.153 11.4184C17.1275 11.4605 17.1016 11.5023 17.0753 11.5438C17.049 11.5854 17.0222 11.6267 16.9951 11.6677C16.9679 11.7087 16.9403 11.7494 16.9123 11.7898C16.8843 11.8303 16.8559 11.8704 16.8271 11.9103C16.7982 11.9501 16.769 11.9897 16.7394 12.0289C16.7098 12.0682 16.6797 12.1072 16.6493 12.1458C16.6189 12.1845 16.5881 12.2228 16.5569 12.2608C16.5257 12.2988 16.4941 12.3365 16.4621 12.3739C16.4301 12.4112 16.3977 12.4483 16.365 12.485C16.3323 12.5217 16.2992 12.5581 16.2657 12.5941C16.2322 12.6301 16.1983 12.6658 16.1642 12.7012C16.1299 12.7365 16.0954 12.7715 16.0604 12.8061C16.0255 12.8408 15.9902 12.875 15.9546 12.909C15.919 12.9429 15.883 12.9764 15.8467 13.0096C15.5449 13.2849 15.2224 13.5218 14.8877 13.7547L14.8901 15.4345C15.0524 15.4411 15.1946 15.4602 15.3281 15.5637C15.3433 15.5754 15.3578 15.5879 15.3717 15.6011C15.3856 15.6144 15.3988 15.6283 15.4112 15.6428C15.4237 15.6574 15.4354 15.6726 15.4463 15.6883C15.4572 15.7041 15.4673 15.7204 15.4765 15.7371C15.4858 15.7539 15.4942 15.7712 15.5017 15.7888C15.5092 15.8064 15.5158 15.8244 15.5214 15.8428C15.5271 15.8611 15.5319 15.8796 15.5356 15.8984C15.5394 15.9172 15.5422 15.9362 15.5441 15.9553C15.5462 15.9746 15.5472 15.9941 15.5473 16.0135C15.5474 16.033 15.5466 16.0525 15.5447 16.0719C15.5428 16.0913 15.5399 16.1105 15.5361 16.1296C15.5322 16.1487 15.5274 16.1676 15.5217 16.1862C15.5159 16.2048 15.5092 16.2231 15.5016 16.241C15.4939 16.2589 15.4854 16.2764 15.476 16.2935C15.4665 16.3105 15.4563 16.3271 15.4452 16.3431C15.4341 16.3591 15.4222 16.3745 15.4095 16.3893C15.268 16.5533 15.0938 16.586 14.8896 16.603C14.892 17.094 14.9255 17.6026 14.7224 18.0624C14.4906 18.587 14.0807 18.9053 13.5566 19.1069C13.5545 19.141 13.5517 19.1752 13.5482 19.2092C13.5447 19.2433 13.5405 19.2773 13.5356 19.3112C13.5308 19.3451 13.5252 19.3789 13.519 19.4125C13.5128 19.4462 13.5059 19.4797 13.4983 19.5131C13.4907 19.5465 13.4825 19.5797 13.4736 19.6128C13.4647 19.6459 13.4551 19.6787 13.4448 19.7114C13.4346 19.7441 13.4237 19.7766 13.4122 19.8088C13.4007 19.841 13.3885 19.873 13.3757 19.9048C13.3628 19.9365 13.3494 19.968 13.3353 19.9992C13.3212 20.0304 13.3065 20.0613 13.2911 20.092C13.2758 20.1226 13.2598 20.1529 13.2433 20.1829C13.2267 20.2128 13.2096 20.2424 13.1918 20.2717C13.1741 20.301 13.1558 20.3299 13.1369 20.3585C13.118 20.387 13.0985 20.4152 13.0784 20.4429C13.0584 20.4707 13.0378 20.4981 13.0166 20.525C12.9955 20.5519 12.9738 20.5784 12.9516 20.6045C12.5006 21.1355 11.8732 21.4424 11.1822 21.4976C10.5088 21.5158 9.90897 21.3606 9.37883 20.9277C8.80932 20.4627 8.51458 19.8279 8.44324 19.1056C8.14742 18.9995 7.88233 18.8491 7.66017 18.6244C7.07478 18.0321 7.10997 17.3695 7.1146 16.604C6.94703 16.6012 6.78136 16.5644 6.65105 16.4519C6.63654 16.4394 6.62272 16.4261 6.60956 16.4122C6.59641 16.3982 6.58399 16.3837 6.5723 16.3684C6.56064 16.3532 6.54978 16.3375 6.53971 16.3211C6.52962 16.3048 6.5204 16.2881 6.51205 16.2708C6.5037 16.2535 6.49624 16.2359 6.48967 16.2179C6.48311 16.1999 6.47747 16.1816 6.47276 16.163C6.46805 16.1444 6.4643 16.1256 6.46151 16.1067C6.45873 16.0877 6.45691 16.0686 6.45605 16.0495C6.45492 16.0305 6.45474 16.0116 6.45552 15.9926C6.45626 15.9737 6.45795 15.9548 6.4606 15.936C6.46322 15.9173 6.46678 15.8987 6.47127 15.8802C6.47574 15.8618 6.48111 15.8436 6.4874 15.8257C6.49369 15.8078 6.50084 15.7903 6.50886 15.7731C6.51689 15.756 6.52574 15.7392 6.53541 15.7229C6.54512 15.7066 6.5556 15.6908 6.56684 15.6755C6.57809 15.6603 6.59007 15.6456 6.60278 15.6315C6.74496 15.4761 6.91399 15.4453 7.11286 15.4359L7.11233 13.7495C6.93477 13.6358 6.76258 13.5145 6.59575 13.3856C6.4289 13.2567 6.26805 13.1207 6.11321 12.9776C6.07009 12.9378 6.02745 12.8974 5.9853 12.8565C5.94317 12.8156 5.90155 12.7741 5.86045 12.7322C5.81931 12.6903 5.77871 12.6478 5.73865 12.6049C5.69857 12.5619 5.65902 12.5185 5.62 12.4746C5.58099 12.4307 5.54252 12.3863 5.50458 12.3415C5.46667 12.2966 5.42931 12.2513 5.39251 12.2056C5.3557 12.1598 5.31946 12.1136 5.28378 12.0669C5.24811 12.0203 5.21301 11.9732 5.17849 11.9257C5.14394 11.8781 5.11001 11.8302 5.07667 11.7819C5.04334 11.7335 5.01059 11.6848 4.97841 11.6356C4.94626 11.5864 4.91474 11.5369 4.88383 11.487C4.8529 11.437 4.82257 11.3867 4.79285 11.3361C4.76315 11.2854 4.73408 11.2344 4.70563 11.183C4.6772 11.1316 4.6494 11.0799 4.62221 11.0278C4.59503 10.9757 4.56849 10.9234 4.5426 10.8706C4.51672 10.8179 4.49147 10.7649 4.46688 10.7116C4.44232 10.6582 4.4184 10.6046 4.39513 10.5506C4.37183 10.4967 4.34922 10.4425 4.32731 10.388C4.30536 10.3335 4.28409 10.2788 4.26349 10.2238C4.2429 10.1688 4.22298 10.1135 4.20374 10.0581C4.18449 10.0026 4.16592 9.94683 4.14803 9.89089C4.13016 9.83492 4.11299 9.77876 4.0965 9.72241C4.07998 9.66603 4.06417 9.60946 4.04906 9.55272C4.03396 9.49596 4.01955 9.43901 4.00585 9.38188C3.99215 9.32478 3.97915 9.26752 3.96685 9.21009C3.95452 9.15266 3.94292 9.09508 3.93203 9.03735C3.92114 8.97964 3.91096 8.92181 3.90151 8.86386C3.89202 8.80588 3.88326 8.7478 3.8752 8.68963C3.86715 8.63143 3.85982 8.57316 3.8532 8.51482C3.84659 8.45645 3.84069 8.39802 3.8355 8.33951C3.83032 8.28101 3.82585 8.22245 3.8221 8.16383C3.81838 8.10522 3.81536 8.04656 3.81305 7.98786C3.81059 7.92856 3.80887 7.86924 3.80788 7.80991C3.80688 7.75058 3.80664 7.69125 3.80713 7.63191C3.8076 7.57256 3.80882 7.51322 3.81077 7.45392C3.81273 7.39461 3.81542 7.33534 3.81884 7.27609C3.82226 7.21684 3.8264 7.15765 3.83128 7.09851C3.83616 7.03937 3.84178 6.9803 3.84812 6.9213C3.85449 6.8623 3.86157 6.80338 3.86937 6.74454C3.87718 6.68571 3.88571 6.62698 3.89497 6.56837C3.90424 6.50975 3.91422 6.45126 3.92491 6.3929C3.93564 6.33453 3.94708 6.2763 3.95924 6.21821C3.97137 6.16012 3.98423 6.10219 3.99782 6.04443C4.01142 5.98667 4.02573 5.92908 4.04075 5.87165C4.05575 5.81425 4.07147 5.75702 4.0879 5.69998C4.10433 5.64296 4.12146 5.58615 4.1393 5.52955C4.15714 5.47295 4.17568 5.41658 4.19493 5.36045C4.21417 5.30431 4.23409 5.24843 4.25469 5.19279C4.27531 5.13713 4.29662 5.08174 4.31862 5.02662C4.3406 4.97151 4.36326 4.91667 4.38661 4.86211C4.40996 4.80755 4.43399 4.75329 4.45869 4.69934C4.48337 4.64538 4.50872 4.59173 4.53475 4.53838C4.56077 4.48506 4.58746 4.43205 4.61481 4.37937C4.64213 4.32671 4.6701 4.27439 4.69872 4.22242C4.72737 4.17042 4.75665 4.1188 4.78656 4.06754C4.81648 4.01629 4.84701 3.96542 4.87816 3.91494C4.90935 3.86443 4.94114 3.81432 4.97353 3.76461C5.00595 3.7149 5.03897 3.66559 5.07258 3.61668C5.10621 3.5678 5.14046 3.51933 5.17531 3.47128C5.21013 3.42325 5.24554 3.37565 5.28155 3.32847C5.31756 3.2813 5.35414 3.23458 5.39131 3.18832C5.4285 3.14206 5.46624 3.09626 5.50454 3.05094C5.54283 3.00561 5.5817 2.96077 5.62112 2.91641C5.66052 2.87204 5.70047 2.82818 5.74097 2.78481C7.07887 1.3513 8.89464 0.573262 10.8435 0.503904Z" fill="#333333"/>
  <path d="M9.61292 19.1967C10.5345 19.1725 11.4648 19.1876 12.3869 19.1963C12.303 19.5016 12.193 19.7254 11.9736 19.9556C11.8003 20.1082 11.6173 20.225 11.394 20.2901C11.3719 20.2965 11.3496 20.3024 11.3273 20.3077C11.3048 20.313 11.2823 20.3178 11.2597 20.322C11.237 20.3262 11.2143 20.3299 11.1915 20.333C11.1687 20.3361 11.1458 20.3386 11.1228 20.3406C11.0999 20.3426 11.0769 20.344 11.0539 20.3448C11.0309 20.3457 11.0078 20.346 10.9848 20.3457C10.9618 20.3454 10.9388 20.3446 10.9158 20.3432C10.8928 20.3418 10.8699 20.3398 10.847 20.3373C10.8241 20.3348 10.8013 20.3317 10.7785 20.328C10.7558 20.3244 10.7332 20.3202 10.7106 20.3154C10.6881 20.3107 10.6657 20.3054 10.6434 20.2995C10.6211 20.2937 10.599 20.2873 10.577 20.2803C10.5551 20.2734 10.5333 20.2659 10.5117 20.2579C10.4901 20.2499 10.4687 20.2414 10.4476 20.2324C10.4264 20.2233 10.4054 20.2137 10.3847 20.2037C10.364 20.1936 10.3436 20.183 10.3234 20.1719C9.93094 19.9535 9.73067 19.6185 9.61292 19.1967Z" fill="#6C6D8C"/>
  <path d="M8.27144 16.5981C10.0899 16.5981 11.9104 16.5784 13.7286 16.5997C13.7312 17.0293 13.8081 17.4555 13.5182 17.8089C13.3346 17.9698 13.1606 18.0279 12.9189 18.0329C12.0616 18.0504 11.1989 18.0308 10.3411 18.0314L9.44524 18.0319C9.25508 18.0321 9.05463 18.0432 8.86617 18.0147C8.73098 17.9942 8.59786 17.9185 8.50137 17.8231C8.18566 17.5109 8.26999 17.0047 8.27144 16.5981Z" fill="#90B1F3"/>
  <path d="M8.27219 13.999L13.7289 13.9997L13.7285 15.438C11.9113 15.4148 10.0907 15.437 8.27314 15.4373L8.27219 13.999Z" fill="#90B1F3"/>
  <path d="M10.6485 1.67132C11.245 1.64551 11.8267 1.68658 12.4084 1.82599C12.4567 1.83757 12.5048 1.84974 12.5528 1.86251C12.6008 1.87527 12.6486 1.88862 12.6963 1.90254C12.744 1.91649 12.7915 1.93102 12.8388 1.94613C12.8861 1.96124 12.9332 1.97694 12.9801 1.99323C13.027 2.0095 13.0737 2.02635 13.1203 2.04377C13.1668 2.06119 13.213 2.0792 13.2591 2.09778C13.3052 2.11634 13.351 2.13547 13.3966 2.15518C13.4422 2.17487 13.4875 2.19512 13.5326 2.21593C13.5777 2.23675 13.6225 2.25813 13.6671 2.28008C13.7116 2.30199 13.7559 2.32446 13.7999 2.34749C13.8439 2.37048 13.8877 2.39403 13.9311 2.41812C13.9745 2.44222 14.0176 2.46685 14.0604 2.49203C14.1033 2.51717 14.1458 2.54285 14.1879 2.56907C14.2301 2.59526 14.272 2.62198 14.3135 2.64922C14.3551 2.67646 14.3962 2.70421 14.4371 2.73247C14.4779 2.76073 14.5184 2.78948 14.5585 2.81874C14.5987 2.84799 14.6384 2.87774 14.6778 2.90798C14.7172 2.9382 14.7563 2.96891 14.7949 3.00012C14.8335 3.0313 14.8718 3.06297 14.9096 3.09512C14.9475 3.12726 14.985 3.15987 15.022 3.19292C15.0591 3.22598 15.0957 3.25949 15.132 3.29346C15.1682 3.32743 15.204 3.36185 15.2394 3.39672C15.2748 3.43157 15.3097 3.46685 15.3442 3.50255C15.3787 3.53826 15.4128 3.57439 15.4464 3.61095C15.48 3.64751 15.5132 3.68448 15.5459 3.72186C15.5786 3.75922 15.6109 3.79698 15.6426 3.83514C15.6744 3.87332 15.7057 3.91188 15.7365 3.95081C15.7674 3.98977 15.7977 4.02908 15.8276 4.06875C15.8574 4.10846 15.8868 4.1485 15.9157 4.18889C15.9445 4.22931 15.9729 4.27007 16.0007 4.31118C16.0286 4.35232 16.056 4.39377 16.0828 4.43554C16.1096 4.47734 16.136 4.51945 16.1618 4.56188C16.1874 4.60415 16.2125 4.64673 16.2371 4.68963C16.2616 4.73253 16.2857 4.77572 16.3092 4.8192C16.3327 4.86268 16.3557 4.90643 16.3782 4.95046C16.4006 4.99452 16.4225 5.03884 16.4439 5.08342C16.4653 5.128 16.4861 5.17283 16.5063 5.21791C16.5266 5.26301 16.5463 5.30835 16.5654 5.35393C16.5846 5.3995 16.6032 5.4453 16.6212 5.49131C16.6392 5.53735 16.6567 5.5836 16.6736 5.63006C16.6905 5.67652 16.7068 5.72317 16.7225 5.77001C16.7383 5.81688 16.7535 5.86393 16.7681 5.91115C16.7827 5.95838 16.7967 6.00578 16.8101 6.05334C16.8236 6.10092 16.8364 6.14866 16.8487 6.19655C16.861 6.24444 16.8726 6.29247 16.8838 6.34063C16.8948 6.3888 16.9053 6.4371 16.9152 6.48554C16.9251 6.53399 16.9344 6.58254 16.9432 6.6312C16.9519 6.67986 16.96 6.72862 16.9675 6.77747C16.975 6.82633 16.982 6.87527 16.9883 6.92429C16.9946 6.97331 17.0003 7.02241 17.0055 7.0716C17.0106 7.12076 17.0151 7.16998 17.019 7.21928C17.0229 7.26855 17.0262 7.31786 17.0289 7.36721C17.0316 7.41659 17.0337 7.46598 17.0352 7.51539C17.0367 7.56479 17.0376 7.61421 17.0378 7.66365C17.0381 7.71308 17.0378 7.76251 17.0369 7.81195C17.036 7.86135 17.0344 7.91076 17.0323 7.96017C17.0301 8.00955 17.0274 8.0589 17.024 8.10822C17.0207 8.15754 17.0167 8.20681 17.0122 8.25603C17.0076 8.30527 17.0025 8.35442 16.9967 8.4035C16.9909 8.4526 16.9846 8.50162 16.9776 8.55056C16.9706 8.59953 16.9631 8.64838 16.9549 8.69713C16.9468 8.74587 16.938 8.79452 16.9286 8.84307C16.9193 8.89162 16.9093 8.94004 16.8988 8.98831C16.8882 9.03662 16.8771 9.08478 16.8654 9.13281C16.8538 9.18048 16.8415 9.22801 16.8287 9.2754C16.8159 9.3228 16.8025 9.37001 16.7886 9.41705C16.7746 9.46411 16.7601 9.51099 16.745 9.5577C16.7299 9.6044 16.7143 9.65092 16.698 9.69723C16.6818 9.74355 16.665 9.78966 16.6476 9.83557C16.6302 9.88147 16.6123 9.92716 16.5938 9.97262C16.5753 10.0181 16.5563 10.0633 16.5367 10.1083C16.5171 10.1533 16.497 10.1981 16.4763 10.2426C16.4556 10.2871 16.4344 10.3313 16.4126 10.3753C16.3908 10.4193 16.3685 10.463 16.3457 10.5065C16.3229 10.5499 16.2995 10.5931 16.2756 10.6359C16.2517 10.6788 16.2273 10.7214 16.2024 10.7636C16.1775 10.8059 16.152 10.8479 16.126 10.8895C16.1001 10.9312 16.0736 10.9725 16.0466 11.0135C16.0197 11.0545 15.9922 11.0952 15.9642 11.1355C15.9362 11.1758 15.9078 11.2158 15.8788 11.2555C15.8499 11.2951 15.8205 11.3344 15.7906 11.3733C15.7606 11.4122 15.7303 11.4507 15.6994 11.4889C15.6686 11.5271 15.6373 11.5649 15.6055 11.6023C15.5737 11.6397 15.5415 11.6767 15.5088 11.7133C15.4761 11.7499 15.443 11.7862 15.4095 11.822C15.3759 11.8578 15.3419 11.8931 15.3074 11.9281C15.273 11.9631 15.2382 11.9977 15.2029 12.0318C15.1676 12.0659 15.1319 12.0996 15.0958 12.1328C15.0597 12.1661 15.0232 12.1989 14.9863 12.2312C14.9494 12.2636 14.9121 12.2955 14.8744 12.3269C14.8368 12.3584 14.7987 12.3894 14.7603 12.4198C14.7218 12.4504 14.683 12.4804 14.6438 12.51C14.6046 12.5395 14.5651 12.5686 14.5252 12.5972C14.4853 12.6258 14.4451 12.6539 14.4045 12.6815C14.3639 12.7091 14.323 12.7362 14.2818 12.7629C14.2406 12.7895 14.199 12.8156 14.1571 12.8411L11.5826 12.8411L11.5818 8.56938C11.9345 8.11637 12.3189 7.68259 12.6871 7.24198C12.8444 7.05373 13.0532 6.84832 13.1669 6.63128C13.179 6.60796 13.1894 6.58388 13.1981 6.55903C13.2068 6.53422 13.2136 6.50891 13.2186 6.4831C13.2237 6.4573 13.2268 6.43126 13.2281 6.40498C13.2294 6.37874 13.2288 6.35252 13.2263 6.32632C13.2246 6.30733 13.2219 6.28847 13.2183 6.26975C13.2147 6.251 13.2102 6.23249 13.2047 6.21421C13.1993 6.19593 13.193 6.17795 13.1858 6.16028C13.1786 6.14264 13.1706 6.12538 13.1616 6.1085C13.1527 6.09163 13.143 6.07524 13.1325 6.05933C13.122 6.04342 13.1107 6.02808 13.0986 6.0133C13.0866 5.9985 13.0738 5.98433 13.0604 5.97079C13.047 5.95728 13.0329 5.94445 13.0182 5.93229C12.8957 5.83138 12.7421 5.78833 12.5847 5.80487C12.4823 5.81558 12.3959 5.85177 12.3148 5.91455C12.1296 6.0578 11.9837 6.27211 11.8343 6.45184L11.1676 7.25282C11.1127 7.3191 11.057 7.38481 11.0007 7.44996C10.7105 7.1144 10.4294 6.76912 10.1465 6.42727C10.016 6.26963 9.88383 6.07215 9.72924 5.94043C9.64256 5.86653 9.53041 5.81711 9.41713 5.80499C9.39792 5.80287 9.37863 5.80171 9.35928 5.80152C9.33995 5.80135 9.32065 5.80214 9.30138 5.80388C9.28213 5.80561 9.26301 5.8083 9.24402 5.81194C9.22502 5.81561 9.20626 5.8202 9.18773 5.82571C9.1692 5.83126 9.151 5.83769 9.1331 5.84503C9.11521 5.85239 9.09773 5.8606 9.08066 5.86967C9.0636 5.87877 9.04703 5.8887 9.03095 5.89945C9.01485 5.9102 8.99934 5.92173 8.98443 5.93402C8.96954 5.94604 8.95529 5.9588 8.94167 5.97228C8.92805 5.98573 8.91514 5.99985 8.90296 6.01463C8.89077 6.02938 8.87936 6.04472 8.86871 6.06066C8.85807 6.07656 8.84826 6.09297 8.83927 6.10987C8.83028 6.12677 8.82216 6.14408 8.81491 6.16181C8.80766 6.17954 8.80132 6.19758 8.79589 6.21595C8.79045 6.23431 8.78598 6.2529 8.78245 6.27174C8.77889 6.29054 8.77628 6.30948 8.77463 6.32856C8.76524 6.44555 8.7951 6.55858 8.85209 6.66036C8.97599 6.88173 9.18339 7.08438 9.34691 7.28007C9.70621 7.70664 10.0631 8.1352 10.4177 8.56574C10.4361 9.05002 10.4203 9.5407 10.4203 10.0256L10.4203 12.8423L7.84268 12.8408C7.55379 12.6627 7.28149 12.4621 7.02578 12.239C6.98889 12.2068 6.95241 12.1741 6.91635 12.1409C6.88026 12.1078 6.8446 12.0743 6.80936 12.0403C6.7741 12.0063 6.73925 11.9718 6.70481 11.937C6.67041 11.9022 6.63643 11.8669 6.60287 11.8312C6.56929 11.7956 6.53616 11.7595 6.50349 11.723C6.47082 11.6865 6.43859 11.6496 6.4068 11.6123C6.37502 11.5751 6.3437 11.5374 6.31284 11.4994C6.28199 11.4613 6.2516 11.4229 6.22165 11.3842C6.19174 11.3454 6.1623 11.3063 6.13332 11.2668C6.10434 11.2273 6.07586 11.1874 6.04788 11.1472C6.01987 11.1071 5.99235 11.0666 5.96533 11.0257C5.93834 10.9848 5.91183 10.9437 5.8858 10.9021C5.8598 10.8606 5.83432 10.8188 5.80934 10.7767C5.78433 10.7346 5.75986 10.6921 5.73593 10.6494C5.71197 10.6067 5.68854 10.5637 5.66563 10.5204C5.64272 10.4771 5.62034 10.4335 5.59851 10.3897C5.57667 10.3458 5.55537 10.3017 5.53461 10.2574C5.51385 10.213 5.49363 10.1684 5.47394 10.1235C5.45426 10.0787 5.43512 10.0336 5.41654 9.9883C5.39799 9.94297 5.37997 9.89742 5.36249 9.85166C5.34501 9.80589 5.32811 9.75993 5.31179 9.71378C5.29544 9.6676 5.27965 9.62122 5.26443 9.57465C5.24922 9.52812 5.23456 9.48138 5.22047 9.43446C5.20641 9.38753 5.19292 9.34046 5.17999 9.29323C5.16705 9.24597 5.1547 9.19858 5.14293 9.15105C5.13116 9.10349 5.11996 9.05581 5.10935 9.008C5.09874 8.96016 5.08871 8.91222 5.07928 8.86416C5.06986 8.81611 5.06101 8.76794 5.05273 8.71967C5.04446 8.67139 5.03678 8.62302 5.0297 8.57455C5.02261 8.52608 5.01612 8.47753 5.01022 8.42889C5.00432 8.38029 4.99901 8.3316 4.9943 8.28282C4.98958 8.23408 4.98546 8.18528 4.98193 8.13643C4.97829 8.08672 4.97526 8.03698 4.97283 7.98721C4.97041 7.93745 4.96862 7.88766 4.96746 7.83784C4.96627 7.78802 4.96571 7.73818 4.96576 7.68834C4.96582 7.63849 4.96648 7.58867 4.96775 7.53888C4.96904 7.48906 4.97095 7.43925 4.97345 7.38946C4.97599 7.33969 4.97913 7.28997 4.98288 7.24029C4.98663 7.19058 4.991 7.14094 4.99599 7.09136C5.00096 7.04179 5.00655 6.99228 5.01278 6.94282C5.01899 6.89338 5.0258 6.84402 5.03321 6.79472C5.04066 6.74545 5.04871 6.69628 5.05737 6.6472C5.066 6.59813 5.07524 6.54916 5.08512 6.50031C5.09499 6.45145 5.10545 6.40274 5.1165 6.35416C5.12759 6.30558 5.13926 6.25714 5.15153 6.20883C5.1638 6.16053 5.17666 6.11239 5.19012 6.06442C5.2036 6.01642 5.21766 5.96861 5.2323 5.921C5.24694 5.87335 5.26217 5.82591 5.278 5.77865C5.29382 5.73139 5.31023 5.68435 5.32721 5.6375C5.3442 5.59063 5.36176 5.544 5.3799 5.4976C5.39804 5.45117 5.41676 5.40499 5.43606 5.35905C5.45533 5.31309 5.47518 5.26738 5.49561 5.22192C5.51604 5.17648 5.53702 5.13129 5.55856 5.08635C5.58009 5.04141 5.60217 4.99675 5.62481 4.95236C5.64747 4.90795 5.67067 4.86383 5.69441 4.82002C5.71815 4.77621 5.74242 4.73271 5.76724 4.6895C5.79205 4.64627 5.81739 4.60336 5.84325 4.56076C5.86914 4.5182 5.89555 4.47594 5.92249 4.43401C5.9494 4.39207 5.97683 4.35048 6.00479 4.30924C6.03274 4.26797 6.06121 4.22707 6.09018 4.18654C6.11916 4.14598 6.14863 4.1058 6.1786 4.06598C6.20855 4.02614 6.239 3.98671 6.26996 3.94767C6.30089 3.9086 6.33231 3.86992 6.36421 3.83162C6.39611 3.79335 6.42848 3.75547 6.46131 3.71798C6.49418 3.68048 6.52748 3.6434 6.56123 3.60673C6.595 3.57006 6.62923 3.53382 6.66391 3.498C6.69857 3.46219 6.73368 3.42682 6.76925 3.39188C6.80478 3.35693 6.84075 3.32242 6.87714 3.28837C6.91356 3.25432 6.95039 3.22073 6.98761 3.18759C7.02485 3.15445 7.0625 3.12176 7.10055 3.08953C7.13857 3.05733 7.177 3.0256 7.21585 2.99433C7.25467 2.96309 7.29387 2.93233 7.33346 2.90203C7.37305 2.87175 7.41302 2.84196 7.45335 2.81266C7.49369 2.78338 7.53438 2.75459 7.57544 2.72631C7.61649 2.69802 7.65787 2.67024 7.69959 2.64297C7.74133 2.61573 7.7834 2.589 7.8258 2.56278C7.86821 2.53657 7.91093 2.51088 7.95397 2.48574C7.99698 2.46057 8.0403 2.43595 8.08395 2.41188C8.12759 2.38778 8.17154 2.36424 8.21579 2.34124C8.26001 2.31825 8.30451 2.29581 8.34929 2.27391C8.39406 2.25202 8.43911 2.2307 8.48444 2.20994C8.52974 2.18915 8.57529 2.16894 8.62112 2.14931C8.66694 2.12965 8.713 2.11057 8.75929 2.09207C8.80555 2.07357 8.85205 2.05565 8.89878 2.03831C8.94551 2.02097 8.99245 2.00421 9.0396 1.98802C9.08674 1.97184 9.13408 1.95623 9.18161 1.94121C9.22914 1.92621 9.27685 1.91179 9.32474 1.89795C9.37263 1.88414 9.42069 1.8709 9.46891 1.85825C9.51713 1.84562 9.5655 1.83359 9.61403 1.82214C9.66255 1.8107 9.7112 1.79987 9.75997 1.78964C9.80877 1.77941 9.85768 1.76979 9.9067 1.76077C9.95572 1.75173 10.0049 1.74331 10.0541 1.7355C10.1033 1.7277 10.1526 1.72052 10.202 1.71396C10.2514 1.70737 10.3009 1.7014 10.3505 1.69605C10.4001 1.6907 10.4497 1.68596 10.4993 1.68182C10.549 1.67772 10.5987 1.67421 10.6485 1.67132Z" fill="#FED17F"/>
</svg>
src/assets/icons/example/loading.svg
比對新檔案
@@ -0,0 +1,4 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M34.1633 5.48664C35.4588 5.29413 36.7781 5.61759 37.8376 6.38749C38.8971 7.1574 39.6122 8.31227 39.8292 9.60385C40.0462 10.8954 39.7478 12.2206 38.9981 13.2945C38.2484 14.3684 37.1072 15.1052 35.82 15.3466C29.9971 16.3355 24.7122 19.3534 20.9014 23.8658C17.0907 28.3782 15.0001 34.0937 15 40C15 46.6304 17.6339 52.9892 22.3223 57.6776C27.0107 62.3661 33.3696 65 40 65V75C20.67 75 5 59.3333 5 40C5 22.85 17.42 8.29998 34.1633 5.48664Z" fill="#0D6CF2"/>
<path d="M56.3067 14.3267C56.7451 13.8375 57.2757 13.4395 57.8681 13.1555C58.4604 12.8715 59.1029 12.7069 59.7589 12.6713C60.4149 12.6357 61.0714 12.7298 61.691 12.948C62.3106 13.1663 62.8812 13.5045 63.37 13.9433C67.034 17.2228 69.964 21.2391 71.9682 25.7294C73.9724 30.2197 75.0055 35.0827 75 40C75 59.3333 59.33 75 40 75V65C45.0605 65.0001 50.0019 63.4644 54.171 60.5959C58.3401 57.7275 61.5404 53.6614 63.3491 48.9351C65.1578 44.2088 65.4895 39.0449 64.3005 34.1261C63.1115 29.2072 60.4577 24.765 56.69 21.3867C55.7031 20.5012 55.1082 19.26 55.0364 17.936C54.9645 16.6121 55.4214 15.3138 56.3067 14.3267Z" fill="#0D6CF2"/>
</svg>
src/main.ts
@@ -3,6 +3,7 @@
import { worker } from '@/mocks/browser.js'
import App from './App.vue'
import router from './router'
import iconifyPlugin from '@/plugins/icons'
import '@/assets/css/main.css'
if (import.meta.env.VITE_NODE_ENV === 'development') {
@@ -13,5 +14,6 @@
app.use(createPinia())
app.use(router)
app.use(iconifyPlugin)
app.mount('#app')
src/plugins/icons/index.ts
比對新檔案
@@ -0,0 +1,9 @@
import { addCollection } from '@iconify/vue'
import icons from '@/assets/icons/iconifyIcons.auto.json'
export default {
  install: () => {
    // 註冊 Iconify 圖示集合
    addCollection(icons)
  },
}
vite-plugins/auto-generate-icon/generateIconifyJson.ts
比對新檔案
@@ -0,0 +1,97 @@
import { promises as fs } from 'node:fs'
import path from 'node:path'
import { importDirectory, cleanupSVG, runSVGO, parseColors, isEmptyColor } from '@iconify/tools'
export default async function generateIconifyJson(): Promise<void> {
  const sourceDir = './src/assets/icons'
  const jsonOutputDir = './src/assets/icons'
  const jsonFileName = 'iconifyIcons.auto.json'
  const typeOutputDir = './src/types'
  const typeFileName = 'icons.auto.ts'
  const iconNames: string[] = []
  /** 方法:檢查是否是來自於 colored 資料夾的檔案 */
  const isInColoredFolder = (keyword: string): boolean => keyword.startsWith('colored-')
  // Import icons
  const iconSet = await importDirectory(sourceDir, {
    // 將資料夾名稱納為 Icon 的前綴之一
    // 強制轉換成小寫,並取代所有 "_" 為 "-" ,否則 <Icon> 無法使用
    keyword: (fileEntry) =>
      fileEntry.subdir.replace(/\//g, '-').concat(fileEntry.file.replace(/_/g, '-')).toLowerCase(),
  })
  // Validate, clean up, fix palette and optimise
  iconSet.forEach((name: string, type: string) => {
    if (type !== 'icon') {
      console.log(`Type is not icon: ${name}`)
      return
    }
    const svg = iconSet.toSVG(name)
    if (!svg) {
      // Invalid icon
      iconSet.remove(name)
      console.log(`Invalid: ${name}`)
      return
    }
    // Clean up and optimise icons
    try {
      // Clean up icon code
      cleanupSVG(svg)
      if (!isInColoredFolder(name)) {
        // Assume icon is monotone: replace color with currentColor, add if missing
        parseColors(svg, {
          defaultColor: 'currentColor',
          callback: (_attr, colorStr, color) => {
            return !color || isEmptyColor(color) ? colorStr : 'currentColor'
          },
        })
      }
      // Optimise
      runSVGO(svg)
    } catch (err) {
      // Invalid icon
      console.error(`Error parsing ${name}:`, err)
      iconSet.remove(name)
      return
    }
    // Update icon
    iconSet.fromSVG(name, svg)
    iconNames.push(name)
  })
  // Export as IconifyJSON
  const iconifyJson = JSON.stringify(iconSet.export(), null, '\t') + '\n'
  // 生成 TypeScript 型別
  const iconTypeString = `export type GeneratedIconNames = ${
    iconNames.length ? iconNames.map((name) => `"${name}"`).join(' | ') : 'string'
  };
// 擴展 @iconify/vue 的 Icon 元件型別
declare module '@iconify/vue' {
  // 透過 interface 合併來約束 icon 屬性型別
  export interface IconProps {
    icon: GeneratedIconNames
  }
}
`
  // Create output directory if it doesn't exist
  await fs.mkdir(jsonOutputDir, { recursive: true })
  await fs.mkdir(typeOutputDir, { recursive: true })
  // Save to file
  const jsonOutputFile = path.join(jsonOutputDir, jsonFileName)
  const typeOutputFile = path.join(typeOutputDir, typeFileName)
  await fs.writeFile(jsonOutputFile, iconifyJson, 'utf8')
  await fs.writeFile(typeOutputFile, iconTypeString, 'utf8')
  console.log(`Icons have been processed and saved to ${jsonOutputFile}`)
}
vite-plugins/auto-generate-icon/index.ts
比對新檔案
@@ -0,0 +1,55 @@
import generateIconifyJson from './generateIconifyJson'
import chokidar from 'chokidar'
import { Plugin } from 'vite'
export default function autoGenerateIcon(): Plugin[] {
  const watchDir = './src/assets/icons'
  return [
    {
      name: 'watch-and-generate-icons',
      // 僅適用於開發模式
      apply: 'serve',
      configureServer(server) {
        function debounce(fn: (...args: unknown[]) => void, delay = 500) {
          let timer: NodeJS.Timeout
          return (...args: unknown[]) => {
            clearTimeout(timer)
            timer = setTimeout(() => {
              fn(...args)
            }, delay)
          }
        }
        async function onDirUpdated() {
          try {
            await generateIconifyJson()
            console.log('[vite-plugin-watch-and-generate-icons] generated')
          } catch (error) {
            console.error(
              `[vite-plugin-watch-and-generate-icons] failure: \n${(error as Error).message}`,
            )
          }
          server.ws.send({ type: 'full-reload' }) // 通知 Vite 重新載入
        }
        const debouncedOnSvgUpdateHandler = debounce(onDirUpdated, 500)
        // 啟動 Vite 開發伺服器時執行
        console.log(`[vite-plugin-watch-and-generate-icons] listening file system on: ${watchDir}`)
        const watcher = chokidar.watch(watchDir, {
          ignored: [/\.auto\.json/],
        })
        watcher.on('all', async (_event, path) => {
          debouncedOnSvgUpdateHandler(path)
        })
        // 停止監聽
        server.httpServer?.on('close', () => watcher.close())
      },
    },
  ]
}
vite-plugins/build-validator/index.ts
比對新檔案
@@ -0,0 +1,47 @@
import { Plugin } from 'vite'
import { exec } from 'child_process'
import { promisify } from 'util'
import generateIconifyJson from '../auto-generate-icon/generateIconifyJson'
const execAsync = promisify(exec)
export default function buildValidator(): Plugin {
  return {
    name: 'vite-plugin-build-validator',
    apply: 'build',
    async buildStart() {
      try {
        // 第一步:執行 generateIconifyJson
        console.log('[vite-plugin-build-validator] 開始產生 Icon...')
        await generateIconifyJson()
        console.log('[vite-plugin-build-validator] Icon 產生成功')
        // 第二步:執行 vue-tsc
        console.log('[vite-plugin-build-validator] 開始執行類型檢查...')
        try {
          const { stdout, stderr } = await execAsync('npx vue-tsc')
          if (stderr && stderr.includes('error')) {
            console.error(`[vite-plugin-build-validator] vue-tsc 類型錯誤: \n${stderr}`)
            throw new Error('類型檢查失敗')
          }
          if (stdout) {
            console.log(`[vite-plugin-build-validator] vue-tsc 輸出: \n${stdout}`)
          }
        } catch (typescriptError) {
          console.warn(`stdout: ${(typescriptError as { stdout?: string })?.stdout}`)
          console.error('[vite-plugin-build-validator] vue-tsc 執行失敗')
          throw new Error('類型檢查執行失敗')
        }
        console.log('[vite-plugin-build-validator] 類型檢查通過')
      } catch (error) {
        console.error(`[vite-plugin-build-validator] 建構驗證失敗: \n${(error as Error).message}`)
        // 中斷 Vite 的建構過程
        process.exit(1)
      }
    },
  }
}
vite.config.ts
@@ -1,14 +1,15 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import autoGenerateIcon from './vite-plugins/auto-generate-icon/index'
import buildValidator from './vite-plugins/build-validator'
// https://vite.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx(), vueDevTools(), tailwindcss()],
  plugins: [vue(), vueJsx(), vueDevTools(), tailwindcss(), autoGenerateIcon(), buildValidator()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),