重构: 将 Razor Pages 前端改为 Vue 3 项目
技术栈:
- Vue 3 + TypeScript + Vite
- Vue Router (路由管理)
- Pinia (状态管理)
- Axios (HTTP 请求)
- Bootstrap 5 (UI 框架)
功能:
- 实例列表展示 (实时刷新)
- 创建/编辑/删除实例
- 启动/停止实例
- 实例详情查看
目录结构:
- src/api: API 调用封装
- src/stores: Pinia 状态管理
- src/views: 页面组件
- src/router: 路由配置
- src/types: TypeScript 类型定义
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
已添加19个文件
已删除35个文件
已修改3个文件
| | |
| | | "Bash(cd \"D:/Git/ShanMeiXinNengYuan/Code/WCS/WIDESEAWCS_S7Simulator\" && dotnet test --no-build)", |
| | | "Bash(cd \"D:/Git/ShanMeiXinNengYuan/Code/WCS/WIDESEAWCS_S7Simulator\" && dotnet test 2>&1 | tail -20)", |
| | | "mcp__web-search-prime__web_search_prime", |
| | | "mcp__web-reader__webReader" |
| | | "mcp__web-reader__webReader", |
| | | "Bash(cd \"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WCS\\\\WIDESEAWCS_S7Simulator\" && npm create vite@latest WIDESEAWCS_S7Simulator.Web -- --template vue-ts)" |
| | | ] |
| | | } |
| | | } |
| | |
| | | "WorkspaceRootPath": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\", |
| | | "Documents": [ |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{34B63567-0A18-7E94-9249-33A42106FAAB}|WIDESEAWCS_S7Simulator.Web\\WIDESEAWCS_S7Simulator.Web.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.web\\pages\\edit.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{34B63567-0A18-7E94-9249-33A42106FAAB}|WIDESEAWCS_S7Simulator.Web\\WIDESEAWCS_S7Simulator.Web.csproj|solutionrelative:wideseawcs_s7simulator.web\\pages\\edit.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\manager\\simulatorinstancemanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\manager\\simulatorinstancemanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\persistence\\filepersistenceservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\persistence\\filepersistenceservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\server\\s7serverinstance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\server\\s7serverinstance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\persistence\\filepersistenceservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\persistence\\filepersistenceservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | } |
| | | ], |
| | | "DocumentGroupContainers": [ |
| | |
| | | "DocumentGroups": [ |
| | | { |
| | | "DockedWidth": 200, |
| | | "SelectedChildIndex": 4, |
| | | "SelectedChildIndex": 3, |
| | | "Children": [ |
| | | { |
| | | "$type": "Bookmark", |
| | |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 0, |
| | | "Title": "Edit.cshtml.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "RelativeToolTip": "WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "ViewState": "AgIAADYAAAAAAAAAAAAQwCsAAAAoAAAAAAAAAA==", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2026-03-13T07:51:30.349Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 2, |
| | | "Title": "S7ServerInstance.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "RelativeToolTip": "WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "ViewState": "AgIAAN0AAAAAAAAAAAAAAD4AAAAgAAAAAAAAAA==", |
| | | "ViewState": "AgIAAL8AAAAAAAAAAAAAAD4AAAAgAAAAAAAAAA==", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2026-03-13T07:12:02.925Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 0, |
| | | "DocumentIndex": 1, |
| | | "Title": "SimulatorInstanceManager.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "RelativeToolTip": "WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "ViewState": "AgIAAE0AAAAAAAAAAAAkwGkAAABIAAAAAAAAAA==", |
| | | "ViewState": "AgIAADcAAAAAAAAAAAAiwGkAAABIAAAAAAAAAA==", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2026-03-13T06:55:20.346Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 1, |
| | | "DocumentIndex": 3, |
| | | "Title": "FilePersistenceService.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Persistence\\FilePersistenceService.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Core\\Persistence\\FilePersistenceService.cs", |
| | |
| | | "WorkspaceRootPath": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\", |
| | | "Documents": [ |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\server\\s7serverinstance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\server\\s7serverinstance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | "AbsoluteMoniker": "D:0:0:{34B63567-0A18-7E94-9249-33A42106FAAB}|WIDESEAWCS_S7Simulator.Web\\WIDESEAWCS_S7Simulator.Web.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.web\\pages\\edit.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{34B63567-0A18-7E94-9249-33A42106FAAB}|WIDESEAWCS_S7Simulator.Web\\WIDESEAWCS_S7Simulator.Web.csproj|solutionrelative:wideseawcs_s7simulator.web\\pages\\edit.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\manager\\simulatorinstancemanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\manager\\simulatorinstancemanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\server\\s7serverinstance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | | "RelativeMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|solutionrelative:wideseawcs_s7simulator.core\\server\\s7serverinstance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" |
| | | }, |
| | | { |
| | | "AbsoluteMoniker": "D:0:0:{559E6124-CE06-87A7-E890-9BA8EA7CF3C5}|WIDESEAWCS_S7Simulator.Core\\WIDESEAWCS_S7Simulator.Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_s7simulator\\wideseawcs_s7simulator.core\\persistence\\filepersistenceservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", |
| | |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 0, |
| | | "Title": "Edit.cshtml.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "RelativeToolTip": "WIDESEAWCS_S7Simulator.Web\\Pages\\Edit.cshtml.cs", |
| | | "ViewState": "AgIAADYAAAAAAAAAAAAQwCsAAAAoAAAAAAAAAA==", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2026-03-13T07:51:30.349Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 2, |
| | | "Title": "S7ServerInstance.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "RelativeToolTip": "WIDESEAWCS_S7Simulator.Core\\Server\\S7ServerInstance.cs", |
| | | "ViewState": "AgIAAN0AAAAAAAAAAAAAAD4AAAAgAAAAAAAAAA==", |
| | | "ViewState": "AgIAAL8AAAAAAAAAAAAAAD4AAAAgAAAAAAAAAA==", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2026-03-13T07:12:02.925Z", |
| | | "EditorCaption": "" |
| | |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "RelativeToolTip": "WIDESEAWCS_S7Simulator.Core\\Manager\\SimulatorInstanceManager.cs", |
| | | "ViewState": "AgIAAE0AAAAAAAAAAAAkwGkAAABIAAAAAAAAAA==", |
| | | "ViewState": "AgIAADcAAAAAAAAAAAAiwGkAAABIAAAAAAAAAA==", |
| | | "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", |
| | | "WhenOpened": "2026-03-13T06:55:20.346Z", |
| | | "EditorCaption": "" |
| | | }, |
| | | { |
| | | "$type": "Document", |
| | | "DocumentIndex": 2, |
| | | "DocumentIndex": 3, |
| | | "Title": "FilePersistenceService.cs", |
| | | "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_S7Simulator\\WIDESEAWCS_S7Simulator.Core\\Persistence\\FilePersistenceService.cs", |
| | | "RelativeDocumentMoniker": "WIDESEAWCS_S7Simulator.Core\\Persistence\\FilePersistenceService.cs", |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # Logs |
| | | logs |
| | | *.log |
| | | npm-debug.log* |
| | | yarn-debug.log* |
| | | yarn-error.log* |
| | | pnpm-debug.log* |
| | | lerna-debug.log* |
| | | |
| | | node_modules |
| | | dist |
| | | dist-ssr |
| | | *.local |
| | | |
| | | # Editor directories and files |
| | | .vscode/* |
| | | !.vscode/extensions.json |
| | | .idea |
| | | .DS_Store |
| | | *.suo |
| | | *.ntvs* |
| | | *.njsproj |
| | | *.sln |
| | | *.sw? |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="zh-CN"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <link rel="icon" href="/favicon.ico"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | | <title>S7 PLC Simulator</title> |
| | | </head> |
| | | <body> |
| | | <div id="app"></div> |
| | | <script type="module" src="/src/main.ts"></script> |
| | | </body> |
| | | </html> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "wideseawcs-s7simulator-web", |
| | | "version": "1.0.0", |
| | | "lockfileVersion": 3, |
| | | "requires": true, |
| | | "packages": { |
| | | "": { |
| | | "name": "wideseawcs-s7simulator-web", |
| | | "version": "1.0.0", |
| | | "dependencies": { |
| | | "axios": "^1.7.9", |
| | | "bootstrap": "^5.3.3", |
| | | "bootstrap-icons": "^1.11.3", |
| | | "pinia": "^2.3.0", |
| | | "vue": "^3.5.13", |
| | | "vue-router": "^4.5.0" |
| | | }, |
| | | "devDependencies": { |
| | | "@vitejs/plugin-vue": "^5.2.1", |
| | | "typescript": "~5.7.2", |
| | | "vite": "^6.0.11", |
| | | "vue-tsc": "^2.2.0" |
| | | } |
| | | }, |
| | | "node_modules/@babel/helper-string-parser": { |
| | | "version": "7.27.1", |
| | | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", |
| | | "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=6.9.0" |
| | | } |
| | | }, |
| | | "node_modules/@babel/helper-validator-identifier": { |
| | | "version": "7.28.5", |
| | | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", |
| | | "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=6.9.0" |
| | | } |
| | | }, |
| | | "node_modules/@babel/parser": { |
| | | "version": "7.29.0", |
| | | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", |
| | | "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@babel/types": "^7.29.0" |
| | | }, |
| | | "bin": { |
| | | "parser": "bin/babel-parser.js" |
| | | }, |
| | | "engines": { |
| | | "node": ">=6.0.0" |
| | | } |
| | | }, |
| | | "node_modules/@babel/types": { |
| | | "version": "7.29.0", |
| | | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", |
| | | "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@babel/helper-string-parser": "^7.27.1", |
| | | "@babel/helper-validator-identifier": "^7.28.5" |
| | | }, |
| | | "engines": { |
| | | "node": ">=6.9.0" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/aix-ppc64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", |
| | | "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", |
| | | "cpu": [ |
| | | "ppc64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "aix" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/android-arm": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", |
| | | "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", |
| | | "cpu": [ |
| | | "arm" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "android" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/android-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "android" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/android-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", |
| | | "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "android" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/darwin-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "darwin" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/darwin-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", |
| | | "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "darwin" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/freebsd-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "freebsd" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/freebsd-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", |
| | | "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "freebsd" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-arm": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", |
| | | "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", |
| | | "cpu": [ |
| | | "arm" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-ia32": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", |
| | | "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", |
| | | "cpu": [ |
| | | "ia32" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-loong64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", |
| | | "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", |
| | | "cpu": [ |
| | | "loong64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-mips64el": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", |
| | | "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", |
| | | "cpu": [ |
| | | "mips64el" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-ppc64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", |
| | | "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", |
| | | "cpu": [ |
| | | "ppc64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-riscv64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", |
| | | "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", |
| | | "cpu": [ |
| | | "riscv64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-s390x": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", |
| | | "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", |
| | | "cpu": [ |
| | | "s390x" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/linux-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", |
| | | "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/netbsd-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "netbsd" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/netbsd-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", |
| | | "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "netbsd" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/openbsd-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "openbsd" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/openbsd-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", |
| | | "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "openbsd" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/openharmony-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "openharmony" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/sunos-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", |
| | | "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "sunos" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/win32-arm64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", |
| | | "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/win32-ia32": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", |
| | | "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", |
| | | "cpu": [ |
| | | "ia32" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@esbuild/win32-x64": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", |
| | | "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ], |
| | | "engines": { |
| | | "node": ">=18" |
| | | } |
| | | }, |
| | | "node_modules/@jridgewell/sourcemap-codec": { |
| | | "version": "1.5.5", |
| | | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", |
| | | "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@popperjs/core": { |
| | | "version": "2.11.8", |
| | | "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", |
| | | "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", |
| | | "license": "MIT", |
| | | "peer": true, |
| | | "funding": { |
| | | "type": "opencollective", |
| | | "url": "https://opencollective.com/popperjs" |
| | | } |
| | | }, |
| | | "node_modules/@rollup/rollup-android-arm-eabi": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", |
| | | "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", |
| | | "cpu": [ |
| | | "arm" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "android" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-android-arm64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", |
| | | "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "android" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-darwin-arm64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", |
| | | "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "darwin" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-darwin-x64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", |
| | | "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "darwin" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-freebsd-arm64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", |
| | | "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "freebsd" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-freebsd-x64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", |
| | | "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "freebsd" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", |
| | | "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", |
| | | "cpu": [ |
| | | "arm" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-arm-musleabihf": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", |
| | | "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", |
| | | "cpu": [ |
| | | "arm" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-arm64-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-arm64-musl": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", |
| | | "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-loong64-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", |
| | | "cpu": [ |
| | | "loong64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-loong64-musl": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", |
| | | "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", |
| | | "cpu": [ |
| | | "loong64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-ppc64-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", |
| | | "cpu": [ |
| | | "ppc64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-ppc64-musl": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", |
| | | "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", |
| | | "cpu": [ |
| | | "ppc64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-riscv64-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", |
| | | "cpu": [ |
| | | "riscv64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-riscv64-musl": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", |
| | | "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", |
| | | "cpu": [ |
| | | "riscv64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-s390x-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", |
| | | "cpu": [ |
| | | "s390x" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-x64-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-linux-x64-musl": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", |
| | | "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "linux" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-openbsd-x64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", |
| | | "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "openbsd" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-openharmony-arm64": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", |
| | | "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "openharmony" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-win32-arm64-msvc": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", |
| | | "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", |
| | | "cpu": [ |
| | | "arm64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-win32-ia32-msvc": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", |
| | | "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", |
| | | "cpu": [ |
| | | "ia32" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-win32-x64-gnu": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", |
| | | "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ] |
| | | }, |
| | | "node_modules/@rollup/rollup-win32-x64-msvc": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", |
| | | "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", |
| | | "cpu": [ |
| | | "x64" |
| | | ], |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "win32" |
| | | ] |
| | | }, |
| | | "node_modules/@types/estree": { |
| | | "version": "1.0.8", |
| | | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", |
| | | "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@vitejs/plugin-vue": { |
| | | "version": "5.2.4", |
| | | "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", |
| | | "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": "^18.0.0 || >=20.0.0" |
| | | }, |
| | | "peerDependencies": { |
| | | "vite": "^5.0.0 || ^6.0.0", |
| | | "vue": "^3.2.25" |
| | | } |
| | | }, |
| | | "node_modules/@volar/language-core": { |
| | | "version": "2.4.15", |
| | | "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.15.tgz", |
| | | "integrity": "sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@volar/source-map": "2.4.15" |
| | | } |
| | | }, |
| | | "node_modules/@volar/source-map": { |
| | | "version": "2.4.15", |
| | | "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.15.tgz", |
| | | "integrity": "sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@volar/typescript": { |
| | | "version": "2.4.15", |
| | | "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.15.tgz", |
| | | "integrity": "sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@volar/language-core": "2.4.15", |
| | | "path-browserify": "^1.0.1", |
| | | "vscode-uri": "^3.0.8" |
| | | } |
| | | }, |
| | | "node_modules/@vue/compiler-core": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz", |
| | | "integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@babel/parser": "^7.29.0", |
| | | "@vue/shared": "3.5.30", |
| | | "entities": "^7.0.1", |
| | | "estree-walker": "^2.0.2", |
| | | "source-map-js": "^1.2.1" |
| | | } |
| | | }, |
| | | "node_modules/@vue/compiler-dom": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz", |
| | | "integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/compiler-core": "3.5.30", |
| | | "@vue/shared": "3.5.30" |
| | | } |
| | | }, |
| | | "node_modules/@vue/compiler-sfc": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz", |
| | | "integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@babel/parser": "^7.29.0", |
| | | "@vue/compiler-core": "3.5.30", |
| | | "@vue/compiler-dom": "3.5.30", |
| | | "@vue/compiler-ssr": "3.5.30", |
| | | "@vue/shared": "3.5.30", |
| | | "estree-walker": "^2.0.2", |
| | | "magic-string": "^0.30.21", |
| | | "postcss": "^8.5.8", |
| | | "source-map-js": "^1.2.1" |
| | | } |
| | | }, |
| | | "node_modules/@vue/compiler-ssr": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz", |
| | | "integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/compiler-dom": "3.5.30", |
| | | "@vue/shared": "3.5.30" |
| | | } |
| | | }, |
| | | "node_modules/@vue/compiler-vue2": { |
| | | "version": "2.7.16", |
| | | "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", |
| | | "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "de-indent": "^1.0.2", |
| | | "he": "^1.2.0" |
| | | } |
| | | }, |
| | | "node_modules/@vue/devtools-api": { |
| | | "version": "6.6.4", |
| | | "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", |
| | | "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@vue/language-core": { |
| | | "version": "2.2.12", |
| | | "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz", |
| | | "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@volar/language-core": "2.4.15", |
| | | "@vue/compiler-dom": "^3.5.0", |
| | | "@vue/compiler-vue2": "^2.7.16", |
| | | "@vue/shared": "^3.5.0", |
| | | "alien-signals": "^1.0.3", |
| | | "minimatch": "^9.0.3", |
| | | "muggle-string": "^0.4.1", |
| | | "path-browserify": "^1.0.1" |
| | | }, |
| | | "peerDependencies": { |
| | | "typescript": "*" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "typescript": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/@vue/reactivity": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz", |
| | | "integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/shared": "3.5.30" |
| | | } |
| | | }, |
| | | "node_modules/@vue/runtime-core": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz", |
| | | "integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/reactivity": "3.5.30", |
| | | "@vue/shared": "3.5.30" |
| | | } |
| | | }, |
| | | "node_modules/@vue/runtime-dom": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz", |
| | | "integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/reactivity": "3.5.30", |
| | | "@vue/runtime-core": "3.5.30", |
| | | "@vue/shared": "3.5.30", |
| | | "csstype": "^3.2.3" |
| | | } |
| | | }, |
| | | "node_modules/@vue/server-renderer": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz", |
| | | "integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/compiler-ssr": "3.5.30", |
| | | "@vue/shared": "3.5.30" |
| | | }, |
| | | "peerDependencies": { |
| | | "vue": "3.5.30" |
| | | } |
| | | }, |
| | | "node_modules/@vue/shared": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz", |
| | | "integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/alien-signals": { |
| | | "version": "1.0.13", |
| | | "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz", |
| | | "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/asynckit": { |
| | | "version": "0.4.0", |
| | | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", |
| | | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/axios": { |
| | | "version": "1.13.6", |
| | | "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", |
| | | "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "follow-redirects": "^1.15.11", |
| | | "form-data": "^4.0.5", |
| | | "proxy-from-env": "^1.1.0" |
| | | } |
| | | }, |
| | | "node_modules/balanced-match": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", |
| | | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/bootstrap": { |
| | | "version": "5.3.8", |
| | | "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", |
| | | "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", |
| | | "funding": [ |
| | | { |
| | | "type": "github", |
| | | "url": "https://github.com/sponsors/twbs" |
| | | }, |
| | | { |
| | | "type": "opencollective", |
| | | "url": "https://opencollective.com/bootstrap" |
| | | } |
| | | ], |
| | | "license": "MIT", |
| | | "peerDependencies": { |
| | | "@popperjs/core": "^2.11.8" |
| | | } |
| | | }, |
| | | "node_modules/bootstrap-icons": { |
| | | "version": "1.13.1", |
| | | "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz", |
| | | "integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==", |
| | | "funding": [ |
| | | { |
| | | "type": "github", |
| | | "url": "https://github.com/sponsors/twbs" |
| | | }, |
| | | { |
| | | "type": "opencollective", |
| | | "url": "https://opencollective.com/bootstrap" |
| | | } |
| | | ], |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/brace-expansion": { |
| | | "version": "2.0.2", |
| | | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", |
| | | "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "balanced-match": "^1.0.0" |
| | | } |
| | | }, |
| | | "node_modules/call-bind-apply-helpers": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", |
| | | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "es-errors": "^1.3.0", |
| | | "function-bind": "^1.1.2" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/combined-stream": { |
| | | "version": "1.0.8", |
| | | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", |
| | | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "delayed-stream": "~1.0.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.8" |
| | | } |
| | | }, |
| | | "node_modules/csstype": { |
| | | "version": "3.2.3", |
| | | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", |
| | | "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/de-indent": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", |
| | | "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/delayed-stream": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", |
| | | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=0.4.0" |
| | | } |
| | | }, |
| | | "node_modules/dunder-proto": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", |
| | | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "call-bind-apply-helpers": "^1.0.1", |
| | | "es-errors": "^1.3.0", |
| | | "gopd": "^1.2.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/entities": { |
| | | "version": "7.0.1", |
| | | "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", |
| | | "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", |
| | | "license": "BSD-2-Clause", |
| | | "engines": { |
| | | "node": ">=0.12" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/fb55/entities?sponsor=1" |
| | | } |
| | | }, |
| | | "node_modules/es-define-property": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", |
| | | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/es-errors": { |
| | | "version": "1.3.0", |
| | | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", |
| | | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/es-object-atoms": { |
| | | "version": "1.1.1", |
| | | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", |
| | | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "es-errors": "^1.3.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/es-set-tostringtag": { |
| | | "version": "2.1.0", |
| | | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", |
| | | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "es-errors": "^1.3.0", |
| | | "get-intrinsic": "^1.2.6", |
| | | "has-tostringtag": "^1.0.2", |
| | | "hasown": "^2.0.2" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/esbuild": { |
| | | "version": "0.25.12", |
| | | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", |
| | | "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", |
| | | "dev": true, |
| | | "hasInstallScript": true, |
| | | "license": "MIT", |
| | | "bin": { |
| | | "esbuild": "bin/esbuild" |
| | | }, |
| | | "engines": { |
| | | "node": ">=18" |
| | | }, |
| | | "optionalDependencies": { |
| | | "@esbuild/aix-ppc64": "0.25.12", |
| | | "@esbuild/android-arm": "0.25.12", |
| | | "@esbuild/android-arm64": "0.25.12", |
| | | "@esbuild/android-x64": "0.25.12", |
| | | "@esbuild/darwin-arm64": "0.25.12", |
| | | "@esbuild/darwin-x64": "0.25.12", |
| | | "@esbuild/freebsd-arm64": "0.25.12", |
| | | "@esbuild/freebsd-x64": "0.25.12", |
| | | "@esbuild/linux-arm": "0.25.12", |
| | | "@esbuild/linux-arm64": "0.25.12", |
| | | "@esbuild/linux-ia32": "0.25.12", |
| | | "@esbuild/linux-loong64": "0.25.12", |
| | | "@esbuild/linux-mips64el": "0.25.12", |
| | | "@esbuild/linux-ppc64": "0.25.12", |
| | | "@esbuild/linux-riscv64": "0.25.12", |
| | | "@esbuild/linux-s390x": "0.25.12", |
| | | "@esbuild/linux-x64": "0.25.12", |
| | | "@esbuild/netbsd-arm64": "0.25.12", |
| | | "@esbuild/netbsd-x64": "0.25.12", |
| | | "@esbuild/openbsd-arm64": "0.25.12", |
| | | "@esbuild/openbsd-x64": "0.25.12", |
| | | "@esbuild/openharmony-arm64": "0.25.12", |
| | | "@esbuild/sunos-x64": "0.25.12", |
| | | "@esbuild/win32-arm64": "0.25.12", |
| | | "@esbuild/win32-ia32": "0.25.12", |
| | | "@esbuild/win32-x64": "0.25.12" |
| | | } |
| | | }, |
| | | "node_modules/estree-walker": { |
| | | "version": "2.0.2", |
| | | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", |
| | | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/fdir": { |
| | | "version": "6.5.0", |
| | | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", |
| | | "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=12.0.0" |
| | | }, |
| | | "peerDependencies": { |
| | | "picomatch": "^3 || ^4" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "picomatch": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/follow-redirects": { |
| | | "version": "1.15.11", |
| | | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", |
| | | "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", |
| | | "funding": [ |
| | | { |
| | | "type": "individual", |
| | | "url": "https://github.com/sponsors/RubenVerborgh" |
| | | } |
| | | ], |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=4.0" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "debug": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/form-data": { |
| | | "version": "4.0.5", |
| | | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", |
| | | "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "asynckit": "^0.4.0", |
| | | "combined-stream": "^1.0.8", |
| | | "es-set-tostringtag": "^2.1.0", |
| | | "hasown": "^2.0.2", |
| | | "mime-types": "^2.1.12" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 6" |
| | | } |
| | | }, |
| | | "node_modules/fsevents": { |
| | | "version": "2.3.3", |
| | | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", |
| | | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", |
| | | "dev": true, |
| | | "hasInstallScript": true, |
| | | "license": "MIT", |
| | | "optional": true, |
| | | "os": [ |
| | | "darwin" |
| | | ], |
| | | "engines": { |
| | | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" |
| | | } |
| | | }, |
| | | "node_modules/function-bind": { |
| | | "version": "1.1.2", |
| | | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", |
| | | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", |
| | | "license": "MIT", |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/ljharb" |
| | | } |
| | | }, |
| | | "node_modules/get-intrinsic": { |
| | | "version": "1.3.0", |
| | | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", |
| | | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "call-bind-apply-helpers": "^1.0.2", |
| | | "es-define-property": "^1.0.1", |
| | | "es-errors": "^1.3.0", |
| | | "es-object-atoms": "^1.1.1", |
| | | "function-bind": "^1.1.2", |
| | | "get-proto": "^1.0.1", |
| | | "gopd": "^1.2.0", |
| | | "has-symbols": "^1.1.0", |
| | | "hasown": "^2.0.2", |
| | | "math-intrinsics": "^1.1.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/ljharb" |
| | | } |
| | | }, |
| | | "node_modules/get-proto": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", |
| | | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "dunder-proto": "^1.0.1", |
| | | "es-object-atoms": "^1.0.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/gopd": { |
| | | "version": "1.2.0", |
| | | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", |
| | | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/ljharb" |
| | | } |
| | | }, |
| | | "node_modules/has-symbols": { |
| | | "version": "1.1.0", |
| | | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", |
| | | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/ljharb" |
| | | } |
| | | }, |
| | | "node_modules/has-tostringtag": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", |
| | | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "has-symbols": "^1.0.3" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/ljharb" |
| | | } |
| | | }, |
| | | "node_modules/hasown": { |
| | | "version": "2.0.2", |
| | | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", |
| | | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "function-bind": "^1.1.2" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/he": { |
| | | "version": "1.2.0", |
| | | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", |
| | | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "bin": { |
| | | "he": "bin/he" |
| | | } |
| | | }, |
| | | "node_modules/magic-string": { |
| | | "version": "0.30.21", |
| | | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", |
| | | "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@jridgewell/sourcemap-codec": "^1.5.5" |
| | | } |
| | | }, |
| | | "node_modules/math-intrinsics": { |
| | | "version": "1.1.0", |
| | | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", |
| | | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/mime-db": { |
| | | "version": "1.52.0", |
| | | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", |
| | | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.6" |
| | | } |
| | | }, |
| | | "node_modules/mime-types": { |
| | | "version": "2.1.35", |
| | | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", |
| | | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "mime-db": "1.52.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.6" |
| | | } |
| | | }, |
| | | "node_modules/minimatch": { |
| | | "version": "9.0.9", |
| | | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", |
| | | "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", |
| | | "dev": true, |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "brace-expansion": "^2.0.2" |
| | | }, |
| | | "engines": { |
| | | "node": ">=16 || 14 >=14.17" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/isaacs" |
| | | } |
| | | }, |
| | | "node_modules/muggle-string": { |
| | | "version": "0.4.1", |
| | | "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", |
| | | "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/nanoid": { |
| | | "version": "3.3.11", |
| | | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", |
| | | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", |
| | | "funding": [ |
| | | { |
| | | "type": "github", |
| | | "url": "https://github.com/sponsors/ai" |
| | | } |
| | | ], |
| | | "license": "MIT", |
| | | "bin": { |
| | | "nanoid": "bin/nanoid.cjs" |
| | | }, |
| | | "engines": { |
| | | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" |
| | | } |
| | | }, |
| | | "node_modules/path-browserify": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", |
| | | "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/picocolors": { |
| | | "version": "1.1.1", |
| | | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", |
| | | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", |
| | | "license": "ISC" |
| | | }, |
| | | "node_modules/picomatch": { |
| | | "version": "4.0.3", |
| | | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", |
| | | "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=12" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/jonschlinkert" |
| | | } |
| | | }, |
| | | "node_modules/pinia": { |
| | | "version": "2.3.1", |
| | | "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz", |
| | | "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/devtools-api": "^6.6.3", |
| | | "vue-demi": "^0.14.10" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/posva" |
| | | }, |
| | | "peerDependencies": { |
| | | "typescript": ">=4.4.4", |
| | | "vue": "^2.7.0 || ^3.5.11" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "typescript": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/postcss": { |
| | | "version": "8.5.8", |
| | | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", |
| | | "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", |
| | | "funding": [ |
| | | { |
| | | "type": "opencollective", |
| | | "url": "https://opencollective.com/postcss/" |
| | | }, |
| | | { |
| | | "type": "tidelift", |
| | | "url": "https://tidelift.com/funding/github/npm/postcss" |
| | | }, |
| | | { |
| | | "type": "github", |
| | | "url": "https://github.com/sponsors/ai" |
| | | } |
| | | ], |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "nanoid": "^3.3.11", |
| | | "picocolors": "^1.1.1", |
| | | "source-map-js": "^1.2.1" |
| | | }, |
| | | "engines": { |
| | | "node": "^10 || ^12 || >=14" |
| | | } |
| | | }, |
| | | "node_modules/proxy-from-env": { |
| | | "version": "1.1.0", |
| | | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", |
| | | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/rollup": { |
| | | "version": "4.59.0", |
| | | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", |
| | | "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@types/estree": "1.0.8" |
| | | }, |
| | | "bin": { |
| | | "rollup": "dist/bin/rollup" |
| | | }, |
| | | "engines": { |
| | | "node": ">=18.0.0", |
| | | "npm": ">=8.0.0" |
| | | }, |
| | | "optionalDependencies": { |
| | | "@rollup/rollup-android-arm-eabi": "4.59.0", |
| | | "@rollup/rollup-android-arm64": "4.59.0", |
| | | "@rollup/rollup-darwin-arm64": "4.59.0", |
| | | "@rollup/rollup-darwin-x64": "4.59.0", |
| | | "@rollup/rollup-freebsd-arm64": "4.59.0", |
| | | "@rollup/rollup-freebsd-x64": "4.59.0", |
| | | "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", |
| | | "@rollup/rollup-linux-arm-musleabihf": "4.59.0", |
| | | "@rollup/rollup-linux-arm64-gnu": "4.59.0", |
| | | "@rollup/rollup-linux-arm64-musl": "4.59.0", |
| | | "@rollup/rollup-linux-loong64-gnu": "4.59.0", |
| | | "@rollup/rollup-linux-loong64-musl": "4.59.0", |
| | | "@rollup/rollup-linux-ppc64-gnu": "4.59.0", |
| | | "@rollup/rollup-linux-ppc64-musl": "4.59.0", |
| | | "@rollup/rollup-linux-riscv64-gnu": "4.59.0", |
| | | "@rollup/rollup-linux-riscv64-musl": "4.59.0", |
| | | "@rollup/rollup-linux-s390x-gnu": "4.59.0", |
| | | "@rollup/rollup-linux-x64-gnu": "4.59.0", |
| | | "@rollup/rollup-linux-x64-musl": "4.59.0", |
| | | "@rollup/rollup-openbsd-x64": "4.59.0", |
| | | "@rollup/rollup-openharmony-arm64": "4.59.0", |
| | | "@rollup/rollup-win32-arm64-msvc": "4.59.0", |
| | | "@rollup/rollup-win32-ia32-msvc": "4.59.0", |
| | | "@rollup/rollup-win32-x64-gnu": "4.59.0", |
| | | "@rollup/rollup-win32-x64-msvc": "4.59.0", |
| | | "fsevents": "~2.3.2" |
| | | } |
| | | }, |
| | | "node_modules/source-map-js": { |
| | | "version": "1.2.1", |
| | | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", |
| | | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", |
| | | "license": "BSD-3-Clause", |
| | | "engines": { |
| | | "node": ">=0.10.0" |
| | | } |
| | | }, |
| | | "node_modules/tinyglobby": { |
| | | "version": "0.2.15", |
| | | "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", |
| | | "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "fdir": "^6.5.0", |
| | | "picomatch": "^4.0.3" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12.0.0" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/SuperchupuDev" |
| | | } |
| | | }, |
| | | "node_modules/typescript": { |
| | | "version": "5.7.3", |
| | | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", |
| | | "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", |
| | | "devOptional": true, |
| | | "license": "Apache-2.0", |
| | | "bin": { |
| | | "tsc": "bin/tsc", |
| | | "tsserver": "bin/tsserver" |
| | | }, |
| | | "engines": { |
| | | "node": ">=14.17" |
| | | } |
| | | }, |
| | | "node_modules/vite": { |
| | | "version": "6.4.1", |
| | | "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", |
| | | "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "esbuild": "^0.25.0", |
| | | "fdir": "^6.4.4", |
| | | "picomatch": "^4.0.2", |
| | | "postcss": "^8.5.3", |
| | | "rollup": "^4.34.9", |
| | | "tinyglobby": "^0.2.13" |
| | | }, |
| | | "bin": { |
| | | "vite": "bin/vite.js" |
| | | }, |
| | | "engines": { |
| | | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/vitejs/vite?sponsor=1" |
| | | }, |
| | | "optionalDependencies": { |
| | | "fsevents": "~2.3.3" |
| | | }, |
| | | "peerDependencies": { |
| | | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", |
| | | "jiti": ">=1.21.0", |
| | | "less": "*", |
| | | "lightningcss": "^1.21.0", |
| | | "sass": "*", |
| | | "sass-embedded": "*", |
| | | "stylus": "*", |
| | | "sugarss": "*", |
| | | "terser": "^5.16.0", |
| | | "tsx": "^4.8.1", |
| | | "yaml": "^2.4.2" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "@types/node": { |
| | | "optional": true |
| | | }, |
| | | "jiti": { |
| | | "optional": true |
| | | }, |
| | | "less": { |
| | | "optional": true |
| | | }, |
| | | "lightningcss": { |
| | | "optional": true |
| | | }, |
| | | "sass": { |
| | | "optional": true |
| | | }, |
| | | "sass-embedded": { |
| | | "optional": true |
| | | }, |
| | | "stylus": { |
| | | "optional": true |
| | | }, |
| | | "sugarss": { |
| | | "optional": true |
| | | }, |
| | | "terser": { |
| | | "optional": true |
| | | }, |
| | | "tsx": { |
| | | "optional": true |
| | | }, |
| | | "yaml": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/vscode-uri": { |
| | | "version": "3.1.0", |
| | | "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", |
| | | "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/vue": { |
| | | "version": "3.5.30", |
| | | "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz", |
| | | "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/compiler-dom": "3.5.30", |
| | | "@vue/compiler-sfc": "3.5.30", |
| | | "@vue/runtime-dom": "3.5.30", |
| | | "@vue/server-renderer": "3.5.30", |
| | | "@vue/shared": "3.5.30" |
| | | }, |
| | | "peerDependencies": { |
| | | "typescript": "*" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "typescript": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/vue-demi": { |
| | | "version": "0.14.10", |
| | | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", |
| | | "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", |
| | | "hasInstallScript": true, |
| | | "license": "MIT", |
| | | "bin": { |
| | | "vue-demi-fix": "bin/vue-demi-fix.js", |
| | | "vue-demi-switch": "bin/vue-demi-switch.js" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/antfu" |
| | | }, |
| | | "peerDependencies": { |
| | | "@vue/composition-api": "^1.0.0-rc.1", |
| | | "vue": "^3.0.0-0 || ^2.6.0" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "@vue/composition-api": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/vue-router": { |
| | | "version": "4.6.4", |
| | | "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", |
| | | "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@vue/devtools-api": "^6.6.4" |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/posva" |
| | | }, |
| | | "peerDependencies": { |
| | | "vue": "^3.5.0" |
| | | } |
| | | }, |
| | | "node_modules/vue-tsc": { |
| | | "version": "2.2.12", |
| | | "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz", |
| | | "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@volar/typescript": "2.4.15", |
| | | "@vue/language-core": "2.2.12" |
| | | }, |
| | | "bin": { |
| | | "vue-tsc": "bin/vue-tsc.js" |
| | | }, |
| | | "peerDependencies": { |
| | | "typescript": ">=5.0.0" |
| | | } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "wideseawcs-s7simulator-web", |
| | | "private": true, |
| | | "version": "1.0.0", |
| | | "type": "module", |
| | | "scripts": { |
| | | "dev": "vite", |
| | | "build": "vue-tsc && vite build", |
| | | "preview": "vite preview" |
| | | }, |
| | | "dependencies": { |
| | | "vue": "^3.5.13", |
| | | "vue-router": "^4.5.0", |
| | | "pinia": "^2.3.0", |
| | | "axios": "^1.7.9", |
| | | "bootstrap": "^5.3.3", |
| | | "bootstrap-icons": "^1.11.3" |
| | | }, |
| | | "devDependencies": { |
| | | "@vitejs/plugin-vue": "^5.2.1", |
| | | "typescript": "~5.7.2", |
| | | "vite": "^6.0.11", |
| | | "vue-tsc": "^2.2.0" |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div id="app"> |
| | | <nav class="navbar navbar-expand-sm navbar-dark bg-primary shadow-sm mb-4"> |
| | | <div class="container-fluid"> |
| | | <router-link class="navbar-brand" to="/"> |
| | | <i class="bi bi-cpu-fill me-2"></i>S7 PLC Simulator |
| | | </router-link> |
| | | <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse"> |
| | | <span class="navbar-toggler-icon"></span> |
| | | </button> |
| | | <div class="navbar-collapse collapse"> |
| | | <ul class="navbar-nav flex-grow-1"> |
| | | <li class="nav-item"> |
| | | <router-link class="nav-link" to="/"> |
| | | <i class="bi bi-house-door me-1"></i>å®ä¾å表 |
| | | </router-link> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </nav> |
| | | |
| | | <div class="container-fluid px-4"> |
| | | <router-view /> |
| | | </div> |
| | | |
| | | <footer class="border-top py-3 mt-4 bg-light"> |
| | | <div class="container-fluid text-center text-muted"> |
| | | <small>© 2026 - S7 PLC Simulator Management UI</small> |
| | | </div> |
| | | </footer> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | </script> |
| | | |
| | | <style> |
| | | #app { |
| | | min-height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .container-fluid { |
| | | flex: 1; |
| | | } |
| | | |
| | | .navbar-nav .nav-link.router-link-active { |
| | | font-weight: bold; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import axios from 'axios' |
| | | import type { |
| | | InstanceListItem, |
| | | InstanceState, |
| | | InstanceConfig |
| | | } from '../types' |
| | | |
| | | const api = axios.create({ |
| | | baseURL: import.meta.env.VITE_API_BASE_URL || '/api', |
| | | headers: { |
| | | 'Content-Type': 'application/json' |
| | | } |
| | | }) |
| | | |
| | | // è·åææå®ä¾ |
| | | export async function getAllInstances(): Promise<InstanceListItem[]> { |
| | | const response = await api.get<InstanceListItem[]>('/SimulatorInstances') |
| | | return response.data |
| | | } |
| | | |
| | | // è·åæå®å®ä¾ç¶æ |
| | | export async function getInstance(id: string): Promise<InstanceState | null> { |
| | | try { |
| | | const response = await api.get<InstanceState>(`/SimulatorInstances/${encodeURIComponent(id)}`) |
| | | return response.data |
| | | } catch (error) { |
| | | if (axios.isAxiosError(error) && error.response?.status === 404) { |
| | | return null |
| | | } |
| | | throw error |
| | | } |
| | | } |
| | | |
| | | // è·åå®ä¾é
ç½® |
| | | export async function getInstanceConfig(id: string): Promise<InstanceConfig | null> { |
| | | try { |
| | | const response = await api.get<InstanceConfig>(`/SimulatorInstances/${encodeURIComponent(id)}/config`) |
| | | return response.data |
| | | } catch (error) { |
| | | if (axios.isAxiosError(error) && error.response?.status === 404) { |
| | | return null |
| | | } |
| | | throw error |
| | | } |
| | | } |
| | | |
| | | // å建å®ä¾ |
| | | export async function createInstance(config: InstanceConfig): Promise<InstanceState | null> { |
| | | try { |
| | | const response = await api.post<InstanceState>('/SimulatorInstances', config) |
| | | return response.data |
| | | } catch (error) { |
| | | console.error('å建å®ä¾å¤±è´¥:', error) |
| | | return null |
| | | } |
| | | } |
| | | |
| | | // æ´æ°å®ä¾ |
| | | export async function updateInstance(id: string, config: InstanceConfig): Promise<InstanceState | null> { |
| | | try { |
| | | const response = await api.put<InstanceState>(`/SimulatorInstances/${encodeURIComponent(id)}`, config) |
| | | return response.data |
| | | } catch (error) { |
| | | console.error('æ´æ°å®ä¾å¤±è´¥:', error) |
| | | return null |
| | | } |
| | | } |
| | | |
| | | // å é¤å®ä¾ |
| | | export async function deleteInstance(id: string, deleteConfig: boolean = true): Promise<boolean> { |
| | | try { |
| | | await api.delete(`/SimulatorInstances/${encodeURIComponent(id)}?deleteConfig=${deleteConfig}`) |
| | | return true |
| | | } catch (error) { |
| | | console.error('å é¤å®ä¾å¤±è´¥:', error) |
| | | return false |
| | | } |
| | | } |
| | | |
| | | // å¯å¨å®ä¾ |
| | | export async function startInstance(id: string): Promise<InstanceState | null> { |
| | | try { |
| | | const response = await api.post<InstanceState>(`/SimulatorInstances/${encodeURIComponent(id)}/start`) |
| | | return response.data |
| | | } catch (error) { |
| | | console.error('å¯å¨å®ä¾å¤±è´¥:', error) |
| | | return null |
| | | } |
| | | } |
| | | |
| | | // 忢å®ä¾ |
| | | export async function stopInstance(id: string): Promise<InstanceState | null> { |
| | | try { |
| | | const response = await api.post<InstanceState>(`/SimulatorInstances/${encodeURIComponent(id)}/stop`) |
| | | return response.data |
| | | } catch (error) { |
| | | console.error('忢å®ä¾å¤±è´¥:', error) |
| | | return null |
| | | } |
| | | } |
| | | |
| | | // éå¯å®ä¾ |
| | | export async function restartInstance(id: string): Promise<InstanceState | null> { |
| | | try { |
| | | const response = await api.post<InstanceState>(`/SimulatorInstances/${encodeURIComponent(id)}/restart`) |
| | | return response.data |
| | | } catch (error) { |
| | | console.error('éå¯å®ä¾å¤±è´¥:', error) |
| | | return null |
| | | } |
| | | } |
| | | |
| | | export default api |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { createApp } from 'vue' |
| | | import { createPinia } from 'pinia' |
| | | import App from './App.vue' |
| | | import router from './router' |
| | | import './style.css' |
| | | |
| | | // Bootstrap CSS |
| | | import 'bootstrap/dist/css/bootstrap.min.css' |
| | | import 'bootstrap-icons/font/bootstrap-icons.css' |
| | | import 'bootstrap/dist/js/bootstrap.bundle.min.js' |
| | | |
| | | const app = createApp(App) |
| | | |
| | | app.use(createPinia()) |
| | | app.use(router) |
| | | |
| | | app.mount('#app') |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { createRouter, createWebHistory } from 'vue-router' |
| | | import type { RouteRecordRaw } from 'vue-router' |
| | | |
| | | const routes: RouteRecordRaw[] = [ |
| | | { |
| | | path: '/', |
| | | name: 'home', |
| | | component: () => import('../views/HomeView.vue') |
| | | }, |
| | | { |
| | | path: '/create', |
| | | name: 'create', |
| | | component: () => import('../views/CreateView.vue') |
| | | }, |
| | | { |
| | | path: '/edit/:id', |
| | | name: 'edit', |
| | | component: () => import('../views/EditView.vue'), |
| | | props: true |
| | | }, |
| | | { |
| | | path: '/details/:id', |
| | | name: 'details', |
| | | component: () => import('../views/DetailsView.vue'), |
| | | props: true |
| | | } |
| | | ] |
| | | |
| | | const router = createRouter({ |
| | | history: createWebHistory(), |
| | | routes |
| | | }) |
| | | |
| | | export default router |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineStore } from 'pinia' |
| | | import { ref, computed } from 'vue' |
| | | import type { InstanceListItem } from '../types' |
| | | import * as api from '../api' |
| | | |
| | | export const useInstancesStore = defineStore('instances', () => { |
| | | // ç¶æ |
| | | const instances = ref<InstanceListItem[]>([]) |
| | | const loading = ref(false) |
| | | const error = ref<string | null>(null) |
| | | const autoRefreshEnabled = ref(true) |
| | | let refreshTimer: number | null = null |
| | | |
| | | // 计ç®å±æ§ |
| | | const runningCount = computed(() => |
| | | instances.value.filter(i => i.status === 'Running').length |
| | | ) |
| | | |
| | | const stoppedCount = computed(() => |
| | | instances.value.filter(i => i.status === 'Stopped').length |
| | | ) |
| | | |
| | | const errorCount = computed(() => |
| | | instances.value.filter(i => i.status === 'Error').length |
| | | ) |
| | | |
| | | // æ¹æ³ |
| | | async function loadInstances() { |
| | | loading.value = true |
| | | error.value = null |
| | | try { |
| | | instances.value = await api.getAllInstances() |
| | | } catch (err) { |
| | | error.value = 'å è½½å®ä¾å表失败' |
| | | console.error(err) |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | async function startInstance(id: string) { |
| | | try { |
| | | await api.startInstance(id) |
| | | await loadInstances() |
| | | } catch (err) { |
| | | console.error('å¯å¨å®ä¾å¤±è´¥:', err) |
| | | throw err |
| | | } |
| | | } |
| | | |
| | | async function stopInstance(id: string) { |
| | | try { |
| | | await api.stopInstance(id) |
| | | await loadInstances() |
| | | } catch (err) { |
| | | console.error('忢å®ä¾å¤±è´¥:', err) |
| | | throw err |
| | | } |
| | | } |
| | | |
| | | async function deleteInstance(id: string) { |
| | | try { |
| | | await api.deleteInstance(id) |
| | | await loadInstances() |
| | | } catch (err) { |
| | | console.error('å é¤å®ä¾å¤±è´¥:', err) |
| | | throw err |
| | | } |
| | | } |
| | | |
| | | function startAutoRefresh(interval: number = 2000) { |
| | | stopAutoRefresh() |
| | | if (autoRefreshEnabled.value) { |
| | | refreshTimer = window.setInterval(() => { |
| | | loadInstances() |
| | | }, interval) |
| | | } |
| | | } |
| | | |
| | | function stopAutoRefresh() { |
| | | if (refreshTimer !== null) { |
| | | clearInterval(refreshTimer) |
| | | refreshTimer = null |
| | | } |
| | | } |
| | | |
| | | function setAutoRefreshEnabled(enabled: boolean) { |
| | | autoRefreshEnabled.value = enabled |
| | | if (!enabled) { |
| | | stopAutoRefresh() |
| | | } |
| | | } |
| | | |
| | | // è·åå个å®ä¾ |
| | | function getInstance(id: string) { |
| | | return instances.value.find(i => i.instanceId === id) |
| | | } |
| | | |
| | | return { |
| | | // ç¶æ |
| | | instances, |
| | | loading, |
| | | error, |
| | | autoRefreshEnabled, |
| | | // 计ç®å±æ§ |
| | | runningCount, |
| | | stoppedCount, |
| | | errorCount, |
| | | // æ¹æ³ |
| | | loadInstances, |
| | | startInstance, |
| | | stopInstance, |
| | | deleteInstance, |
| | | startAutoRefresh, |
| | | stopAutoRefresh, |
| | | setAutoRefreshEnabled, |
| | | getInstance |
| | | } |
| | | }) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /* Global Styles */ |
| | | :root { |
| | | font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; |
| | | } |
| | | |
| | | body { |
| | | margin: 0; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* Status Colors */ |
| | | .status-stopped { |
| | | border-left: 4px solid #6c757d; |
| | | } |
| | | |
| | | .status-starting { |
| | | border-left: 4px solid #0dcaf0; |
| | | } |
| | | |
| | | .status-running { |
| | | border-left: 4px solid #198754; |
| | | } |
| | | |
| | | .status-stopping { |
| | | border-left: 4px solid #ffc107; |
| | | } |
| | | |
| | | .status-error { |
| | | border-left: 4px solid #dc3545; |
| | | } |
| | | |
| | | /* Loading Spinner Overlay */ |
| | | .spinner-overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | /* Spin icon animation */ |
| | | .spin-icon { |
| | | animation: spin 1s linear infinite; |
| | | } |
| | | |
| | | @keyframes spin { |
| | | from { |
| | | transform: rotate(0deg); |
| | | } |
| | | to { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | /* Card hover effect */ |
| | | .card { |
| | | transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; |
| | | } |
| | | |
| | | .card:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | /* Custom scrollbar */ |
| | | ::-webkit-scrollbar { |
| | | width: 8px; |
| | | height: 8px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-track { |
| | | background: #f1f1f1; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb { |
| | | background: #888; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb:hover { |
| | | background: #555; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å®ä¾ç¶ææä¸¾ |
| | | export enum InstanceStatus { |
| | | Stopped = 'Stopped', |
| | | Starting = 'Starting', |
| | | Running = 'Running', |
| | | Stopping = 'Stopping', |
| | | Error = 'Error' |
| | | } |
| | | |
| | | // PLC å巿䏾 |
| | | export enum SiemensPLCType { |
| | | S7200Smart = 'S7200Smart', |
| | | S71200 = 'S71200', |
| | | S71500 = 'S71500', |
| | | S7300 = 'S7300', |
| | | S7400 = 'S7400' |
| | | } |
| | | |
| | | // å
ååºåé
ç½® |
| | | export interface MemoryRegionConfig { |
| | | mRegionSize: number |
| | | dBBBlockCount: number |
| | | dBBBlockSize: number |
| | | iRegionSize: number |
| | | qRegionSize: number |
| | | tRegionCount: number |
| | | cRegionCount: number |
| | | } |
| | | |
| | | // å®ä¾é
ç½® |
| | | export interface InstanceConfig { |
| | | id: string |
| | | name: string |
| | | plcType: SiemensPLCType |
| | | port: number |
| | | activationKey: string |
| | | autoStart: boolean |
| | | memoryConfig: MemoryRegionConfig |
| | | } |
| | | |
| | | // 客æ·ç«¯è¿æ¥ä¿¡æ¯ |
| | | export interface ClientConnection { |
| | | endpoint: string |
| | | connectTime: string |
| | | lastActivityTime: string |
| | | } |
| | | |
| | | // å®ä¾ç¶æ |
| | | export interface InstanceState { |
| | | instanceId: string |
| | | name: string |
| | | plcType: string |
| | | port: number |
| | | status: InstanceStatus |
| | | clientCount: number |
| | | totalRequests: number |
| | | startTime: string | null |
| | | lastActivityTime: string | null |
| | | errorMessage: string | null |
| | | } |
| | | |
| | | // å®ä¾å表项 |
| | | export interface InstanceListItem { |
| | | instanceId: string |
| | | name: string |
| | | plcType: string |
| | | port: number |
| | | status: string |
| | | clientCount: number |
| | | totalRequests: number |
| | | startTime: string | null |
| | | lastActivityTime: string | null |
| | | errorMessage: string | null |
| | | } |
| | | |
| | | // å建å®ä¾è¾å
¥ |
| | | export interface CreateInstanceInput { |
| | | id: string |
| | | name: string |
| | | plcType: SiemensPLCType |
| | | port: number |
| | | activationKey?: string |
| | | autoStart: boolean |
| | | mRegionSize: number |
| | | dBBBlockCount: number |
| | | dBBBlockSize: number |
| | | iRegionSize: number |
| | | qRegionSize: number |
| | | tRegionCount: number |
| | | cRegionCount: number |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <div class="d-flex justify-content-between align-items-center mb-4"> |
| | | <div> |
| | | <h2 class="mb-0"> |
| | | <i class="bi bi-plus-circle me-2"></i>å建å®ä¾ |
| | | </h2> |
| | | <p class="text-muted mb-0 mt-1">å建æ°ç S7 PLC 仿çå¨å®ä¾</p> |
| | | </div> |
| | | <router-link to="/" class="btn btn-outline-secondary"> |
| | | <i class="bi bi-arrow-left me-1"></i>è¿åå表 |
| | | </router-link> |
| | | </div> |
| | | |
| | | <div class="row justify-content-center"> |
| | | <div class="col-lg-8"> |
| | | <div class="card"> |
| | | <div class="card-body"> |
| | | <form @submit.prevent="handleSubmit"> |
| | | <!-- åºæ¬ä¿¡æ¯ --> |
| | | <h5 class="card-title mb-3">åºæ¬ä¿¡æ¯</h5> |
| | | <div class="row mb-3"> |
| | | <div class="col-md-6"> |
| | | <label for="id" class="form-label">å®ä¾ID *</label> |
| | | <input |
| | | type="text" |
| | | class="form-control" |
| | | id="id" |
| | | v-model="form.id" |
| | | pattern="[a-zA-Z0-9_-]+" |
| | | required |
| | | placeholder="ä¾å¦: PLC_001" |
| | | > |
| | | <div class="form-text">åªè½å
å«åæ¯ãæ°åãä¸å线åè¿å符</div> |
| | | </div> |
| | | <div class="col-md-6"> |
| | | <label for="name" class="form-label">å®ä¾åç§° *</label> |
| | | <input |
| | | type="text" |
| | | class="form-control" |
| | | id="name" |
| | | v-model="form.name" |
| | | required |
| | | placeholder="ä¾å¦: 1å·PLC" |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row mb-3"> |
| | | <div class="col-md-6"> |
| | | <label for="plcType" class="form-label">PLCåå· *</label> |
| | | <select class="form-select" id="plcType" v-model="form.plcType" required> |
| | | <option value="S7200Smart">S7-200 Smart</option> |
| | | <option value="S71200">S7-1200</option> |
| | | <option value="S71500">S7-1500</option> |
| | | <option value="S7300">S7-300</option> |
| | | <option value="S7400">S7-400</option> |
| | | </select> |
| | | </div> |
| | | <div class="col-md-6"> |
| | | <label for="port" class="form-label">çå¬ç«¯å£ *</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="port" |
| | | v-model.number="form.port" |
| | | min="1" |
| | | max="65535" |
| | | required |
| | | placeholder="102" |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row mb-3"> |
| | | <div class="col-md-6"> |
| | | <label for="activationKey" class="form-label">HSLæ¿æ´»ç </label> |
| | | <input |
| | | type="text" |
| | | class="form-control" |
| | | id="activationKey" |
| | | v-model="form.activationKey" |
| | | placeholder="å¯éï¼ç空使ç¨é»è®¤" |
| | | > |
| | | </div> |
| | | <div class="col-md-6 d-flex align-items-center"> |
| | | <div class="form-check"> |
| | | <input class="form-check-input" type="checkbox" id="autoStart" v-model="form.autoStart"> |
| | | <label class="form-check-label" for="autoStart"> |
| | | èªå¨å¯å¨ |
| | | </label> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- å
åé
ç½® --> |
| | | <h5 class="card-title mb-3 mt-4">å
åé
ç½®</h5> |
| | | <div class="row mb-3"> |
| | | <div class="col-md-4"> |
| | | <label for="mRegionSize" class="form-label">Måºå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="mRegionSize" |
| | | v-model.number="form.mRegionSize" |
| | | min="0" |
| | | placeholder="1024" |
| | | > |
| | | </div> |
| | | <div class="col-md-4"> |
| | | <label for="iRegionSize" class="form-label">Iåºå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="iRegionSize" |
| | | v-model.number="form.iRegionSize" |
| | | min="0" |
| | | placeholder="256" |
| | | > |
| | | </div> |
| | | <div class="col-md-4"> |
| | | <label for="qRegionSize" class="form-label">Qåºå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="qRegionSize" |
| | | v-model.number="form.qRegionSize" |
| | | min="0" |
| | | placeholder="256" |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row mb-3"> |
| | | <div class="col-md-4"> |
| | | <label for="dbBlockCount" class="form-label">DBåæ°é</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="dbBlockCount" |
| | | v-model.number="form.dbBlockCount" |
| | | min="0" |
| | | placeholder="100" |
| | | > |
| | | </div> |
| | | <div class="col-md-4"> |
| | | <label for="dbBlockSize" class="form-label">DBå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="dbBlockSize" |
| | | v-model.number="form.dbBlockSize" |
| | | min="0" |
| | | placeholder="1024" |
| | | > |
| | | </div> |
| | | <div class="col-md-2"> |
| | | <label for="tRegionCount" class="form-label">宿¶å¨æ°é</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="tRegionCount" |
| | | v-model.number="form.tRegionCount" |
| | | min="0" |
| | | placeholder="64" |
| | | > |
| | | </div> |
| | | <div class="col-md-2"> |
| | | <label for="cRegionCount" class="form-label">计æ°å¨æ°é</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="cRegionCount" |
| | | v-model.number="form.cRegionCount" |
| | | min="0" |
| | | placeholder="64" |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æäº¤æé® --> |
| | | <div class="d-flex gap-2 mt-4"> |
| | | <button type="submit" class="btn btn-primary" :disabled="submitting"> |
| | | <span v-if="submitting" class="spinner-border spinner-border-sm me-1"></span> |
| | | <i v-else class="bi bi-check-lg me-1"></i> |
| | | {{ submitting ? 'å建ä¸...' : 'å建å®ä¾' }} |
| | | </button> |
| | | <router-link to="/" class="btn btn-outline-secondary">åæ¶</router-link> |
| | | </div> |
| | | </form> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref } from 'vue' |
| | | import { useRouter } from 'vue-router' |
| | | import * as api from '../api' |
| | | import type { InstanceConfig, MemoryRegionConfig, SiemensPLCType } from '../types' |
| | | |
| | | const router = useRouter() |
| | | |
| | | const form = ref({ |
| | | id: '', |
| | | name: '', |
| | | plcType: 'S71200' as SiemensPLCType, |
| | | port: 102, |
| | | activationKey: '', |
| | | autoStart: false, |
| | | mRegionSize: 1024, |
| | | dbBlockCount: 100, |
| | | dbBlockSize: 1024, |
| | | iRegionSize: 256, |
| | | qRegionSize: 256, |
| | | tRegionCount: 64, |
| | | cRegionCount: 64 |
| | | }) |
| | | |
| | | const submitting = ref(false) |
| | | |
| | | async function handleSubmit() { |
| | | submitting.value = true |
| | | |
| | | try { |
| | | const memoryConfig: MemoryRegionConfig = { |
| | | mRegionSize: form.value.mRegionSize > 0 ? form.value.mRegionSize : 1024, |
| | | dBBBlockCount: form.value.dbBlockCount > 0 ? form.value.dbBlockCount : 100, |
| | | dBBBlockSize: form.value.dbBlockSize > 0 ? form.value.dbBlockSize : 1024, |
| | | iRegionSize: form.value.iRegionSize > 0 ? form.value.iRegionSize : 256, |
| | | qRegionSize: form.value.qRegionSize > 0 ? form.value.qRegionSize : 256, |
| | | tRegionCount: form.value.tRegionCount > 0 ? form.value.tRegionCount : 64, |
| | | cRegionCount: form.value.cRegionCount > 0 ? form.value.cRegionCount : 64 |
| | | } |
| | | |
| | | const config: InstanceConfig = { |
| | | id: form.value.id, |
| | | name: form.value.name, |
| | | plcType: form.value.plcType, |
| | | port: form.value.port, |
| | | activationKey: form.value.activationKey || '', |
| | | autoStart: form.value.autoStart, |
| | | memoryConfig |
| | | } |
| | | |
| | | const result = await api.createInstance(config) |
| | | |
| | | if (result) { |
| | | alert(`å®ä¾ "${form.value.id}" å建æå!`) |
| | | router.push('/') |
| | | } else { |
| | | alert('å建å®ä¾å¤±è´¥ï¼è¯·æ£æ¥è¾å
¥') |
| | | } |
| | | } catch (err) { |
| | | console.error('å建å®ä¾å¤±è´¥:', err) |
| | | alert('å建å®ä¾å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .card-title { |
| | | color: #495057; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .form-label { |
| | | font-weight: 500; |
| | | color: #495057; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <div v-if="loading" class="text-center py-5"> |
| | | <div class="spinner-border text-primary" role="status"> |
| | | <span class="visually-hidden">å è½½ä¸...</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-else-if="errorMsg"> |
| | | <div class="alert alert-danger">{{ errorMsg }}</div> |
| | | <router-link to="/" class="btn btn-primary">è¿åå表</router-link> |
| | | </div> |
| | | |
| | | <div v-else-if="instance"> |
| | | <div class="d-flex justify-content-between align-items-center mb-4"> |
| | | <div> |
| | | <h2 class="mb-0"> |
| | | <i class="bi bi-info-circle me-2"></i>å®ä¾è¯¦æ
|
| | | </h2> |
| | | <p class="text-muted mb-0 mt-1">{{ instance.name }} ({{ instance.instanceId }})</p> |
| | | </div> |
| | | <router-link to="/" class="btn btn-outline-secondary"> |
| | | <i class="bi bi-arrow-left me-1"></i>è¿åå表 |
| | | </router-link> |
| | | </div> |
| | | |
| | | <!-- ç¶æå¡ç --> |
| | | <div class="row mb-4"> |
| | | <div class="col-md-3"> |
| | | <div class="card text-center"> |
| | | <div class="card-body"> |
| | | <h6 class="card-subtitle mb-2 text-muted">ç¶æ</h6> |
| | | <h4 :class="['mb-0', getStatusClass(instance.status)]"> |
| | | {{ getStatusText(instance.status) }} |
| | | </h4> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="col-md-3"> |
| | | <div class="card text-center"> |
| | | <div class="card-body"> |
| | | <h6 class="card-subtitle mb-2 text-muted">è¿æ¥å®¢æ·ç«¯</h6> |
| | | <h4 class="mb-0"> |
| | | <i class="bi bi-people-fill me-1"></i>{{ instance.clientCount }} |
| | | </h4> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="col-md-3"> |
| | | <div class="card text-center"> |
| | | <div class="card-body"> |
| | | <h6 class="card-subtitle mb-2 text-muted">æ»è¯·æ±æ°</h6> |
| | | <h4 class="mb-0">{{ instance.totalRequests }}</h4> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="col-md-3"> |
| | | <div class="card text-center"> |
| | | <div class="card-body"> |
| | | <h6 class="card-subtitle mb-2 text-muted">端å£</h6> |
| | | <h4 class="mb-0">{{ instance.port }}</h4> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 详ç»ä¿¡æ¯ --> |
| | | <div class="card mb-4"> |
| | | <div class="card-header"> |
| | | <h5 class="mb-0">åºæ¬ä¿¡æ¯</h5> |
| | | </div> |
| | | <div class="card-body"> |
| | | <table class="table table-bordered"> |
| | | <tbody> |
| | | <tr> |
| | | <th style="width: 30%">å®ä¾ID</th> |
| | | <td>{{ instance.instanceId }}</td> |
| | | </tr> |
| | | <tr> |
| | | <th>å®ä¾åç§°</th> |
| | | <td>{{ instance.name }}</td> |
| | | </tr> |
| | | <tr> |
| | | <th>PLCåå·</th> |
| | | <td>{{ getPlcTypeText(instance.plcType) }}</td> |
| | | </tr> |
| | | <tr> |
| | | <th>çå¬ç«¯å£</th> |
| | | <td>{{ instance.port }}</td> |
| | | </tr> |
| | | <tr v-if="instance.startTime"> |
| | | <th>å¯å¨æ¶é´</th> |
| | | <td>{{ formatDate(instance.startTime) }}</td> |
| | | </tr> |
| | | <tr v-if="instance.lastActivityTime"> |
| | | <th>æåæ´»å¨æ¶é´</th> |
| | | <td>{{ formatDate(instance.lastActivityTime) }}</td> |
| | | </tr> |
| | | <tr v-if="instance.errorMessage"> |
| | | <th>é误信æ¯</th> |
| | | <td class="text-danger">{{ instance.errorMessage }}</td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æä½æé® --> |
| | | <div class="card"> |
| | | <div class="card-body"> |
| | | <div class="d-flex gap-2"> |
| | | <button |
| | | v-if="instance.status === 'Stopped' || instance.status === 'Error'" |
| | | class="btn btn-success" |
| | | @click="handleStart" |
| | | > |
| | | <i class="bi bi-play-fill me-1"></i>å¯å¨ |
| | | </button> |
| | | <button |
| | | v-if="instance.status === 'Running'" |
| | | class="btn btn-warning" |
| | | @click="handleStop" |
| | | > |
| | | <i class="bi bi-stop-fill me-1"></i>忢 |
| | | </button> |
| | | <router-link :to="`/edit/${instance.instanceId}`" class="btn btn-primary"> |
| | | <i class="bi bi-pencil-fill me-1"></i>ç¼è¾ |
| | | </router-link> |
| | | <router-link to="/" class="btn btn-outline-secondary"> |
| | | <i class="bi bi-arrow-left me-1"></i>è¿åå表 |
| | | </router-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, onMounted, onUnmounted } from 'vue' |
| | | import { useRoute } from 'vue-router' |
| | | import * as api from '../api' |
| | | import type { InstanceState, InstanceStatus } from '../types' |
| | | |
| | | const route = useRoute() |
| | | |
| | | const instance = ref<InstanceState | null>(null) |
| | | const loading = ref(true) |
| | | const errorMsg = ref('') |
| | | |
| | | let refreshTimer: number | null = null |
| | | |
| | | const id = route.params.id as string |
| | | |
| | | async function loadInstance() { |
| | | try { |
| | | instance.value = await api.getInstance(id) |
| | | if (!instance.value) { |
| | | errorMsg.value = `å®ä¾ "${id}" ä¸åå¨` |
| | | } |
| | | } catch (err) { |
| | | console.error('å è½½å®ä¾å¤±è´¥:', err) |
| | | errorMsg.value = 'å è½½å®ä¾å¤±è´¥ï¼è¯·æ¥çæ§å¶å°' |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | loadInstance() |
| | | // æ¯2ç§å·æ°ä¸æ¬¡ç¶æ |
| | | refreshTimer = window.setInterval(() => { |
| | | if (instance.value && instance.value.status !== 'Stopped') { |
| | | loadInstance() |
| | | } |
| | | }, 2000) |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | if (refreshTimer !== null) { |
| | | clearInterval(refreshTimer) |
| | | } |
| | | }) |
| | | |
| | | async function handleStart() { |
| | | if (confirm(`ç¡®å®è¦å¯å¨å®ä¾ "${id}" å?`)) { |
| | | try { |
| | | await api.startInstance(id) |
| | | await loadInstance() |
| | | } catch (err) { |
| | | console.error('å¯å¨å®ä¾å¤±è´¥:', err) |
| | | alert('å¯å¨å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | } |
| | | } |
| | | } |
| | | |
| | | async function handleStop() { |
| | | if (confirm(`ç¡®å®è¦åæ¢å®ä¾ "${id}" å?`)) { |
| | | try { |
| | | await api.stopInstance(id) |
| | | await loadInstance() |
| | | } catch (err) { |
| | | console.error('忢å®ä¾å¤±è´¥:', err) |
| | | alert('åæ¢å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | } |
| | | } |
| | | } |
| | | |
| | | function getStatusClass(status: InstanceStatus): string { |
| | | const map: Record<InstanceStatus, string> = { |
| | | 'Stopped': 'text-secondary', |
| | | 'Starting': 'text-info', |
| | | 'Running': 'text-success', |
| | | 'Stopping': 'text-warning', |
| | | 'Error': 'text-danger' |
| | | } |
| | | return map[status] || '' |
| | | } |
| | | |
| | | function getStatusText(status: InstanceStatus): string { |
| | | const map: Record<InstanceStatus, string> = { |
| | | 'Stopped': '已忢', |
| | | 'Starting': 'å¯å¨ä¸', |
| | | 'Running': 'è¿è¡ä¸', |
| | | 'Stopping': '忢ä¸', |
| | | 'Error': 'é误' |
| | | } |
| | | return map[status] || status |
| | | } |
| | | |
| | | function getPlcTypeText(plcType: string): string { |
| | | const map: Record<string, string> = { |
| | | 'S7200Smart': 'S7-200 Smart', |
| | | 'S71200': 'S7-1200', |
| | | 'S71500': 'S7-1500', |
| | | 'S7300': 'S7-300', |
| | | 'S7400': 'S7-400' |
| | | } |
| | | return map[plcType] || plcType |
| | | } |
| | | |
| | | function formatDate(dateString: string | null): string { |
| | | if (!dateString) return '-' |
| | | const date = new Date(dateString) |
| | | return date.toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit', |
| | | second: '2-digit' |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .card-subtitle { |
| | | font-size: 0.875rem; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | table th { |
| | | background-color: #f8f9fa; |
| | | font-weight: 600; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <div v-if="loading" class="text-center py-5"> |
| | | <div class="spinner-border text-primary" role="status"> |
| | | <span class="visually-hidden">å è½½ä¸...</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-else-if="errorMsg"> |
| | | <div class="alert alert-danger">{{ errorMsg }}</div> |
| | | <router-link to="/" class="btn btn-primary">è¿åå表</router-link> |
| | | </div> |
| | | |
| | | <div v-else> |
| | | <div class="d-flex justify-content-between align-items-center mb-4"> |
| | | <div> |
| | | <h2 class="mb-0"> |
| | | <i class="bi bi-pencil me-2"></i>ç¼è¾å®ä¾ |
| | | </h2> |
| | | <p class="text-muted mb-0 mt-1">ç¼è¾å®ä¾é
ç½®: {{ form.id }}</p> |
| | | </div> |
| | | <router-link to="/" class="btn btn-outline-secondary"> |
| | | <i class="bi bi-arrow-left me-1"></i>è¿åå表 |
| | | </router-link> |
| | | </div> |
| | | |
| | | <div v-if="isRunning" class="alert alert-warning"> |
| | | <i class="bi bi-exclamation-triangle-fill me-2"></i> |
| | | å®ä¾æ£å¨è¿è¡ä¸ï¼ä¿®æ¹é
ç½®åéè¦éå¯å®ä¾æè½çæ |
| | | </div> |
| | | |
| | | <div class="row justify-content-center"> |
| | | <div class="col-lg-8"> |
| | | <div class="card"> |
| | | <div class="card-body"> |
| | | <form @submit.prevent="handleSubmit"> |
| | | <!-- åºæ¬ä¿¡æ¯ --> |
| | | <h5 class="card-title mb-3">åºæ¬ä¿¡æ¯</h5> |
| | | <div class="row mb-3"> |
| | | <div class="col-md-6"> |
| | | <label for="id" class="form-label">å®ä¾ID</label> |
| | | <input |
| | | type="text" |
| | | class="form-control" |
| | | id="id" |
| | | v-model="form.id" |
| | | disabled |
| | | > |
| | | <div class="form-text">å®ä¾IDå建åä¸å¯ä¿®æ¹</div> |
| | | </div> |
| | | <div class="col-md-6"> |
| | | <label for="name" class="form-label">å®ä¾åç§° *</label> |
| | | <input |
| | | type="text" |
| | | class="form-control" |
| | | id="name" |
| | | v-model="form.name" |
| | | required |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row mb-3"> |
| | | <div class="col-md-6"> |
| | | <label for="plcType" class="form-label">PLCåå· *</label> |
| | | <select class="form-select" id="plcType" v-model="form.plcType" required> |
| | | <option value="S7200Smart">S7-200 Smart</option> |
| | | <option value="S71200">S7-1200</option> |
| | | <option value="S71500">S7-1500</option> |
| | | <option value="S7300">S7-300</option> |
| | | <option value="S7400">S7-400</option> |
| | | </select> |
| | | </div> |
| | | <div class="col-md-6"> |
| | | <label for="port" class="form-label">çå¬ç«¯å£ *</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="port" |
| | | v-model.number="form.port" |
| | | min="1" |
| | | max="65535" |
| | | required |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row mb-3"> |
| | | <div class="col-md-6"> |
| | | <label for="activationKey" class="form-label">HSLæ¿æ´»ç </label> |
| | | <input |
| | | type="text" |
| | | class="form-control" |
| | | id="activationKey" |
| | | v-model="form.activationKey" |
| | | > |
| | | </div> |
| | | <div class="col-md-6 d-flex align-items-center"> |
| | | <div class="form-check"> |
| | | <input class="form-check-input" type="checkbox" id="autoStart" v-model="form.autoStart"> |
| | | <label class="form-check-label" for="autoStart"> |
| | | èªå¨å¯å¨ |
| | | </label> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- å
åé
ç½® --> |
| | | <h5 class="card-title mb-3 mt-4">å
åé
ç½®</h5> |
| | | <div class="row mb-3"> |
| | | <div class="col-md-4"> |
| | | <label for="mRegionSize" class="form-label">Måºå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="mRegionSize" |
| | | v-model.number="form.mRegionSize" |
| | | min="0" |
| | | > |
| | | </div> |
| | | <div class="col-md-4"> |
| | | <label for="iRegionSize" class="form-label">Iåºå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="iRegionSize" |
| | | v-model.number="form.iRegionSize" |
| | | min="0" |
| | | > |
| | | </div> |
| | | <div class="col-md-4"> |
| | | <label for="qRegionSize" class="form-label">Qåºå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="qRegionSize" |
| | | v-model.number="form.qRegionSize" |
| | | min="0" |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row mb-3"> |
| | | <div class="col-md-4"> |
| | | <label for="dbBlockCount" class="form-label">DBåæ°é</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="dbBlockCount" |
| | | v-model.number="form.dbBlockCount" |
| | | min="0" |
| | | > |
| | | </div> |
| | | <div class="col-md-4"> |
| | | <label for="dbBlockSize" class="form-label">DBå大å°</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="dbBlockSize" |
| | | v-model.number="form.dbBlockSize" |
| | | min="0" |
| | | > |
| | | </div> |
| | | <div class="col-md-2"> |
| | | <label for="tRegionCount" class="form-label">宿¶å¨æ°é</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="tRegionCount" |
| | | v-model.number="form.tRegionCount" |
| | | min="0" |
| | | > |
| | | </div> |
| | | <div class="col-md-2"> |
| | | <label for="cRegionCount" class="form-label">计æ°å¨æ°é</label> |
| | | <input |
| | | type="number" |
| | | class="form-control" |
| | | id="cRegionCount" |
| | | v-model.number="form.cRegionCount" |
| | | min="0" |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æäº¤æé® --> |
| | | <div class="d-flex gap-2 mt-4"> |
| | | <button type="submit" class="btn btn-primary" :disabled="submitting"> |
| | | <span v-if="submitting" class="spinner-border spinner-border-sm me-1"></span> |
| | | <i v-else class="bi bi-check-lg me-1"></i> |
| | | {{ submitting ? 'ä¿åä¸...' : 'ä¿åæ´æ¹' }} |
| | | </button> |
| | | <router-link to="/" class="btn btn-outline-secondary">åæ¶</router-link> |
| | | </div> |
| | | </form> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, onMounted } from 'vue' |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | import * as api from '../api' |
| | | import type { InstanceConfig, MemoryRegionConfig, SiemensPLCType } from '../types' |
| | | |
| | | const router = useRouter() |
| | | const route = useRoute() |
| | | |
| | | const form = ref({ |
| | | id: '', |
| | | name: '', |
| | | plcType: 'S71200' as SiemensPLCType, |
| | | port: 102, |
| | | activationKey: '', |
| | | autoStart: false, |
| | | mRegionSize: 1024, |
| | | dbBlockCount: 100, |
| | | dbBlockSize: 1024, |
| | | iRegionSize: 256, |
| | | qRegionSize: 256, |
| | | tRegionCount: 64, |
| | | cRegionCount: 64 |
| | | }) |
| | | |
| | | const loading = ref(true) |
| | | const errorMsg = ref('') |
| | | const submitting = ref(false) |
| | | const isRunning = ref(false) |
| | | |
| | | const id = route.params.id as string |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | // è·åå®ä¾ç¶æ |
| | | const state = await api.getInstance(id) |
| | | if (!state) { |
| | | errorMsg.value = `å®ä¾ "${id}" ä¸åå¨` |
| | | loading.value = false |
| | | return |
| | | } |
| | | |
| | | isRunning.value = state.status === 'Running' |
| | | |
| | | // è·åå®ä¾é
ç½® |
| | | const config = await api.getInstanceConfig(id) |
| | | if (!config) { |
| | | errorMsg.value = `æ æ³å è½½å®ä¾ "${id}" çé
ç½®` |
| | | loading.value = false |
| | | return |
| | | } |
| | | |
| | | form.value = { |
| | | id: config.id, |
| | | name: config.name, |
| | | plcType: config.plcType, |
| | | port: config.port, |
| | | activationKey: config.activationKey, |
| | | autoStart: config.autoStart, |
| | | mRegionSize: config.memoryConfig.mRegionSize, |
| | | dbBlockCount: config.memoryConfig.dBBBlockCount, |
| | | dbBlockSize: config.memoryConfig.dBBBlockSize, |
| | | iRegionSize: config.memoryConfig.iRegionSize, |
| | | qRegionSize: config.memoryConfig.qRegionSize, |
| | | tRegionCount: config.memoryConfig.tRegionCount, |
| | | cRegionCount: config.memoryConfig.cRegionCount |
| | | } |
| | | } catch (err) { |
| | | console.error('å è½½å®ä¾é
置失败:', err) |
| | | errorMsg.value = 'å è½½å®ä¾é
置失败ï¼è¯·æ¥çæ§å¶å°' |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | }) |
| | | |
| | | async function handleSubmit() { |
| | | submitting.value = true |
| | | |
| | | try { |
| | | const memoryConfig: MemoryRegionConfig = { |
| | | mRegionSize: form.value.mRegionSize > 0 ? form.value.mRegionSize : 1024, |
| | | dBBBlockCount: form.value.dbBlockCount > 0 ? form.value.dbBlockCount : 100, |
| | | dBBBlockSize: form.value.dbBlockSize > 0 ? form.value.dbBlockSize : 1024, |
| | | iRegionSize: form.value.iRegionSize > 0 ? form.value.iRegionSize : 256, |
| | | qRegionSize: form.value.qRegionSize > 0 ? form.value.qRegionSize : 256, |
| | | tRegionCount: form.value.tRegionCount > 0 ? form.value.tRegionCount : 64, |
| | | cRegionCount: form.value.cRegionCount > 0 ? form.value.cRegionCount : 64 |
| | | } |
| | | |
| | | const config: InstanceConfig = { |
| | | id: form.value.id, |
| | | name: form.value.name, |
| | | plcType: form.value.plcType, |
| | | port: form.value.port, |
| | | activationKey: form.value.activationKey, |
| | | autoStart: form.value.autoStart, |
| | | memoryConfig |
| | | } |
| | | |
| | | const result = await api.updateInstance(form.value.id, config) |
| | | |
| | | if (result) { |
| | | alert(`å®ä¾ "${form.value.id}" æ´æ°æå!`) |
| | | router.push('/') |
| | | } else { |
| | | alert('æ´æ°å®ä¾å¤±è´¥') |
| | | } |
| | | } catch (err) { |
| | | console.error('æ´æ°å®ä¾å¤±è´¥:', err) |
| | | alert('æ´æ°å®ä¾å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | } finally { |
| | | submitting.value = false |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .card-title { |
| | | color: #495057; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .form-label { |
| | | font-weight: 500; |
| | | color: #495057; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <div class="d-flex justify-content-between align-items-center mb-4"> |
| | | <div> |
| | | <h2 class="mb-0"> |
| | | <i class="bi bi-cpu-fill me-2"></i>S7 PLC 仿çå¨å®ä¾ |
| | | </h2> |
| | | <p class="text-muted mb-0 mt-1">管çåçæ§ S7 PLC 仿çå¨å®ä¾</p> |
| | | </div> |
| | | <div class="d-flex align-items-center gap-3"> |
| | | <div class="text-muted small"> |
| | | è¿è¡ä¸: {{ runningCount }} | 已忢: {{ stoppedCount }} |
| | | <span v-if="errorCount > 0" class="text-danger">| é误: {{ errorCount }}</span> |
| | | </div> |
| | | <router-link to="/create" class="btn btn-primary"> |
| | | <i class="bi bi-plus-lg me-1"></i>å建å®ä¾ |
| | | </router-link> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- Loading state --> |
| | | <div v-if="loading && instances.length === 0" class="text-center py-5"> |
| | | <div class="spinner-border text-primary" role="status"> |
| | | <span class="visually-hidden">å è½½ä¸...</span> |
| | | </div> |
| | | <p class="mt-3 text-muted">æ£å¨å è½½å®ä¾å表...</p> |
| | | </div> |
| | | |
| | | <!-- Empty state --> |
| | | <div v-else-if="instances.length === 0" class="empty-state"> |
| | | <i class="bi bi-inbox"></i> |
| | | <h3>ææ å®ä¾</h3> |
| | | <p>ç¹å»ä¸æ¹"å建å®ä¾"æé®æ¥å建æ¨ç第ä¸ä¸ªä»¿çå¨å®ä¾</p> |
| | | </div> |
| | | |
| | | <!-- Instances grid --> |
| | | <div v-else class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4"> |
| | | <div v-for="instance in instances" :key="instance.instanceId" class="col"> |
| | | <div :class="['card', 'instance-card', 'h-100', getStatusClass(instance.status)]"> |
| | | <div class="card-header d-flex justify-content-between align-items-center"> |
| | | <h5 class="card-title mb-0">{{ instance.instanceId }}</h5> |
| | | <span :class="['badge', getStatusClass(instance.status)]"> |
| | | {{ getStatusText(instance.status) }} |
| | | </span> |
| | | </div> |
| | | <div class="card-body"> |
| | | <div class="instance-info mb-3"> |
| | | <div class="row mb-2"> |
| | | <div class="col-6"> |
| | | <small class="instance-info-label">åç§°</small> |
| | | <div class="instance-info-value">{{ instance.name || '-' }}</div> |
| | | </div> |
| | | <div class="col-6"> |
| | | <small class="instance-info-label">PLCåå·</small> |
| | | <div class="instance-info-value">{{ getPlcTypeText(instance.plcType) }}</div> |
| | | </div> |
| | | </div> |
| | | <div class="row mb-2"> |
| | | <div class="col-6"> |
| | | <small class="instance-info-label">端å£</small> |
| | | <div class="instance-info-value">{{ instance.port || '-' }}</div> |
| | | </div> |
| | | <div class="col-6"> |
| | | <small class="instance-info-label">客æ·ç«¯</small> |
| | | <div class="instance-info-value"> |
| | | <i class="bi bi-people-fill me-1"></i>{{ instance.clientCount || 0 }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div v-if="instance.startTime" class="row"> |
| | | <div class="col-12"> |
| | | <small class="instance-info-label">å¯å¨æ¶é´</small> |
| | | <div class="instance-info-value small">{{ formatDate(instance.startTime) }}</div> |
| | | </div> |
| | | </div> |
| | | <div v-if="instance.errorMessage" class="alert alert-danger alert-sm mt-2 mb-0 py-2 small"> |
| | | <i class="bi bi-exclamation-triangle-fill me-1"></i>{{ instance.errorMessage }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="card-footer bg-white"> |
| | | <div class="action-buttons d-flex gap-2"> |
| | | <button |
| | | v-if="instance.status === 'Running'" |
| | | class="btn btn-warning btn-sm flex-fill" |
| | | @click="handleStop(instance.instanceId)" |
| | | > |
| | | <i class="bi bi-stop-fill me-1"></i>忢 |
| | | </button> |
| | | <button |
| | | v-if="instance.status === 'Stopped'" |
| | | class="btn btn-success btn-sm flex-fill" |
| | | @click="handleStart(instance.instanceId)" |
| | | > |
| | | <i class="bi bi-play-fill me-1"></i>å¯å¨ |
| | | </button> |
| | | <router-link :to="`/details/${instance.instanceId}`" class="btn btn-info btn-sm text-white flex-fill"> |
| | | <i class="bi bi-info-circle-fill me-1"></i>详æ
|
| | | </router-link> |
| | | <router-link :to="`/edit/${instance.instanceId}`" class="btn btn-primary btn-sm flex-fill"> |
| | | <i class="bi bi-pencil-fill me-1"></i>ç¼è¾ |
| | | </router-link> |
| | | <button class="btn btn-danger btn-sm" @click="handleDelete(instance.instanceId)"> |
| | | <i class="bi bi-trash-fill"></i> |
| | | </button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { onMounted, onUnmounted } from 'vue' |
| | | import { storeToRefs } from 'pinia' |
| | | import { useInstancesStore } from '../stores/instances' |
| | | |
| | | const store = useInstancesStore() |
| | | const { instances, loading, runningCount, stoppedCount, errorCount } = storeToRefs(store) |
| | | |
| | | onMounted(() => { |
| | | store.loadInstances() |
| | | store.startAutoRefresh(2000) |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | store.stopAutoRefresh() |
| | | }) |
| | | |
| | | function handleStart(id: string) { |
| | | if (confirm(`ç¡®å®è¦å¯å¨å®ä¾ "${id}" å?`)) { |
| | | store.startInstance(id).catch(() => { |
| | | alert('å¯å¨å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | }) |
| | | } |
| | | } |
| | | |
| | | function handleStop(id: string) { |
| | | if (confirm(`ç¡®å®è¦åæ¢å®ä¾ "${id}" å?`)) { |
| | | store.stopInstance(id).catch(() => { |
| | | alert('åæ¢å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | }) |
| | | } |
| | | } |
| | | |
| | | function handleDelete(id: string) { |
| | | if (confirm(`ç¡®å®è¦å é¤å®ä¾ "${id}" å?æ¤æä½ä¸å¯æ¤é!`)) { |
| | | store.deleteInstance(id).catch(() => { |
| | | alert('å é¤å¤±è´¥ï¼è¯·æ¥çæ§å¶å°') |
| | | }) |
| | | } |
| | | } |
| | | |
| | | function getStatusClass(status: string): string { |
| | | const map: Record<string, string> = { |
| | | 'Stopped': 'status-stopped', |
| | | 'Starting': 'status-starting', |
| | | 'Running': 'status-running', |
| | | 'Stopping': 'status-stopping', |
| | | 'Error': 'status-error' |
| | | } |
| | | return map[status] || '' |
| | | } |
| | | |
| | | function getStatusText(status: string): string { |
| | | const map: Record<string, string> = { |
| | | 'Stopped': '已忢', |
| | | 'Starting': 'å¯å¨ä¸', |
| | | 'Running': 'è¿è¡ä¸', |
| | | 'Stopping': '忢ä¸', |
| | | 'Error': 'é误' |
| | | } |
| | | return map[status] || status |
| | | } |
| | | |
| | | function getPlcTypeText(plcType: string): string { |
| | | const map: Record<string, string> = { |
| | | 'S7200Smart': 'S7-200 Smart', |
| | | 'S71200': 'S7-1200', |
| | | 'S71500': 'S7-1500', |
| | | 'S7300': 'S7-300', |
| | | 'S7400': 'S7-400' |
| | | } |
| | | return map[plcType] || plcType |
| | | } |
| | | |
| | | function formatDate(dateString: string | null): string { |
| | | if (!dateString) return '-' |
| | | const date = new Date(dateString) |
| | | return date.toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit', |
| | | second: '2-digit' |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .instance-card { |
| | | transition: transform 0.2s, box-shadow 0.2s; |
| | | } |
| | | |
| | | .instance-card:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .instance-info-label { |
| | | color: #6c757d; |
| | | font-size: 0.75rem; |
| | | text-transform: uppercase; |
| | | letter-spacing: 0.5px; |
| | | } |
| | | |
| | | .instance-info-value { |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .action-buttons { |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .status-stopped { border-left: 4px solid #6c757d; } |
| | | .status-starting { border-left: 4px solid #0dcaf0; } |
| | | .status-running { border-left: 4px solid #198754; } |
| | | .status-stopping { border-left: 4px solid #ffc107; } |
| | | .status-error { border-left: 4px solid #dc3545; } |
| | | |
| | | .empty-state { |
| | | text-align: center; |
| | | padding: 4rem 2rem; |
| | | color: #6c757d; |
| | | } |
| | | |
| | | .empty-state i { |
| | | font-size: 4rem; |
| | | margin-bottom: 1rem; |
| | | } |
| | | |
| | | .empty-state h3 { |
| | | margin-bottom: 0.5rem; |
| | | } |
| | | |
| | | .alert-sm { |
| | | font-size: 0.875rem; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /// <reference types="vite/client" /> |
| | | |
| | | declare module '*.vue' { |
| | | import type { DefineComponent } from 'vue' |
| | | const component: DefineComponent<{}, {}, any> |
| | | export default component |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "compilerOptions": { |
| | | "target": "ES2020", |
| | | "useDefineForClassFields": true, |
| | | "module": "ESNext", |
| | | "lib": ["ES2020", "DOM", "DOM.Iterable"], |
| | | "skipLibCheck": true, |
| | | "moduleResolution": "bundler", |
| | | "allowImportingTsExtensions": true, |
| | | "resolveJsonModule": true, |
| | | "isolatedModules": true, |
| | | "noEmit": true, |
| | | "jsx": "preserve", |
| | | "strict": true, |
| | | "noUnusedLocals": true, |
| | | "noUnusedParameters": true, |
| | | "noFallthroughCasesInSwitch": true, |
| | | "baseUrl": ".", |
| | | "paths": { |
| | | "@/*": ["src/*"] |
| | | } |
| | | }, |
| | | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], |
| | | "references": [{ "path": "./tsconfig.node.json" }] |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "compilerOptions": { |
| | | "composite": true, |
| | | "skipLibCheck": true, |
| | | "module": "ESNext", |
| | | "moduleResolution": "bundler", |
| | | "allowSyntheticDefaultImports": true |
| | | }, |
| | | "include": ["vite.config.ts"] |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineConfig } from 'vite' |
| | | import vue from '@vitejs/plugin-vue' |
| | | |
| | | export default defineConfig({ |
| | | plugins: [vue()], |
| | | server: { |
| | | port: 3000, |
| | | proxy: { |
| | | '/api': { |
| | | target: 'http://localhost:5000', |
| | | changeOrigin: true |
| | | } |
| | | } |
| | | } |
| | | }) |