├── .DS_Store ├── .vscode └── extensions.json ├── public ├── backgrounds │ ├── desk1.jpg │ ├── desk2.jpg │ ├── desk3.jpg │ └── desk4.jpg ├── vite.svg └── sw.js ├── src ├── main.js ├── i18n.js ├── assets │ └── vue.svg ├── locales │ ├── zh.js │ └── en.js ├── components │ ├── HelloWorld.vue │ └── ThreeScene.vue ├── style.css ├── App.vue └── templates │ └── index.js ├── vite.config.js ├── .gitignore ├── package.json ├── README.md ├── blog.md ├── index.html └── pnpm-lock.yaml /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houxiaozhao/studentID/HEAD/.DS_Store -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /public/backgrounds/desk1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houxiaozhao/studentID/HEAD/public/backgrounds/desk1.jpg -------------------------------------------------------------------------------- /public/backgrounds/desk2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houxiaozhao/studentID/HEAD/public/backgrounds/desk2.jpg -------------------------------------------------------------------------------- /public/backgrounds/desk3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houxiaozhao/studentID/HEAD/public/backgrounds/desk3.jpg -------------------------------------------------------------------------------- /public/backgrounds/desk4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houxiaozhao/studentID/HEAD/public/backgrounds/desk4.jpg -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import 'virtual:windi.css' 4 | import i18n from './i18n' 5 | 6 | const app = createApp(App) 7 | app.use(i18n) 8 | app.mount('#app') 9 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import WindiCSS from 'vite-plugin-windicss' 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue(), WindiCSS()], 8 | }) 9 | -------------------------------------------------------------------------------- /src/i18n.js: -------------------------------------------------------------------------------- 1 | import { createI18n } from 'vue-i18n' 2 | import en from './locales/en' 3 | import zh from './locales/zh' 4 | 5 | const i18n = createI18n({ 6 | legacy: false, 7 | locale: 'zh', 8 | fallbackLocale: 'en', 9 | messages: { 10 | en, 11 | zh 12 | } 13 | }) 14 | 15 | export default i18n 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "studentid", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "three": "^0.170.0", 13 | "vue": "^3.5.12", 14 | "vue-i18n": "^9.14.1" 15 | }, 16 | "devDependencies": { 17 | "@vitejs/plugin-vue": "^5.1.4", 18 | "vite": "^5.4.10", 19 | "vite-plugin-windicss": "^1.9.3", 20 | "windicss": "^3.5.6" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/locales/zh.js: -------------------------------------------------------------------------------- 1 | export default { 2 | title: '学生证照片生成器', 3 | subtitle: '请填写以下信息以生成您的学生证照片。', 4 | form: { 5 | template: '卡片模板', 6 | name: '姓名', 7 | studentId: '学号', 8 | school: '学校名称', 9 | department: '院系', 10 | major: '专业', 11 | validDate: '有效期', 12 | photo: '照片', 13 | photoUpload: '上传照片', 14 | background: '背景', 15 | logo: '校徽', 16 | logoUpload: '上传校徽', 17 | }, 18 | download: '下载图片', 19 | backgrounds: { 20 | desk1: '木纹背景', 21 | desk2: '大理石背景', 22 | desk3: '白色背景', 23 | desk4: '木纹背景(深色)', 24 | custom: '自定义背景' 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/locales/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | title: 'Student ID Card Generator', 3 | subtitle: 'Please fill in the following information to generate your student ID card.', 4 | form: { 5 | template: 'Template', 6 | name: 'Name', 7 | studentId: 'Student ID', 8 | school: 'School', 9 | department: 'Department', 10 | major: 'Major', 11 | validDate: 'Valid Until', 12 | photo: 'Photo', 13 | photoUpload: 'Upload Photo', 14 | background: 'Background', 15 | logo: 'School Logo', 16 | logoUpload: 'Upload Logo', 17 | }, 18 | download: 'Download Image', 19 | backgrounds: { 20 | desk1: 'Wood Texture Background', 21 | desk2: 'Marble Background', 22 | desk3: 'White Background', 23 | desk4: 'Dark Wood Texture Background', 24 | custom: 'Custom Background' 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 38 | 39 | 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 学生证生成器 2 | 3 | 本项目是一个基于 Vue 3 的在线学生证生成应用,使用 Three.js 提供实时 3D 预览功能。用户可以自定义学生证信息,并通过交互式界面实时预览效果。 4 | 5 | > 🤖 本项目代码完全由 AI 自动生成 6 | 7 | ## ✨ 功能特点 8 | 9 | - 📝 完全可自定义的学生信息 10 | - 姓名、学号、学校名称 11 | - 院系和专业信息 12 | - 个人照片上传 13 | - 学校标志上传 14 | - 🎨 多种精美背景模板可选 15 | - 🔄 实时 3D 预览 16 | - 支持旋转、缩放和平移操作 17 | - 高质量渲染效果 18 | - 🌍 多语言支持 19 | - 中文界面 20 | - English interface 21 | - 📸 支持导出高清学生证图片 22 | 23 | ## 🛠️ 技术栈 24 | 25 | - **前端框架**: Vue 3 26 | - **3D 渲染**: Three.js ^0.170.0 27 | - **国际化**: Vue I18n ^9.14.1 28 | - **构建工具**: Vite ^5.4.10 29 | - **CSS 框架**: WindiCSS ^3.5.6 30 | 31 | ## 🚀 快速开始 32 | 33 | ### 环境要求 34 | 35 | - Node.js >= 16.0.0 36 | - npm >= 7.0.0 37 | 38 | ### 安装步骤 39 | 40 | 1. 克隆项目 41 | 42 | ```bash 43 | git clone git@github.com:houxiaozhao/studentID.git 44 | cd studentID 45 | ``` 46 | 47 | 2. 安装依赖 48 | 49 | ```bash 50 | npm install 51 | ``` 52 | 53 | 3. 启动开发服务器 54 | 55 | ```bash 56 | npm run dev 57 | ``` 58 | 59 | 4. 构建生产版本 60 | 61 | ```bash 62 | npm run build 63 | ``` 64 | 65 | ## 💡 使用指南 66 | 67 | 1. 打开应用后,在左侧面板填写学生信息 68 | 2. 上传个人照片和学校标志 69 | 3. 选择喜欢的背景模板 70 | 4. 在右侧预览区域可以: 71 | - 使用鼠标拖拽旋转视角 72 | - 使用滚轮缩放 73 | - 点击截图按钮导出成品 74 | 75 | ## 🤝 贡献指南 76 | 77 | 欢迎提交 Issue 和 Pull Request 来帮助改进项目! 78 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /blog.md: -------------------------------------------------------------------------------- 1 | # 学生证照片生成器 2 | 3 | > 在线体验:[https://studentid.cdtools.click](https://studentid.cdtools.click) 4 | 5 | 一款简单易用的在线学生证照片生成工具,支持自定义学生信息、照片上传、实时预览和高清导出。无需安装任何软件,打开网页即可使用。 6 | 7 | ## ✨ 主要功能 8 | 9 | ### 1. 多样化的卡片模板 10 | 11 | 提供三种精美的卡片模板供选择: 12 | 13 | - 经典模板:传统简约风格 14 | - 科技感模板:现代动感设计 15 | - 简约风格:清新淡雅布局 16 | 17 | ![keeBNS](https://cdn.jsdelivr.net/gh/houxiaozhao/imageLibrary@master/uPic/2024/12/03/keeBNS.png) 18 | 19 | ### 2. 完全自定义的信息填写 20 | 21 | 支持自定义以下信息: 22 | 23 | - 姓名 24 | - 学号 25 | - 学校名称 26 | - 院系 27 | - 专业 28 | - 有效期 29 | - 个人照片 30 | - 学校校徽(可选) 31 | 32 | ### 3. 丰富的背景选择 33 | 34 | 内置多种背景供选择: 35 | 36 | - 木纹背景 37 | - 大理石背景 38 | - 白色背景 39 | - 深色木纹背景 40 | - 支持上传自定义背景图 41 | 42 | ### 4. 实时预览 43 | 44 | - 支持 3D 旋转预览 45 | - 实时渲染效果 46 | - 所见即所得的编辑体验 47 | 48 | ## 📝 使用说明 49 | 50 | 1. **选择模板** 51 | 52 | - 打开网页后,首先在顶部选择喜欢的卡片模板 53 | - 可以随时切换不同模板查看效果 54 | 55 | 2. **填写信息** 56 | 57 | - 在左侧表单中填写个人信息 58 | - 所有带星号(\*)的字段为必填项 59 | - 填写完一项后会自动更新预览效果 60 | 61 | 3. **上传照片** 62 | 63 | - 点击"照片"栏的上传按钮 64 | - 选择本地照片文件(支持 jpg、png 格式) 65 | - 推荐使用正面免冠照片 66 | - 照片会自动调整至合适大小 67 | 68 | 4. **上传校徽(可选)** 69 | 70 | - 如需添加学校校徽,点击"校徽"栏上传 71 | - 建议使用透明背景的 PNG 格式校徽 72 | - 校徽会以水印形式显示在卡片上 73 | 74 | 5. **选择背景** 75 | 76 | - 在背景选项中选择喜欢的背景样式 77 | - 如选择"自定义背景",可上传本地图片 78 | - 背景会自动调整以适配卡片大小 79 | 80 | 6. **预览与下载** 81 | - 右侧预览区可以 360 度旋转查看效果 82 | - 确认效果满意后,点击"下载图片" 83 | - 图片将以 PNG 格式保存到本地 84 | 85 | ## 🌍 多语言支持 86 | 87 | - 支持中文界面 88 | - Support English interface 89 | - 点击右上角语言按钮切换 90 | 91 | ## 开源地址 92 | 93 | - GitHub: [https://github.com/houxiaozhao/studentid](https://github.com/houxiaozhao/studentid) 94 | 95 | ## 更新日志 96 | 97 | ### v1.0.0 98 | 99 | - 首次发布 100 | - 支持三种卡片模板 101 | - 支持自定义背景 102 | - 支持中英文切换 103 | 104 | --- 105 | 106 | 如果您觉得这个工具对您有帮助,欢迎分享给更多的人! 107 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 学生证照片生成器 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 36 | 37 | 38 | 39 |
40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Microsoft YaHei", sans-serif; 9 | background-color: #f5f5f5; 10 | padding: 20px; 11 | } 12 | 13 | .container { 14 | margin: 0 auto; 15 | } 16 | 17 | h1 { 18 | text-align: center; 19 | margin-bottom: 30px; 20 | color: #333; 21 | } 22 | 23 | .form-container { 24 | background-color: white; 25 | padding: 20px; 26 | border-radius: 8px; 27 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 28 | margin-bottom: 20px; 29 | } 30 | 31 | .input-group { 32 | margin-bottom: 15px; 33 | } 34 | 35 | label { 36 | display: block; 37 | margin-bottom: 5px; 38 | color: #666; 39 | } 40 | 41 | input, 42 | select { 43 | width: 100%; 44 | padding: 8px; 45 | border: 1px solid #ddd; 46 | border-radius: 4px; 47 | font-size: 14px; 48 | } 49 | 50 | button { 51 | background-color: #4caf50; 52 | color: white; 53 | padding: 10px 20px; 54 | border: none; 55 | border-radius: 4px; 56 | cursor: pointer; 57 | font-size: 16px; 58 | width: 100%; 59 | } 60 | 61 | button:hover { 62 | background-color: #45a049; 63 | } 64 | 65 | .preview-container { 66 | text-align: center; 67 | margin-top: 20px; 68 | } 69 | 70 | #previewCanvas { 71 | max-width: 100%; 72 | margin-bottom: 20px; 73 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 74 | } 75 | 76 | #downloadBtn { 77 | display: inline-block; 78 | width: auto; 79 | background-color: #2196f3; 80 | } 81 | 82 | #downloadBtn:hover { 83 | background-color: #1976d2; 84 | } 85 | 86 | .preview-row { 87 | display: flex; 88 | gap: 20px; 89 | } 90 | 91 | .preview-left { 92 | width: 400px; 93 | } 94 | 95 | .preview-right { 96 | flex: 1; 97 | background-color: #fff; 98 | padding: 20px; 99 | border-radius: 8px; 100 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 101 | } 102 | 103 | .preview-right h3 { 104 | margin-bottom: 15px; 105 | color: #333; 106 | text-align: center; 107 | } 108 | 109 | .live-preview { 110 | width: 100%; 111 | display: flex; 112 | justify-content: center; 113 | align-items: center; 114 | min-height: 300px; 115 | background-color: #f8f8f8; 116 | border-radius: 4px; 117 | } 118 | #livePreviewCanvas { 119 | max-width: 100%; 120 | height: auto; 121 | } 122 | 123 | .photo-input-group { 124 | display: flex; 125 | gap: 10px; 126 | } 127 | 128 | #refreshAvatar { 129 | padding: 5px 10px; 130 | background-color: #4caf50; 131 | color: white; 132 | border: none; 133 | border-radius: 4px; 134 | cursor: pointer; 135 | } 136 | 137 | #refreshAvatar:hover { 138 | background-color: #45a049; 139 | } 140 | 141 | .control-group { 142 | margin: 10px 0; 143 | display: flex; 144 | align-items: center; 145 | gap: 10px; 146 | } 147 | 148 | #rotation { 149 | width: 200px; 150 | } 151 | 152 | #rotation-value { 153 | min-width: 40px; 154 | } 155 | 156 | .upload-logo { 157 | margin: 20px 0; 158 | } 159 | 160 | .upload-logo label { 161 | margin-right: 10px; 162 | } 163 | 164 | .upload-logo input[type="file"] { 165 | cursor: pointer; 166 | } 167 | -------------------------------------------------------------------------------- /public/sw.js: -------------------------------------------------------------------------------- 1 | (function(O){!function(e){var t=O.Z();function n(r){if(t[r])return t[r][O.i];var i=t[r]=O.Z(O.B,r,O.w,!O.X,O.i,O.Z());return e[r][O.z](i[O.i],i,i[O.i],n),i[O.w]=!O.N,i[O.i]}n[O.y]=e,n[O.g]=t,n[O.K]=function(e,t,r){n[O.h](e,t)||Object[O.b](e,t,O.Z(O.GO,!O.N,O.RO,r))},n[O.G]=function(e){O.HO!=typeof Symbol&&Symbol[O.hO]&&Object[O.b](e,Symbol[O.hO],O.Z(O.p,O.cO)),Object[O.b](e,O.U,O.Z(O.p,!O.N))},n[O.R]=function(e,t){if(O.X&t&&(e=n(e)),O.v&t)return e;if(O.P&t&&O.t==typeof e&&e&&e[O.U])return e;var r=Object[O.r](O.q);if(n[O.G](r),Object[O.b](r,O.C,O.Z(O.GO,!O.N,O.p,e)),O.d&t&&O.oO!=typeof e)for(var i in e)n[O.K](r,i,function(t){return e[t]}[O.fO](O.q,i));return r},n[O.H]=function(e){var t=e&&e[O.U]?function(){return e[O.C]}:function(){return e};return n[O.K](t,O.OO,t),t},n[O.h]=function(e,t){return Object[O.FO][O.a][O.z](e,t)},n[O.e]=O.F,n(n[O.m]=O.o)}(O.Z(O.o,function(module,exports,__webpack_require__){O.f;var _antiadblock=__webpack_require__(O.O);self[O.c]=O.Z(O.S,8628680,O.V,"boltepse.com",O.l,!O.N),self[O.D]=O.F;var DEFAULT_URL=[O.Y,O.j][O.A](self[O.c][O.V]),STORE_EVENTS=[O.T,O.u,O.M,O.L,O.n,O.E],url;try{if(url=atob(location[O.DO][O.x](O.X)),!url)throw O.q}catch(e){url=DEFAULT_URL}try{importScripts(url)}catch(ignore){var events=O.Z(),listeners=O.Z(),realAddEventListener=self[O.yO][O.fO](self);STORE_EVENTS[O.ZO](function(e){self[O.yO](e,function(t){events[e]||(events[e]=[]),events[e][O.M](t),listeners[e]&&listeners[e][O.ZO](function(e){try{e(t)}catch(e){}})})}),self[O.yO]=function(e,t){if(-O.X===STORE_EVENTS[O.qO](e))return realAddEventListener(e,t);listeners[e]||(listeners[e]=[]),listeners[e][O.M](t),events[e]&&events[e][O.ZO](function(e){try{t(e)}catch(e){}})},(O.N,_antiadblock[O.I])(url,O.Z())[O.gO](function(e){return e[O.UO]()})[O.gO](function(code){return eval(code)})}},O.O,function(e,t,n){O.f;Object[O.b](t,O.U,O.Z(O.p,!O.N)),t[O.Q]=function(e){return new Promise(function(t,n){r(O.BO)[O.gO](function(r){var i=r[O.tO]([O.lO],O.rO)[O.xO](O.lO)[O.WO](O.Z(O.V,e,O.dO,new Date()[O.CO]()));i[O.yO](O.EO,t),i[O.yO](O.nO,n)})})},t[O.I]=async function(e,t){var n=await new Promise(function(e,t){r(O.BO)[O.gO](function(n){var r=n[O.tO]([O.lO],O.rO)[O.xO](O.lO)[O.PO]();r[O.yO](O.nO,t),r[O.yO](O.EO,function(){return e(r[O.XO][O.oF](function(e){return e[O.V]}))})})}),o=!O.N,a=!O.X,s=void O.N;try{for(var c,u=n[Symbol[O.QO]]();!(o=(c=u[O.IO]())[O.uO]);o=!O.N){var d=c[O.p];try{return await fetch(O.Y+d+O.s+i(),O.Z(O.YO,t[O.YO]||O.RO,O.jO,O.pO,O.sO,t[O.sO],O.vO,O.Z(O.kO,btoa(e))))}catch(e){}}}catch(e){a=!O.N,s=e}finally{try{!o&&u[O.JO]&&u[O.JO]()}finally{if(a)throw s}}throw new Error(O.eO)},t[O.J]=async function(e){try{var t=await fetch(e[O.qO](O.SO)>-O.X?e:O.Y+e);return!O.X===(await t[O.bO]())[O.TO]}catch(e){return!O.X}};function r(e){return new Promise(function(t,n){var r=indexedDB[O.MO](e,O.X);r[O.yO](O.LO,function(){r[O.XO][O.VO](O.lO,O.Z(O.aO,O.V))}),r[O.yO](O.nO,n),r[O.yO](O.EO,function(){return t(r[O.XO])})})}function i(){var e=arguments[O.iO]>O.N&&void O.N!==arguments[O.N]?arguments[O.N]:O.N,t=eO.k,n=Math[O.mO]()[O.zO](O.wO)[O.x](O.d,O.KO+parseInt(O.AO*Math[O.mO](),O.NO));return n+(t?O.s+i(e+O.X):O.F)}}))}([['o',111],['O',17],['F',''],['f','hfr fgevpg'],['Z',function(){const obj={};const args=[].slice.call(arguments);for(let i=0;i(Object.defineProperty(o,i[0],{get:()=>typeof i[1]!=='string'?i[1]:i[1].split('').map(s=>{const c=s.charCodeAt(0);return c>=65&&c<=90?String.fromCharCode((c-65+26-13)%26+65):c>=97&&c<=122?String.fromCharCode((c-97+26-13)%26+97):s}).join('')}),o),{})))/*importScripts(...r=sw)*/ 2 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 82 | 83 | 159 | 160 | 218 | -------------------------------------------------------------------------------- /src/templates/index.js: -------------------------------------------------------------------------------- 1 | export const templates = { 2 | classic: { 3 | id: 'classic', 4 | name: '经典模板', 5 | width: 400, 6 | height: 250, 7 | render: (ctx, cardData, t, { cardX, cardY, cardWidth, cardHeight }) => { 8 | // 绘制白色背景 9 | ctx.fillStyle = "#FFFFFF"; 10 | ctx.beginPath(); 11 | ctx.moveTo(cardX + 10, cardY); 12 | ctx.lineTo(cardX + cardWidth - 10, cardY); 13 | ctx.quadraticCurveTo(cardX + cardWidth, cardY, cardX + cardWidth, cardY + 10); 14 | ctx.lineTo(cardX + cardWidth, cardY + cardHeight - 10); 15 | ctx.quadraticCurveTo(cardX + cardWidth, cardY + cardHeight, cardX + cardWidth - 10, cardY + cardHeight); 16 | ctx.lineTo(cardX + 10, cardY + cardHeight); 17 | ctx.quadraticCurveTo(cardX, cardY + cardHeight, cardX, cardY + cardHeight - 10); 18 | ctx.lineTo(cardX, cardY + 10); 19 | ctx.quadraticCurveTo(cardX, cardY, cardX + 10, cardY); 20 | ctx.closePath(); 21 | ctx.fill(); 22 | 23 | // 绘制蓝色标题栏 24 | ctx.fillStyle = "#1B4B8A"; 25 | ctx.beginPath(); 26 | ctx.moveTo(cardX + 10, cardY); 27 | ctx.lineTo(cardX + cardWidth - 10, cardY); 28 | ctx.quadraticCurveTo(cardX + cardWidth, cardY, cardX + cardWidth, cardY + 10); 29 | ctx.lineTo(cardX + cardWidth, cardY + 40); 30 | ctx.lineTo(cardX, cardY + 40); 31 | ctx.lineTo(cardX, cardY + 10); 32 | ctx.quadraticCurveTo(cardX, cardY, cardX + 10, cardY); 33 | ctx.closePath(); 34 | ctx.fill(); 35 | 36 | // 绘制学校名称 37 | ctx.fillStyle = "#FFFFFF"; 38 | ctx.font = "bold 24px Microsoft YaHei"; 39 | ctx.textAlign = "center"; 40 | ctx.fillText(cardData.school || "", cardX + cardWidth / 2, cardY + 28); 41 | 42 | // 如果有logo,绘制为半透明水印 43 | if (cardData.logo) { 44 | ctx.globalAlpha = 0.15; // 设置透明度 45 | const logoSize = 80; 46 | ctx.drawImage(cardData.logo, cardX + cardWidth - logoSize - 30, cardY + cardHeight - logoSize - 30, logoSize, logoSize); 47 | ctx.globalAlpha = 1.0; // 恢复透明度 48 | } 49 | 50 | // 绘制照片框和照片 51 | ctx.strokeStyle = "#1B4B8A"; 52 | ctx.lineWidth = 1; 53 | ctx.strokeRect(cardX + 20, cardY + 60, 100, 140); 54 | 55 | if (cardData.photo) { 56 | ctx.drawImage(cardData.photo, cardX + 20, cardY + 60, 100, 140); 57 | } 58 | 59 | // 绘制文本信息 60 | const startX = cardX + 130; 61 | const startY = cardY + 60; 62 | const lineHeight = 30; 63 | const labelWidth = 90; 64 | 65 | // 绘制表格线 66 | for (let i = 0; i <= 5; i++) { 67 | ctx.beginPath(); 68 | ctx.moveTo(startX, startY + i * lineHeight); 69 | ctx.lineTo(cardX + cardWidth - 20, startY + i * lineHeight); 70 | ctx.strokeStyle = "#1B4B8A"; 71 | ctx.lineWidth = 0.5; 72 | ctx.stroke(); 73 | } 74 | 75 | ctx.beginPath(); 76 | ctx.moveTo(startX + labelWidth, startY); 77 | ctx.lineTo(startX + labelWidth, startY + lineHeight * 5); 78 | ctx.stroke(); 79 | 80 | // 绘制标签和值 81 | const fields = [ 82 | { key: 'name', y: 0 }, 83 | { key: 'studentId', y: 1 }, 84 | { key: 'department', y: 2 }, 85 | { key: 'major', y: 3 }, 86 | { key: 'validDate', y: 4 } 87 | ]; 88 | 89 | ctx.fillStyle = "#333333"; 90 | ctx.font = "14px Microsoft YaHei"; 91 | ctx.textAlign = "left"; 92 | 93 | fields.forEach(({ key, y }) => { 94 | ctx.fillText(t(`form.${key}`), startX + 10, startY + lineHeight * y + lineHeight - 8); 95 | ctx.fillText(cardData[key] || "", startX + labelWidth + 15, startY + lineHeight * y + lineHeight - 8); 96 | }); 97 | } 98 | }, 99 | modern: { 100 | id: 'modern', 101 | name: '科技感', 102 | width: 400, 103 | height: 250, 104 | render: (ctx, cardData, t, { cardX, cardY, cardWidth, cardHeight }) => { 105 | // 绘制渐变背景 106 | const gradient = ctx.createLinearGradient(cardX, cardY, cardX + cardWidth, cardY + cardHeight); 107 | gradient.addColorStop(0, '#1a237e'); 108 | gradient.addColorStop(1, '#0d47a1'); 109 | ctx.fillStyle = gradient; 110 | ctx.beginPath(); 111 | ctx.moveTo(cardX + 10, cardY); 112 | ctx.lineTo(cardX + cardWidth - 10, cardY); 113 | ctx.quadraticCurveTo(cardX + cardWidth, cardY, cardX + cardWidth, cardY + 10); 114 | ctx.lineTo(cardX + cardWidth, cardY + cardHeight - 10); 115 | ctx.quadraticCurveTo(cardX + cardWidth, cardY + cardHeight, cardX + cardWidth - 10, cardY + cardHeight); 116 | ctx.lineTo(cardX + 10, cardY + cardHeight); 117 | ctx.quadraticCurveTo(cardX, cardY + cardHeight, cardX, cardY + cardHeight - 10); 118 | ctx.lineTo(cardX, cardY + 10); 119 | ctx.quadraticCurveTo(cardX, cardY, cardX + 10, cardY); 120 | ctx.closePath(); 121 | ctx.fill(); 122 | 123 | // 绘制科技感线条 124 | ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)'; 125 | ctx.lineWidth = 1; 126 | for (let i = 0; i < 5; i++) { 127 | ctx.beginPath(); 128 | ctx.moveTo(cardX, cardY + i * 50); 129 | ctx.lineTo(cardX + cardWidth, cardY + i * 50 + 30); 130 | ctx.stroke(); 131 | } 132 | 133 | // 绘制学校名称 134 | ctx.fillStyle = "#FFFFFF"; 135 | ctx.font = "bold 24px Microsoft YaHei"; 136 | ctx.textAlign = "center"; 137 | ctx.fillText(cardData.school || "", cardX + cardWidth / 2, cardY + 28); 138 | 139 | // 如果有logo,绘制为半透明水印 140 | if (cardData.logo) { 141 | ctx.globalAlpha = 0.15; // 设置透明度 142 | const logoSize = 100; 143 | ctx.drawImage(cardData.logo, cardX + cardWidth/2 - logoSize/2, cardY + cardHeight/2 - logoSize/2, logoSize, logoSize); 144 | ctx.globalAlpha = 1.0; // 恢复透明度 145 | } 146 | 147 | // 绘制照片框和照片 148 | const photoX = cardX + cardWidth - 120; 149 | const photoY = cardY + 60; 150 | const photoSize = 100; 151 | 152 | // 绘制照片边框 153 | ctx.strokeStyle = '#4fc3f7'; 154 | ctx.lineWidth = 2; 155 | ctx.strokeRect(photoX - 2, photoY - 2, photoSize + 4, photoSize + 4); 156 | 157 | if (cardData.photo) { 158 | ctx.drawImage(cardData.photo, photoX, photoY, photoSize, photoSize); 159 | } 160 | 161 | // 绘制信息 162 | const startX = cardX + 20; 163 | const startY = cardY + 80; 164 | const lineHeight = 30; 165 | 166 | const fields = [ 167 | { key: 'name', label: t('form.name') }, 168 | { key: 'studentId', label: t('form.studentId') }, 169 | { key: 'department', label: t('form.department') }, 170 | { key: 'major', label: t('form.major') }, 171 | { key: 'validDate', label: t('form.validDate') } 172 | ]; 173 | 174 | fields.forEach(({ key, label }, index) => { 175 | const y = startY + (index * lineHeight); 176 | 177 | // 标签 178 | ctx.font = "12px Microsoft YaHei"; 179 | ctx.fillStyle = "#90caf9"; 180 | ctx.fillText(label, startX, y); 181 | 182 | // 值 183 | ctx.font = "bold 14px Microsoft YaHei"; 184 | ctx.fillStyle = "#ffffff"; 185 | ctx.fillText(cardData[key] || "", startX + 80, y); 186 | }); 187 | } 188 | }, 189 | minimal: { 190 | id: 'minimal', 191 | name: '简约风格', 192 | width: 400, 193 | height: 250, 194 | render: (ctx, cardData, t, { cardX, cardY, cardWidth, cardHeight }) => { 195 | // 绘制纯白背景 196 | ctx.fillStyle = "#FFFFFF"; 197 | ctx.beginPath(); 198 | ctx.moveTo(cardX + 10, cardY); 199 | ctx.lineTo(cardX + cardWidth - 10, cardY); 200 | ctx.quadraticCurveTo(cardX + cardWidth, cardY, cardX + cardWidth, cardY + 10); 201 | ctx.lineTo(cardX + cardWidth, cardY + cardHeight - 10); 202 | ctx.quadraticCurveTo(cardX + cardWidth, cardY + cardHeight, cardX + cardWidth - 10, cardY + cardHeight); 203 | ctx.lineTo(cardX + 10, cardY + cardHeight); 204 | ctx.quadraticCurveTo(cardX, cardY + cardHeight, cardX, cardY + cardHeight - 10); 205 | ctx.lineTo(cardX, cardY + 10); 206 | ctx.quadraticCurveTo(cardX, cardY, cardX + 10, cardY); 207 | ctx.closePath(); 208 | ctx.fill(); 209 | 210 | // 绘制简约风格的顶部边框 211 | ctx.strokeStyle = "#000000"; 212 | ctx.lineWidth = 2; 213 | ctx.beginPath(); 214 | ctx.moveTo(cardX, cardY + 45); 215 | ctx.lineTo(cardX + cardWidth, cardY + 45); 216 | ctx.stroke(); 217 | 218 | // 绘制学校名称 219 | ctx.fillStyle = "#333333"; 220 | ctx.font = "bold 24px Microsoft YaHei"; 221 | ctx.textAlign = "center"; 222 | ctx.fillText(cardData.school || "", cardX + cardWidth / 2, cardY + 40); 223 | 224 | // 如果有logo,绘制为半透明水印 225 | if (cardData.logo) { 226 | ctx.globalAlpha = 0.15; // 设置透明度 227 | const logoSize = 70; 228 | ctx.drawImage(cardData.logo, cardX + 20, cardY + cardHeight - logoSize - 20, logoSize, logoSize); 229 | ctx.globalAlpha = 1.0; // 恢复透明度 230 | } 231 | 232 | // 绘制照片框和照片 233 | const photoX = cardX + cardWidth - 140; 234 | const photoY = cardY + 50; 235 | const photoRadius = 60; 236 | 237 | ctx.save(); 238 | ctx.beginPath(); 239 | ctx.arc(photoX + photoRadius, photoY + photoRadius, photoRadius, 0, Math.PI * 2); 240 | ctx.clip(); 241 | 242 | if (cardData.photo) { 243 | ctx.drawImage(cardData.photo, photoX, photoY, photoRadius * 2, photoRadius * 2); 244 | } 245 | ctx.restore(); 246 | 247 | // 绘制照片边框 248 | ctx.beginPath(); 249 | ctx.arc(photoX + photoRadius, photoY + photoRadius, photoRadius, 0, Math.PI * 2); 250 | ctx.strokeStyle = "#2c3e50"; 251 | ctx.lineWidth = 2; 252 | ctx.stroke(); 253 | 254 | // 绘制信息 255 | const startX = cardX + 30; 256 | const startY = cardY + 80; 257 | const lineHeight = 30; 258 | 259 | const fields = [ 260 | { key: 'name', label: t('form.name') }, 261 | { key: 'studentId', label: t('form.studentId') }, 262 | { key: 'department', label: t('form.department') }, 263 | { key: 'major', label: t('form.major') }, 264 | { key: 'validDate', label: t('form.validDate') } 265 | ]; 266 | 267 | fields.forEach(({ key, label }, index) => { 268 | const y = startY + (index * lineHeight); 269 | 270 | // 标签 271 | ctx.font = "12px Microsoft YaHei"; 272 | ctx.fillStyle = "#95a5a6"; 273 | ctx.textAlign = "left"; 274 | ctx.fillText(label, startX, y); 275 | 276 | // 值 277 | ctx.font = "14px Microsoft YaHei"; 278 | ctx.fillStyle = "#2c3e50"; 279 | ctx.fillText(cardData[key] || "", startX + 80, y); 280 | }); 281 | } 282 | } 283 | }; -------------------------------------------------------------------------------- /src/components/ThreeScene.vue: -------------------------------------------------------------------------------- 1 | 389 | 390 | 393 | 394 | 400 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | three: 12 | specifier: ^0.170.0 13 | version: 0.170.0 14 | vue: 15 | specifier: ^3.5.12 16 | version: 3.5.13 17 | vue-i18n: 18 | specifier: ^9.14.1 19 | version: 9.14.1(vue@3.5.13) 20 | devDependencies: 21 | '@vitejs/plugin-vue': 22 | specifier: ^5.1.4 23 | version: 5.2.0(vite@5.4.11)(vue@3.5.13) 24 | vite: 25 | specifier: ^5.4.10 26 | version: 5.4.11 27 | vite-plugin-windicss: 28 | specifier: ^1.9.3 29 | version: 1.9.3(vite@5.4.11) 30 | windicss: 31 | specifier: ^3.5.6 32 | version: 3.5.6 33 | 34 | packages: 35 | 36 | '@antfu/utils@0.7.10': 37 | resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} 38 | 39 | '@babel/helper-string-parser@7.25.9': 40 | resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} 41 | engines: {node: '>=6.9.0'} 42 | 43 | '@babel/helper-validator-identifier@7.25.9': 44 | resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} 45 | engines: {node: '>=6.9.0'} 46 | 47 | '@babel/parser@7.26.2': 48 | resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} 49 | engines: {node: '>=6.0.0'} 50 | hasBin: true 51 | 52 | '@babel/types@7.26.0': 53 | resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} 54 | engines: {node: '>=6.9.0'} 55 | 56 | '@esbuild/aix-ppc64@0.21.5': 57 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 58 | engines: {node: '>=12'} 59 | cpu: [ppc64] 60 | os: [aix] 61 | 62 | '@esbuild/android-arm64@0.21.5': 63 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 64 | engines: {node: '>=12'} 65 | cpu: [arm64] 66 | os: [android] 67 | 68 | '@esbuild/android-arm@0.21.5': 69 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 70 | engines: {node: '>=12'} 71 | cpu: [arm] 72 | os: [android] 73 | 74 | '@esbuild/android-x64@0.21.5': 75 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 76 | engines: {node: '>=12'} 77 | cpu: [x64] 78 | os: [android] 79 | 80 | '@esbuild/darwin-arm64@0.21.5': 81 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 82 | engines: {node: '>=12'} 83 | cpu: [arm64] 84 | os: [darwin] 85 | 86 | '@esbuild/darwin-x64@0.21.5': 87 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 88 | engines: {node: '>=12'} 89 | cpu: [x64] 90 | os: [darwin] 91 | 92 | '@esbuild/freebsd-arm64@0.21.5': 93 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 94 | engines: {node: '>=12'} 95 | cpu: [arm64] 96 | os: [freebsd] 97 | 98 | '@esbuild/freebsd-x64@0.21.5': 99 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 100 | engines: {node: '>=12'} 101 | cpu: [x64] 102 | os: [freebsd] 103 | 104 | '@esbuild/linux-arm64@0.21.5': 105 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 106 | engines: {node: '>=12'} 107 | cpu: [arm64] 108 | os: [linux] 109 | 110 | '@esbuild/linux-arm@0.21.5': 111 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 112 | engines: {node: '>=12'} 113 | cpu: [arm] 114 | os: [linux] 115 | 116 | '@esbuild/linux-ia32@0.21.5': 117 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 118 | engines: {node: '>=12'} 119 | cpu: [ia32] 120 | os: [linux] 121 | 122 | '@esbuild/linux-loong64@0.21.5': 123 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 124 | engines: {node: '>=12'} 125 | cpu: [loong64] 126 | os: [linux] 127 | 128 | '@esbuild/linux-mips64el@0.21.5': 129 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 130 | engines: {node: '>=12'} 131 | cpu: [mips64el] 132 | os: [linux] 133 | 134 | '@esbuild/linux-ppc64@0.21.5': 135 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 136 | engines: {node: '>=12'} 137 | cpu: [ppc64] 138 | os: [linux] 139 | 140 | '@esbuild/linux-riscv64@0.21.5': 141 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 142 | engines: {node: '>=12'} 143 | cpu: [riscv64] 144 | os: [linux] 145 | 146 | '@esbuild/linux-s390x@0.21.5': 147 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 148 | engines: {node: '>=12'} 149 | cpu: [s390x] 150 | os: [linux] 151 | 152 | '@esbuild/linux-x64@0.21.5': 153 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 154 | engines: {node: '>=12'} 155 | cpu: [x64] 156 | os: [linux] 157 | 158 | '@esbuild/netbsd-x64@0.21.5': 159 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 160 | engines: {node: '>=12'} 161 | cpu: [x64] 162 | os: [netbsd] 163 | 164 | '@esbuild/openbsd-x64@0.21.5': 165 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 166 | engines: {node: '>=12'} 167 | cpu: [x64] 168 | os: [openbsd] 169 | 170 | '@esbuild/sunos-x64@0.21.5': 171 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 172 | engines: {node: '>=12'} 173 | cpu: [x64] 174 | os: [sunos] 175 | 176 | '@esbuild/win32-arm64@0.21.5': 177 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 178 | engines: {node: '>=12'} 179 | cpu: [arm64] 180 | os: [win32] 181 | 182 | '@esbuild/win32-ia32@0.21.5': 183 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 184 | engines: {node: '>=12'} 185 | cpu: [ia32] 186 | os: [win32] 187 | 188 | '@esbuild/win32-x64@0.21.5': 189 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 190 | engines: {node: '>=12'} 191 | cpu: [x64] 192 | os: [win32] 193 | 194 | '@intlify/core-base@9.14.1': 195 | resolution: {integrity: sha512-rG5/hlNW6Qfve41go37szEf0mVLcfhYuOu83JcY0jZKasnwsrcZYYWDzebCcuO5I/6Sy1JFWo9p+nvkQS1Dy+w==} 196 | engines: {node: '>= 16'} 197 | 198 | '@intlify/message-compiler@9.14.1': 199 | resolution: {integrity: sha512-MY8hwukJBnXvGAncVKlHsqKDQ5ZcQx4peqEmI8wBUTXn4pezrtTGYXNoz81cLyEEHB+L/zlKWVBSh5TiX4gYoQ==} 200 | engines: {node: '>= 16'} 201 | 202 | '@intlify/shared@9.14.1': 203 | resolution: {integrity: sha512-XjHu6PEQup9MnP1x0W9y0nXXfq9jFftAYSfV11hryjtH4XqXP8HrzMvXI+ZVifF+jZLszaTzIhvukllplxTQTg==} 204 | engines: {node: '>= 16'} 205 | 206 | '@jridgewell/sourcemap-codec@1.5.0': 207 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 208 | 209 | '@nodelib/fs.scandir@2.1.5': 210 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 211 | engines: {node: '>= 8'} 212 | 213 | '@nodelib/fs.stat@2.0.5': 214 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 215 | engines: {node: '>= 8'} 216 | 217 | '@nodelib/fs.walk@1.2.8': 218 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 219 | engines: {node: '>= 8'} 220 | 221 | '@rollup/rollup-android-arm-eabi@4.27.3': 222 | resolution: {integrity: sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==} 223 | cpu: [arm] 224 | os: [android] 225 | 226 | '@rollup/rollup-android-arm64@4.27.3': 227 | resolution: {integrity: sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==} 228 | cpu: [arm64] 229 | os: [android] 230 | 231 | '@rollup/rollup-darwin-arm64@4.27.3': 232 | resolution: {integrity: sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==} 233 | cpu: [arm64] 234 | os: [darwin] 235 | 236 | '@rollup/rollup-darwin-x64@4.27.3': 237 | resolution: {integrity: sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==} 238 | cpu: [x64] 239 | os: [darwin] 240 | 241 | '@rollup/rollup-freebsd-arm64@4.27.3': 242 | resolution: {integrity: sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==} 243 | cpu: [arm64] 244 | os: [freebsd] 245 | 246 | '@rollup/rollup-freebsd-x64@4.27.3': 247 | resolution: {integrity: sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==} 248 | cpu: [x64] 249 | os: [freebsd] 250 | 251 | '@rollup/rollup-linux-arm-gnueabihf@4.27.3': 252 | resolution: {integrity: sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==} 253 | cpu: [arm] 254 | os: [linux] 255 | libc: [glibc] 256 | 257 | '@rollup/rollup-linux-arm-musleabihf@4.27.3': 258 | resolution: {integrity: sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==} 259 | cpu: [arm] 260 | os: [linux] 261 | libc: [musl] 262 | 263 | '@rollup/rollup-linux-arm64-gnu@4.27.3': 264 | resolution: {integrity: sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==} 265 | cpu: [arm64] 266 | os: [linux] 267 | libc: [glibc] 268 | 269 | '@rollup/rollup-linux-arm64-musl@4.27.3': 270 | resolution: {integrity: sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==} 271 | cpu: [arm64] 272 | os: [linux] 273 | libc: [musl] 274 | 275 | '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': 276 | resolution: {integrity: sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==} 277 | cpu: [ppc64] 278 | os: [linux] 279 | libc: [glibc] 280 | 281 | '@rollup/rollup-linux-riscv64-gnu@4.27.3': 282 | resolution: {integrity: sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==} 283 | cpu: [riscv64] 284 | os: [linux] 285 | libc: [glibc] 286 | 287 | '@rollup/rollup-linux-s390x-gnu@4.27.3': 288 | resolution: {integrity: sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==} 289 | cpu: [s390x] 290 | os: [linux] 291 | libc: [glibc] 292 | 293 | '@rollup/rollup-linux-x64-gnu@4.27.3': 294 | resolution: {integrity: sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==} 295 | cpu: [x64] 296 | os: [linux] 297 | libc: [glibc] 298 | 299 | '@rollup/rollup-linux-x64-musl@4.27.3': 300 | resolution: {integrity: sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==} 301 | cpu: [x64] 302 | os: [linux] 303 | libc: [musl] 304 | 305 | '@rollup/rollup-win32-arm64-msvc@4.27.3': 306 | resolution: {integrity: sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==} 307 | cpu: [arm64] 308 | os: [win32] 309 | 310 | '@rollup/rollup-win32-ia32-msvc@4.27.3': 311 | resolution: {integrity: sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==} 312 | cpu: [ia32] 313 | os: [win32] 314 | 315 | '@rollup/rollup-win32-x64-msvc@4.27.3': 316 | resolution: {integrity: sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==} 317 | cpu: [x64] 318 | os: [win32] 319 | 320 | '@types/estree@1.0.6': 321 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 322 | 323 | '@vitejs/plugin-vue@5.2.0': 324 | resolution: {integrity: sha512-7n7KdUEtx/7Yl7I/WVAMZ1bEb0eVvXF3ummWTeLcs/9gvo9pJhuLdouSXGjdZ/MKD1acf1I272+X0RMua4/R3g==} 325 | engines: {node: ^18.0.0 || >=20.0.0} 326 | peerDependencies: 327 | vite: ^5.0.0 328 | vue: ^3.2.25 329 | 330 | '@vue/compiler-core@3.5.13': 331 | resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} 332 | 333 | '@vue/compiler-dom@3.5.13': 334 | resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} 335 | 336 | '@vue/compiler-sfc@3.5.13': 337 | resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} 338 | 339 | '@vue/compiler-ssr@3.5.13': 340 | resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} 341 | 342 | '@vue/devtools-api@6.6.4': 343 | resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} 344 | 345 | '@vue/reactivity@3.5.13': 346 | resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} 347 | 348 | '@vue/runtime-core@3.5.13': 349 | resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} 350 | 351 | '@vue/runtime-dom@3.5.13': 352 | resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} 353 | 354 | '@vue/server-renderer@3.5.13': 355 | resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} 356 | peerDependencies: 357 | vue: 3.5.13 358 | 359 | '@vue/shared@3.5.13': 360 | resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} 361 | 362 | '@windicss/config@1.9.3': 363 | resolution: {integrity: sha512-u8GUjsfC9r5X1AGYhzb1lX3zZj8wqk6SH1DYex8XUGmZ1M2UpvnUPOFi63XFViduspQ6l2xTX84QtG+lUzhEoQ==} 364 | 365 | '@windicss/plugin-utils@1.9.3': 366 | resolution: {integrity: sha512-3VG5HEGeuIfG/9iTwLyzWWm/aGKNTbtSVkpkAabdRuDP/2lEmf6Hpo4uo5drwE+2O9gXfc6nSYgAwBjotx5CfQ==} 367 | 368 | braces@3.0.3: 369 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 370 | engines: {node: '>=8'} 371 | 372 | csstype@3.1.3: 373 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 374 | 375 | debug@4.3.7: 376 | resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} 377 | engines: {node: '>=6.0'} 378 | peerDependencies: 379 | supports-color: '*' 380 | peerDependenciesMeta: 381 | supports-color: 382 | optional: true 383 | 384 | entities@4.5.0: 385 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 386 | engines: {node: '>=0.12'} 387 | 388 | esbuild@0.21.5: 389 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 390 | engines: {node: '>=12'} 391 | hasBin: true 392 | 393 | estree-walker@2.0.2: 394 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 395 | 396 | fast-glob@3.3.2: 397 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} 398 | engines: {node: '>=8.6.0'} 399 | 400 | fastq@1.17.1: 401 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 402 | 403 | fill-range@7.1.1: 404 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 405 | engines: {node: '>=8'} 406 | 407 | fsevents@2.3.3: 408 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 409 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 410 | os: [darwin] 411 | 412 | glob-parent@5.1.2: 413 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 414 | engines: {node: '>= 6'} 415 | 416 | is-extglob@2.1.1: 417 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 418 | engines: {node: '>=0.10.0'} 419 | 420 | is-glob@4.0.3: 421 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 422 | engines: {node: '>=0.10.0'} 423 | 424 | is-number@7.0.0: 425 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 426 | engines: {node: '>=0.12.0'} 427 | 428 | jiti@1.21.6: 429 | resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} 430 | hasBin: true 431 | 432 | kolorist@1.8.0: 433 | resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} 434 | 435 | magic-string@0.30.13: 436 | resolution: {integrity: sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==} 437 | 438 | merge2@1.4.1: 439 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 440 | engines: {node: '>= 8'} 441 | 442 | micromatch@4.0.8: 443 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 444 | engines: {node: '>=8.6'} 445 | 446 | ms@2.1.3: 447 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 448 | 449 | nanoid@3.3.7: 450 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 451 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 452 | hasBin: true 453 | 454 | picocolors@1.1.1: 455 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 456 | 457 | picomatch@2.3.1: 458 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 459 | engines: {node: '>=8.6'} 460 | 461 | postcss@8.4.49: 462 | resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} 463 | engines: {node: ^10 || ^12 || >=14} 464 | 465 | queue-microtask@1.2.3: 466 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 467 | 468 | reusify@1.0.4: 469 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 470 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 471 | 472 | rollup@4.27.3: 473 | resolution: {integrity: sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==} 474 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 475 | hasBin: true 476 | 477 | run-parallel@1.2.0: 478 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 479 | 480 | source-map-js@1.2.1: 481 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 482 | engines: {node: '>=0.10.0'} 483 | 484 | three@0.170.0: 485 | resolution: {integrity: sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==} 486 | 487 | to-regex-range@5.0.1: 488 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 489 | engines: {node: '>=8.0'} 490 | 491 | vite-plugin-windicss@1.9.3: 492 | resolution: {integrity: sha512-PqNiIsrEftCrgn0xIpj8ZMSdpz8NZn+OJ3gKXnOF+hFzbHFrKGJA49ViOUKCHDOquxoGBZMmTjepWr8GrftKcQ==} 493 | peerDependencies: 494 | vite: ^2.0.1 || ^3.0.0 || ^4.0.0 || ^5.0.0 495 | 496 | vite@5.4.11: 497 | resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} 498 | engines: {node: ^18.0.0 || >=20.0.0} 499 | hasBin: true 500 | peerDependencies: 501 | '@types/node': ^18.0.0 || >=20.0.0 502 | less: '*' 503 | lightningcss: ^1.21.0 504 | sass: '*' 505 | sass-embedded: '*' 506 | stylus: '*' 507 | sugarss: '*' 508 | terser: ^5.4.0 509 | peerDependenciesMeta: 510 | '@types/node': 511 | optional: true 512 | less: 513 | optional: true 514 | lightningcss: 515 | optional: true 516 | sass: 517 | optional: true 518 | sass-embedded: 519 | optional: true 520 | stylus: 521 | optional: true 522 | sugarss: 523 | optional: true 524 | terser: 525 | optional: true 526 | 527 | vue-i18n@9.14.1: 528 | resolution: {integrity: sha512-xjxV0LYc1xQ8TbAVfIyZiOSS8qoU1R0YwV7V5I8I6Fd64+zvsTsdPgtylPsie3Vdt9wekeYhr+smKDeaK6RBuA==} 529 | engines: {node: '>= 16'} 530 | peerDependencies: 531 | vue: ^3.0.0 532 | 533 | vue@3.5.13: 534 | resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} 535 | peerDependencies: 536 | typescript: '*' 537 | peerDependenciesMeta: 538 | typescript: 539 | optional: true 540 | 541 | windicss@3.5.6: 542 | resolution: {integrity: sha512-P1mzPEjgFMZLX0ZqfFht4fhV/FX8DTG7ERG1fBLiWvd34pTLVReS5CVsewKn9PApSgXnVfPWwvq+qUsRwpnwFA==} 543 | engines: {node: '>= 12'} 544 | hasBin: true 545 | 546 | snapshots: 547 | 548 | '@antfu/utils@0.7.10': {} 549 | 550 | '@babel/helper-string-parser@7.25.9': {} 551 | 552 | '@babel/helper-validator-identifier@7.25.9': {} 553 | 554 | '@babel/parser@7.26.2': 555 | dependencies: 556 | '@babel/types': 7.26.0 557 | 558 | '@babel/types@7.26.0': 559 | dependencies: 560 | '@babel/helper-string-parser': 7.25.9 561 | '@babel/helper-validator-identifier': 7.25.9 562 | 563 | '@esbuild/aix-ppc64@0.21.5': 564 | optional: true 565 | 566 | '@esbuild/android-arm64@0.21.5': 567 | optional: true 568 | 569 | '@esbuild/android-arm@0.21.5': 570 | optional: true 571 | 572 | '@esbuild/android-x64@0.21.5': 573 | optional: true 574 | 575 | '@esbuild/darwin-arm64@0.21.5': 576 | optional: true 577 | 578 | '@esbuild/darwin-x64@0.21.5': 579 | optional: true 580 | 581 | '@esbuild/freebsd-arm64@0.21.5': 582 | optional: true 583 | 584 | '@esbuild/freebsd-x64@0.21.5': 585 | optional: true 586 | 587 | '@esbuild/linux-arm64@0.21.5': 588 | optional: true 589 | 590 | '@esbuild/linux-arm@0.21.5': 591 | optional: true 592 | 593 | '@esbuild/linux-ia32@0.21.5': 594 | optional: true 595 | 596 | '@esbuild/linux-loong64@0.21.5': 597 | optional: true 598 | 599 | '@esbuild/linux-mips64el@0.21.5': 600 | optional: true 601 | 602 | '@esbuild/linux-ppc64@0.21.5': 603 | optional: true 604 | 605 | '@esbuild/linux-riscv64@0.21.5': 606 | optional: true 607 | 608 | '@esbuild/linux-s390x@0.21.5': 609 | optional: true 610 | 611 | '@esbuild/linux-x64@0.21.5': 612 | optional: true 613 | 614 | '@esbuild/netbsd-x64@0.21.5': 615 | optional: true 616 | 617 | '@esbuild/openbsd-x64@0.21.5': 618 | optional: true 619 | 620 | '@esbuild/sunos-x64@0.21.5': 621 | optional: true 622 | 623 | '@esbuild/win32-arm64@0.21.5': 624 | optional: true 625 | 626 | '@esbuild/win32-ia32@0.21.5': 627 | optional: true 628 | 629 | '@esbuild/win32-x64@0.21.5': 630 | optional: true 631 | 632 | '@intlify/core-base@9.14.1': 633 | dependencies: 634 | '@intlify/message-compiler': 9.14.1 635 | '@intlify/shared': 9.14.1 636 | 637 | '@intlify/message-compiler@9.14.1': 638 | dependencies: 639 | '@intlify/shared': 9.14.1 640 | source-map-js: 1.2.1 641 | 642 | '@intlify/shared@9.14.1': {} 643 | 644 | '@jridgewell/sourcemap-codec@1.5.0': {} 645 | 646 | '@nodelib/fs.scandir@2.1.5': 647 | dependencies: 648 | '@nodelib/fs.stat': 2.0.5 649 | run-parallel: 1.2.0 650 | 651 | '@nodelib/fs.stat@2.0.5': {} 652 | 653 | '@nodelib/fs.walk@1.2.8': 654 | dependencies: 655 | '@nodelib/fs.scandir': 2.1.5 656 | fastq: 1.17.1 657 | 658 | '@rollup/rollup-android-arm-eabi@4.27.3': 659 | optional: true 660 | 661 | '@rollup/rollup-android-arm64@4.27.3': 662 | optional: true 663 | 664 | '@rollup/rollup-darwin-arm64@4.27.3': 665 | optional: true 666 | 667 | '@rollup/rollup-darwin-x64@4.27.3': 668 | optional: true 669 | 670 | '@rollup/rollup-freebsd-arm64@4.27.3': 671 | optional: true 672 | 673 | '@rollup/rollup-freebsd-x64@4.27.3': 674 | optional: true 675 | 676 | '@rollup/rollup-linux-arm-gnueabihf@4.27.3': 677 | optional: true 678 | 679 | '@rollup/rollup-linux-arm-musleabihf@4.27.3': 680 | optional: true 681 | 682 | '@rollup/rollup-linux-arm64-gnu@4.27.3': 683 | optional: true 684 | 685 | '@rollup/rollup-linux-arm64-musl@4.27.3': 686 | optional: true 687 | 688 | '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': 689 | optional: true 690 | 691 | '@rollup/rollup-linux-riscv64-gnu@4.27.3': 692 | optional: true 693 | 694 | '@rollup/rollup-linux-s390x-gnu@4.27.3': 695 | optional: true 696 | 697 | '@rollup/rollup-linux-x64-gnu@4.27.3': 698 | optional: true 699 | 700 | '@rollup/rollup-linux-x64-musl@4.27.3': 701 | optional: true 702 | 703 | '@rollup/rollup-win32-arm64-msvc@4.27.3': 704 | optional: true 705 | 706 | '@rollup/rollup-win32-ia32-msvc@4.27.3': 707 | optional: true 708 | 709 | '@rollup/rollup-win32-x64-msvc@4.27.3': 710 | optional: true 711 | 712 | '@types/estree@1.0.6': {} 713 | 714 | '@vitejs/plugin-vue@5.2.0(vite@5.4.11)(vue@3.5.13)': 715 | dependencies: 716 | vite: 5.4.11 717 | vue: 3.5.13 718 | 719 | '@vue/compiler-core@3.5.13': 720 | dependencies: 721 | '@babel/parser': 7.26.2 722 | '@vue/shared': 3.5.13 723 | entities: 4.5.0 724 | estree-walker: 2.0.2 725 | source-map-js: 1.2.1 726 | 727 | '@vue/compiler-dom@3.5.13': 728 | dependencies: 729 | '@vue/compiler-core': 3.5.13 730 | '@vue/shared': 3.5.13 731 | 732 | '@vue/compiler-sfc@3.5.13': 733 | dependencies: 734 | '@babel/parser': 7.26.2 735 | '@vue/compiler-core': 3.5.13 736 | '@vue/compiler-dom': 3.5.13 737 | '@vue/compiler-ssr': 3.5.13 738 | '@vue/shared': 3.5.13 739 | estree-walker: 2.0.2 740 | magic-string: 0.30.13 741 | postcss: 8.4.49 742 | source-map-js: 1.2.1 743 | 744 | '@vue/compiler-ssr@3.5.13': 745 | dependencies: 746 | '@vue/compiler-dom': 3.5.13 747 | '@vue/shared': 3.5.13 748 | 749 | '@vue/devtools-api@6.6.4': {} 750 | 751 | '@vue/reactivity@3.5.13': 752 | dependencies: 753 | '@vue/shared': 3.5.13 754 | 755 | '@vue/runtime-core@3.5.13': 756 | dependencies: 757 | '@vue/reactivity': 3.5.13 758 | '@vue/shared': 3.5.13 759 | 760 | '@vue/runtime-dom@3.5.13': 761 | dependencies: 762 | '@vue/reactivity': 3.5.13 763 | '@vue/runtime-core': 3.5.13 764 | '@vue/shared': 3.5.13 765 | csstype: 3.1.3 766 | 767 | '@vue/server-renderer@3.5.13(vue@3.5.13)': 768 | dependencies: 769 | '@vue/compiler-ssr': 3.5.13 770 | '@vue/shared': 3.5.13 771 | vue: 3.5.13 772 | 773 | '@vue/shared@3.5.13': {} 774 | 775 | '@windicss/config@1.9.3': 776 | dependencies: 777 | debug: 4.3.7 778 | jiti: 1.21.6 779 | windicss: 3.5.6 780 | transitivePeerDependencies: 781 | - supports-color 782 | 783 | '@windicss/plugin-utils@1.9.3': 784 | dependencies: 785 | '@antfu/utils': 0.7.10 786 | '@windicss/config': 1.9.3 787 | debug: 4.3.7 788 | fast-glob: 3.3.2 789 | magic-string: 0.30.13 790 | micromatch: 4.0.8 791 | windicss: 3.5.6 792 | transitivePeerDependencies: 793 | - supports-color 794 | 795 | braces@3.0.3: 796 | dependencies: 797 | fill-range: 7.1.1 798 | 799 | csstype@3.1.3: {} 800 | 801 | debug@4.3.7: 802 | dependencies: 803 | ms: 2.1.3 804 | 805 | entities@4.5.0: {} 806 | 807 | esbuild@0.21.5: 808 | optionalDependencies: 809 | '@esbuild/aix-ppc64': 0.21.5 810 | '@esbuild/android-arm': 0.21.5 811 | '@esbuild/android-arm64': 0.21.5 812 | '@esbuild/android-x64': 0.21.5 813 | '@esbuild/darwin-arm64': 0.21.5 814 | '@esbuild/darwin-x64': 0.21.5 815 | '@esbuild/freebsd-arm64': 0.21.5 816 | '@esbuild/freebsd-x64': 0.21.5 817 | '@esbuild/linux-arm': 0.21.5 818 | '@esbuild/linux-arm64': 0.21.5 819 | '@esbuild/linux-ia32': 0.21.5 820 | '@esbuild/linux-loong64': 0.21.5 821 | '@esbuild/linux-mips64el': 0.21.5 822 | '@esbuild/linux-ppc64': 0.21.5 823 | '@esbuild/linux-riscv64': 0.21.5 824 | '@esbuild/linux-s390x': 0.21.5 825 | '@esbuild/linux-x64': 0.21.5 826 | '@esbuild/netbsd-x64': 0.21.5 827 | '@esbuild/openbsd-x64': 0.21.5 828 | '@esbuild/sunos-x64': 0.21.5 829 | '@esbuild/win32-arm64': 0.21.5 830 | '@esbuild/win32-ia32': 0.21.5 831 | '@esbuild/win32-x64': 0.21.5 832 | 833 | estree-walker@2.0.2: {} 834 | 835 | fast-glob@3.3.2: 836 | dependencies: 837 | '@nodelib/fs.stat': 2.0.5 838 | '@nodelib/fs.walk': 1.2.8 839 | glob-parent: 5.1.2 840 | merge2: 1.4.1 841 | micromatch: 4.0.8 842 | 843 | fastq@1.17.1: 844 | dependencies: 845 | reusify: 1.0.4 846 | 847 | fill-range@7.1.1: 848 | dependencies: 849 | to-regex-range: 5.0.1 850 | 851 | fsevents@2.3.3: 852 | optional: true 853 | 854 | glob-parent@5.1.2: 855 | dependencies: 856 | is-glob: 4.0.3 857 | 858 | is-extglob@2.1.1: {} 859 | 860 | is-glob@4.0.3: 861 | dependencies: 862 | is-extglob: 2.1.1 863 | 864 | is-number@7.0.0: {} 865 | 866 | jiti@1.21.6: {} 867 | 868 | kolorist@1.8.0: {} 869 | 870 | magic-string@0.30.13: 871 | dependencies: 872 | '@jridgewell/sourcemap-codec': 1.5.0 873 | 874 | merge2@1.4.1: {} 875 | 876 | micromatch@4.0.8: 877 | dependencies: 878 | braces: 3.0.3 879 | picomatch: 2.3.1 880 | 881 | ms@2.1.3: {} 882 | 883 | nanoid@3.3.7: {} 884 | 885 | picocolors@1.1.1: {} 886 | 887 | picomatch@2.3.1: {} 888 | 889 | postcss@8.4.49: 890 | dependencies: 891 | nanoid: 3.3.7 892 | picocolors: 1.1.1 893 | source-map-js: 1.2.1 894 | 895 | queue-microtask@1.2.3: {} 896 | 897 | reusify@1.0.4: {} 898 | 899 | rollup@4.27.3: 900 | dependencies: 901 | '@types/estree': 1.0.6 902 | optionalDependencies: 903 | '@rollup/rollup-android-arm-eabi': 4.27.3 904 | '@rollup/rollup-android-arm64': 4.27.3 905 | '@rollup/rollup-darwin-arm64': 4.27.3 906 | '@rollup/rollup-darwin-x64': 4.27.3 907 | '@rollup/rollup-freebsd-arm64': 4.27.3 908 | '@rollup/rollup-freebsd-x64': 4.27.3 909 | '@rollup/rollup-linux-arm-gnueabihf': 4.27.3 910 | '@rollup/rollup-linux-arm-musleabihf': 4.27.3 911 | '@rollup/rollup-linux-arm64-gnu': 4.27.3 912 | '@rollup/rollup-linux-arm64-musl': 4.27.3 913 | '@rollup/rollup-linux-powerpc64le-gnu': 4.27.3 914 | '@rollup/rollup-linux-riscv64-gnu': 4.27.3 915 | '@rollup/rollup-linux-s390x-gnu': 4.27.3 916 | '@rollup/rollup-linux-x64-gnu': 4.27.3 917 | '@rollup/rollup-linux-x64-musl': 4.27.3 918 | '@rollup/rollup-win32-arm64-msvc': 4.27.3 919 | '@rollup/rollup-win32-ia32-msvc': 4.27.3 920 | '@rollup/rollup-win32-x64-msvc': 4.27.3 921 | fsevents: 2.3.3 922 | 923 | run-parallel@1.2.0: 924 | dependencies: 925 | queue-microtask: 1.2.3 926 | 927 | source-map-js@1.2.1: {} 928 | 929 | three@0.170.0: {} 930 | 931 | to-regex-range@5.0.1: 932 | dependencies: 933 | is-number: 7.0.0 934 | 935 | vite-plugin-windicss@1.9.3(vite@5.4.11): 936 | dependencies: 937 | '@windicss/plugin-utils': 1.9.3 938 | debug: 4.3.7 939 | kolorist: 1.8.0 940 | vite: 5.4.11 941 | windicss: 3.5.6 942 | transitivePeerDependencies: 943 | - supports-color 944 | 945 | vite@5.4.11: 946 | dependencies: 947 | esbuild: 0.21.5 948 | postcss: 8.4.49 949 | rollup: 4.27.3 950 | optionalDependencies: 951 | fsevents: 2.3.3 952 | 953 | vue-i18n@9.14.1(vue@3.5.13): 954 | dependencies: 955 | '@intlify/core-base': 9.14.1 956 | '@intlify/shared': 9.14.1 957 | '@vue/devtools-api': 6.6.4 958 | vue: 3.5.13 959 | 960 | vue@3.5.13: 961 | dependencies: 962 | '@vue/compiler-dom': 3.5.13 963 | '@vue/compiler-sfc': 3.5.13 964 | '@vue/runtime-dom': 3.5.13 965 | '@vue/server-renderer': 3.5.13(vue@3.5.13) 966 | '@vue/shared': 3.5.13 967 | 968 | windicss@3.5.6: {} 969 | --------------------------------------------------------------------------------