diff --git a/backend/pom.xml b/backend/pom.xml index 34e1ce260ee24c98de09f42a1fcdde52ad470050..34079315642af4e3efb7b5a8201dadc2fa483678 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -59,8 +59,7 @@ org.projectlombok lombok - 1.18.34 - provided + 1.18.42 @@ -95,7 +94,23 @@ - + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + **/com/unionbigdata/teaching/vo/DataColumnVO.java + **/com/unionbigdata/teaching/service/impl/DataColumnServiceImpl.java + **/com/unionbigdata/teaching/service/IDataColumnService.java + **/com/unionbigdata/teaching/mapper/DataColumnMapper.java + **/com/unionbigdata/teaching/entity/DataColumnEntity.java + + + + + org.springframework.boot spring-boot-maven-plugin diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/CheckResultDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/CheckResultDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..aff92796a8a14fed87da076db9cf6f72cc990526 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/CheckResultDTO.java @@ -0,0 +1,10 @@ +package com.unionbigdata.teaching.DTO; + +import lombok.Data; +import java.util.Map; + +@Data +public class CheckResultDTO { + private Map data; // 业务表原始数据 + private Map highlightMap; // 数据项高亮标记 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/CollectInfoColumnDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/CollectInfoColumnDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..e1dac5fae0621c334eefb7219e2b96c495bc7285 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/CollectInfoColumnDTO.java @@ -0,0 +1,14 @@ +package com.unionbigdata.teaching.DTO; + +import lombok.Data; + +/** + * 采集字段DTO,返回给前端的列名信息 + */ +@Data +public class CollectInfoColumnDTO { + private String columnName; // 字段名 + private String columnType; // 字段类型 + private String columnComment; // 字段备注 + private Integer length; // 字段长度 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/CollectInfoSubmitDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/CollectInfoSubmitDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..cefe48514e9dc88d103082353baf6765e18479b7 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/CollectInfoSubmitDTO.java @@ -0,0 +1,14 @@ +package com.unionbigdata.teaching.DTO; + +import lombok.Data; +import java.util.List; +import java.util.Map; + +/** + * 采集信息提交DTO,接收前端批量上报的数据 + */ +@Data +public class CollectInfoSubmitDTO { + private Integer taskId; // 任务ID + private List> tableDataList; // 批量填写的数据列表 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/CreateTableDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/CreateTableDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..50d6c92a4303ac4dea1864cfa8eb12d4df8e2635 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/CreateTableDTO.java @@ -0,0 +1,16 @@ +package com.unionbigdata.teaching.DTO; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class CreateTableDTO { + + // 表名 + private String tableName; + + // 动态表格行数据:每一行是“字段名→值”的键值对。一个Map可以装很多,一个Map存一行;如<字段名,姓名> + private List> tableRows; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/DynamicTableRequestDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/DynamicTableRequestDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..4bb4a46e40d2aefa5733b548d7e9448391126873 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/DynamicTableRequestDTO.java @@ -0,0 +1,17 @@ +package com.unionbigdata.teaching.DTO; +import lombok.Data; +import java.util.List; +import java.util.Map; + +/** + * 接收动态表格数据的DTO + */ +@Data +public class DynamicTableRequestDTO { + // 补充采集任务ID(关联该任务的字段配置) + private Integer taskId; + // 该表的字段名 + private List filedName; + // 动态表格行数据:每一行是“字段名→值”的键值对。一个Map可以装很多,一个Map存一行 + private List> tableRows; +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/SelectColumnDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/SelectColumnDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..a731a055ccc2b78bbfc3d429681287e8a62cfd68 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/SelectColumnDTO.java @@ -0,0 +1,19 @@ +package com.unionbigdata.teaching.DTO; + +import lombok.Data; + +import java.util.List; + +@Data +public class SelectColumnDTO { + //列名 + String columnName; + //注释或备注 + private String columnComment; + // 对应column_type(字段类型) + private String columnType; + //是否采集 + private Integer isCollect; + //数据长度 + private Integer length; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/SensitiveWordBatchDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/SensitiveWordBatchDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..c4e5994a5f2831bef900b5560b82a8fb3da2381b --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/SensitiveWordBatchDTO.java @@ -0,0 +1,16 @@ +package com.unionbigdata.teaching.DTO; + +import com.unionbigdata.teaching.entity.SensitiveWord; +import lombok.Data; + +import java.util.List; + +@Data +public class SensitiveWordBatchDTO {//用于前端“敏感词设置”页面 + // 新增的敏感词列表 + private List add; + // 修改的敏感词列表 + private List update; + // 删除的敏感词列表 + private List delete; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/DTO/TaskAddDTO.java b/backend/src/main/java/com/unionbigdata/teaching/DTO/TaskAddDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..97d897a8c8dd77d9b8e42504e2b6fc7e7fafca9f --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/DTO/TaskAddDTO.java @@ -0,0 +1,53 @@ +package com.unionbigdata.teaching.DTO; + +import com.unionbigdata.teaching.vo.QualityRuleVO; +import com.unionbigdata.teaching.vo.TableFieldVO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +@Data +public class TaskAddDTO { + //第一步所用数据 + private Integer creatorId; // 新增时必填,编辑时不传 + //任务类型 + private Integer taskId; + //任务名称 + private String taskName; + //版本号 + private String version; + //任务描述 + private String taskDescription; + //是否开启敏感词检测 + private Integer isSensitiveDetection; + //数据源id,新建任务后,根据数据源id可以找到对应的数据库,进而找到对应的表 + private Integer dataSourceId; + + + + + + + + + //数据表id,这个是创建的新表的id(根据table_id判断是新增表 or 选择已有表,若table_id存在则是选择已有表,否则是新增表) + private Integer tableId; + //选择已有表时,存储表字段 + private List selectColumnDTO; + + //存储动态建立数据表所用的数据 + @NotEmpty(message = "至少需要1个字段") + private List fields; // 字段列表 + @NotBlank(message = "表名不能为空") + private String tableName; // 用户自定义的表名 + private Long fillerId; // 关联的用户ID(从前端传入) + + + + //质检规则 + private List qualityRuleVOList; + + +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/common/Result.java b/backend/src/main/java/com/unionbigdata/teaching/common/Result.java index 1363a5cac807325f3647b9325c26a5d41a407372..a67cb85b7b6958d791d4235dfb38dbafb8f91452 100644 --- a/backend/src/main/java/com/unionbigdata/teaching/common/Result.java +++ b/backend/src/main/java/com/unionbigdata/teaching/common/Result.java @@ -11,20 +11,17 @@ public class Result implements Serializable { public static final long serialVersionUID = 42L; public static final String SUCCESS_CODE = "200"; public static final String FAIL_CODE = "500"; - public static final String SUCCESS_MSG = "success"; public static final String FAIL_MSG = "fail"; private String code; - private String msg; private T content; private String requestId; - /** - * 先保留原id,避免其他版本报错 - */ private String id; + + // (保留你原有的所有方法) public static Result ok() { Result r = new Result(Result.SUCCESS_CODE, Result.SUCCESS_MSG); return r; @@ -56,6 +53,13 @@ public class Result implements Serializable { return r; } + // ========== 新增这个方法:解决“找不到okWithMsg”的问题 ========== + public static Result okWithMsg(String msg) { + return new Result(SUCCESS_CODE, msg); + } + + + // (保留你原有的构造方法和success方法) public Result() { } diff --git a/backend/src/main/java/com/unionbigdata/teaching/config/CorsConfig.java b/backend/src/main/java/com/unionbigdata/teaching/config/CorsConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..8861d3032b45def4c96d4fbe453856f54c75f959 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/config/CorsConfig.java @@ -0,0 +1,26 @@ +package com.unionbigdata.teaching.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +@Configuration +public class CorsConfig { + + // 当前跨域请求最大有效时长。这里默认1天 + private static final long MAX_AGE = 24 * 60 * 60; + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址 + corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头 + corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法 + corsConfiguration.setMaxAge(MAX_AGE); + source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置 + return new CorsFilter(source); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/CollectInfoController.java b/backend/src/main/java/com/unionbigdata/teaching/controller/CollectInfoController.java new file mode 100644 index 0000000000000000000000000000000000000000..b605b949702b32e15f917d91ba660550af93b949 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/controller/CollectInfoController.java @@ -0,0 +1,31 @@ +package com.unionbigdata.teaching.controller; + +import com.unionbigdata.teaching.DTO.CollectInfoColumnDTO; +import com.unionbigdata.teaching.DTO.CollectInfoSubmitDTO; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.sevice.ICollectInfoService; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import java.util.List; + +@RestController +@RequestMapping("/collect/info") +public class CollectInfoController { + + @Resource + private ICollectInfoService collectInfoService; + + // 根据task_id获取采集列名 + @GetMapping("/columns") + public Result> getTableColumnsByTaskId(@RequestParam Integer taskId) { + List columns = collectInfoService.getTableColumnsByTaskId(taskId); + return Result.ok(columns); + } + + // 批量上报采集数据 + @PostMapping("/submit") + public Result submitCollectInfo(@RequestBody CollectInfoSubmitDTO submitDTO) { + Integer count = collectInfoService.submitCollectInfo(submitDTO); + return Result.ok(count); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/DataSourceController.java b/backend/src/main/java/com/unionbigdata/teaching/controller/DataSourceController.java new file mode 100644 index 0000000000000000000000000000000000000000..6cd0925b4c78b5d2bd5587dbbb3df787f7044e89 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/controller/DataSourceController.java @@ -0,0 +1,34 @@ +package com.unionbigdata.teaching.controller; + +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.entity.DataSource; +import com.unionbigdata.teaching.sevice.impl.DataSourceServiceImpl; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/datasource") +@Tag(name = "数据源模块", description = "与数据源有关的接口") +public class DataSourceController { + + @Autowired + private DataSourceServiceImpl dataSourceService; + +/** + * 获取数据源列表的请求处理方法 + * 该方法映射到 "/list" 路径,用于处理获取数据源列表的请求 + * + * @return 返回一个包含数据源列表的Result对象,目前返回null + */ + @GetMapping("/list") + @Operation(summary = "查询全部数据源", description = "返回全部数据源务") + public Result> list(){ + return Result.ok(dataSourceService.list()); + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/QualityController.java b/backend/src/main/java/com/unionbigdata/teaching/controller/QualityController.java new file mode 100644 index 0000000000000000000000000000000000000000..e7cde32eb450986bac876297e028c7655eb61691 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/controller/QualityController.java @@ -0,0 +1,81 @@ +package com.unionbigdata.teaching.controller; + +import com.unionbigdata.teaching.entity.QualityRuleEntity; +import com.unionbigdata.teaching.vo.QualityResultVO; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.ibatis.annotations.Param; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import com.unionbigdata.teaching.DTO.CheckResultDTO; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.sevice.IQualityRuleService; +import com.unionbigdata.teaching.sevice.IQualityCheckService; +import com.unionbigdata.teaching.vo.QualityRuleVO; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api/quality") +@Tag(name = "质检模块", description = "质检核心接口(仅2个)") +public class QualityController { + + @Autowired + private IQualityRuleService qualityRuleService; + @Autowired + private IQualityCheckService qualityCheckService; + + // ========== 接口1:上传/保存质检规则 【新增+编辑 统一入口】 ========== + // 新增:不传id 编辑:传id paramId/ruleId全部自增/自动绑定 无需前端传 + @PostMapping("/saveRule") + public Result saveRule(@RequestParam("taskId") Integer taskId, + @RequestParam("creatorId") Integer creatorId, + @RequestBody List qualityRules) { + boolean result = qualityRuleService.saveRule(taskId, creatorId, qualityRules); + return Result.ok(result); + } + + // ========== 接口2:执行质检校验 【唯一质检接口】 ========== + // 入参:taskId 出参:带高亮标记的业务数据列表 + @GetMapping("/executeCheck") + public Result> executeCheck(@RequestParam Integer taskId) { + List result = qualityCheckService.executeQualityCheckByTaskId(taskId); + return Result.ok(result); + } + + + @GetMapping("/listAllResults") + @ApiOperation("展示所有质检结果") + public ResponseEntity> listAllQualityResults() { + List resultList = qualityRuleService.listAllQualityResults(); + return ResponseEntity.ok(Map.of( + "code", 200, + "msg", "查询成功", + "data", resultList + )); + } + + @GetMapping("/listResults") + public ResponseEntity> listQualityResults( + @RequestParam(required = false) String taskName, // 替换为taskName + @RequestParam(required = false) String startTime, + @RequestParam(required = false) String endTime + ) { + try { + List resultList = qualityRuleService.listQualityResultsByCombination(taskName, startTime, endTime); + return ResponseEntity.ok(Map.of( + "code", 200, + "msg", "查询成功", + "data", resultList + )); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("code", 400, "msg", e.getMessage(), "data", null)); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/SensitiveWordController.java b/backend/src/main/java/com/unionbigdata/teaching/controller/SensitiveWordController.java new file mode 100644 index 0000000000000000000000000000000000000000..34309f9061a71a5b957808d1672036210f64c804 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/controller/SensitiveWordController.java @@ -0,0 +1,80 @@ +package com.unionbigdata.teaching.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.unionbigdata.teaching.DTO.DynamicTableRequestDTO; +import com.unionbigdata.teaching.DTO.SensitiveWordBatchDTO; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.entity.SensitiveWord; +import com.unionbigdata.teaching.sevice.ISensitiveWordService; +import com.unionbigdata.teaching.vo.SensitiveWordVO; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/sensitiveWord") +@Tag(name = "敏感词模块", description = "与敏感词有关的接口") +public class SensitiveWordController { + + @Autowired + private ISensitiveWordService sensitiveWordService; + + @GetMapping("/list")//返回全部敏感词 + public Result> findAllSensitiveWord(){ + return Result.ok(sensitiveWordService.findAllSensitiveWord()); + } + +/** + * 添加敏感词的接口方法 + * @param sensitiveWord 敏感词信息,通过请求体传递 + * @return 返回操作结果,包含添加的敏感词ID + */ + @PostMapping//添加敏感词 + public Result addSensitiveWord(@RequestBody SensitiveWord sensitiveWord){ + return Result.ok(sensitiveWordService.addSensitiveWord(sensitiveWord)); + } + + @DeleteMapping("/{id}")//根据id删除敏感词 + public Result deleteSensitiveWord(@PathVariable Integer id){ + return Result.ok(sensitiveWordService.deleteSensitiveWord(id)); + } + +// // 批量修改 +// @PostMapping("/updateSensitiveWordBatch") +// public Result updateSensitiveWordBatch(@RequestBody List sensitiveWordList) { +// // 调用Service的批量修改方法 +// int count = sensitiveWordService.updateSensitiveWordBatch(sensitiveWordList); +// return Result.ok(count); // 返回修改的记录数 +// } + + // 批量修改 + @PostMapping("/batch") + public Result updateSensitiveWordBatch(@RequestBody SensitiveWordBatchDTO batchDTO) { + return Result.ok(sensitiveWordService.updateSensitiveWordBatch(batchDTO.getAdd(), batchDTO.getUpdate(), batchDTO.getDelete())); + } + + @GetMapping("/page")//分页查询 + public Result findPage(@RequestParam Integer pageNum, + @RequestParam Integer pageSize) { + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + //queryWrapper.orderByDesc(User::getId); //设置降序查询,默认升序 + + Page page = new Page<>(pageNum,pageSize);//Page中的User要与userSerice对应 + + return Result.ok(sensitiveWordService.page(page, queryWrapper)); + } + + @PostMapping("/dataFilter") + public Result checkAndReplaceSensitiveWord(@RequestBody DynamicTableRequestDTO dynamicDTO) {//如何接收不同表的实体? + return Result.ok(sensitiveWordService.checkAndReplaceSensitiveWord(dynamicDTO)); + } + + @PostMapping("/cs") + public Result cs(@RequestBody String str){ + return Result.ok(sensitiveWordService.cs(str)); + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/TableOperateController.java b/backend/src/main/java/com/unionbigdata/teaching/controller/TableOperateController.java new file mode 100644 index 0000000000000000000000000000000000000000..005b5448130c784a8b8e62e6cebff383974a0f31 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/controller/TableOperateController.java @@ -0,0 +1,53 @@ +package com.unionbigdata.teaching.controller; + +import com.unionbigdata.teaching.sevice.ITableOperateService; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.vo.TableCreateVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/table/visual") +@Tag(name = "可视化建表模块", description = "用户自定义表名、字段的可视化建表接口") +public class TableOperateController { + + private final ITableOperateService tableOperateService; + + public TableOperateController(ITableOperateService tableOperateService) { + this.tableOperateService = tableOperateService; + } + + // 原有接口:建表+列表名 + @PostMapping("/create") + @Operation(summary = "可视化创建表", description = "用户输入表名、字段后,动态创建表并保存配置") + public Result createTable(@Valid @RequestBody TableCreateVO tableCreateVO) { + return Result.ok(tableOperateService.createTableByVisual(tableCreateVO)); + } + + @GetMapping("{id}") + @Operation(summary = "查询该数据源已创建的表名", description = "返回所有可视化创建的表名,用于下拉选择") + public Result>> listAllTableNames(@PathVariable Long id) { + return tableOperateService.listAllTableNames(id); + } + + // ========== 新增:查询表结构(点击表名时调用) ========== + @GetMapping("/columns") + @Operation(summary = "查询表结构", description = "返回指定表的字段信息(字段名、类型、长度)") + public Result>> getTableColumns(@RequestParam String tableName, + @RequestParam(required = false) Integer taskId, + @RequestParam Integer nowTableId) { + return tableOperateService.getTableColumns(tableName,taskId,nowTableId); + } + + // ========== 新增:查询表数据(点击表名时调用) ========== + @GetMapping("/data") + @Operation(summary = "查询表数据", description = "返回指定表的前10条数据") + public Result>> getTableData(@RequestParam String tableName) { + return tableOperateService.getTableData(tableName); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/TaskController.java b/backend/src/main/java/com/unionbigdata/teaching/controller/TaskController.java new file mode 100644 index 0000000000000000000000000000000000000000..4afe8e2dfc7af9c0aabf8e60d504889e8cd6715c --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/controller/TaskController.java @@ -0,0 +1,110 @@ +package com.unionbigdata.teaching.controller; + +import com.unionbigdata.teaching.DTO.DynamicTableRequestDTO; +import com.unionbigdata.teaching.DTO.TaskAddDTO; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.sevice.IQualityRuleService; +import com.unionbigdata.teaching.sevice.ITaskService; +import com.unionbigdata.teaching.vo.TaskVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.util.ObjectUtils; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/task") +@Tag(name = "任务模块", description = "与任务有关的接口") +public class TaskController { + + @Autowired + private ITaskService taskService; + + + + /** + * 用@RequestParam接收查询参数 + * @param timeType 前端下拉框的“发布时间”(可选) + * @param startDate 开始日期(可选,需指定格式) + * @param endDate 结束日期(可选,需指定格式) + * @param taskName 任务名称(可选) + */ + @GetMapping("/list") + @Operation(summary = "按条件获取全部任务", description = "可选时间范围、发布/创建时间来筛选任务") + public List getTaskList( + @RequestParam(value = "timeType", required = false) String timeType, + @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate, + @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate, + @RequestParam(value = "taskName", required = false) String taskName + ) { + // 将单个参数传给Service层处理 + return taskService.queryTaskList(timeType, startDate, endDate, taskName); + } + +/** + * 根据任务ID获取任务信息的接口方法 + * @param id 任务ID,通过路径变量传递 + * @return 返回一个Result对象,包含任务信息的Map集合 + */ + @GetMapping("/addOrEdit/{id}") + @Operation(summary = "返回任务的基本信息", description = "用户点击编辑按钮后,返回该任务的基本信息") + public Result> addOrEditTaskById(@PathVariable Integer id){ + // 调用taskService的getTaskById方法获取任务信息,并封装到Result对象中返回 + return Result.ok(taskService.getTaskById(id)); + } + + @Operation(summary = "获取任务所用表id和表name", description = "通过任务id查询响应的表id和表name") + @GetMapping("/detail/{id}") + public Result> getTaskDetailByTaskId(@PathVariable Integer id){ + return Result.ok(taskService.getTaskDetailByTaskId(id)); + } + + @Operation(summary = "批量删除任务", description = "通过多选框选择多个任务,然后删除") + @PostMapping("/del/batch")//批量删除 + public Result deleteBatch(@RequestBody List ids) { + return Result.ok(taskService.removeTaskBatchByIds(ids)); + } + + @PostMapping("/datacollect")//数据采集 + public Result dataCollect(@RequestBody DynamicTableRequestDTO dynamicDTO) { + return Result.ok(taskService.dataCollect(dynamicDTO)); + } + + @Operation(summary = "新增或编辑任务的最终请求", description = "接收任务的基本信息、选择的表/动态建表信息,进行新增或编辑任务
" + + "①新增任务 且 选择已有表 :taskId为空 且 tableId不为空 且 selectColumnDTO不为空 且 fields为空
" + + "②新增任务 且 动态建表 :taskId为空 且 tableId为空 且 tableName不为空 且 selectColumnDTO为空 且 fields不为空
" + + "③编辑任务 且 选择已有表 :taskId不为空 且 tableId不为空 且 selectColumnDTO不为空 且 fields为空
" + + "④编辑任务 且 动态建表 :taskId不为空 且 tableId为空 且 tableName不为空 且 selectColumnDTO为空 且 fields不为空
" + + "selectColumnDTO与fields二选一,建表时选fields,不建表选selectColumnDTO
" + + "qualityRuleVO是质检规则") + @PostMapping("/addOrUpdateTask")//新增或编辑任务 + public Result taskAddOrUpdate(@RequestBody TaskAddDTO taskAddDTO) { + if (ObjectUtils.isEmpty(taskAddDTO.getTaskId())){// 如果taskId为空,则是新增任务 + if(ObjectUtils.isEmpty(taskAddDTO.getTableId())){//无table_id则要新建表,已完成! + System.err.println("无tableId,要新建task + 新建表 + 绑定字段与任务"); + return Result.ok(taskService.noTableIdAndAddTask(taskAddDTO)); + }else {//有table_id则选择已有表 + System.err.println("有tableId,要新建task + 绑定字段与任务"); + return Result.ok(taskService.haveTableIdAndAddTask(taskAddDTO)); + } + } + else {// 如果taskId不为空,则是 编辑 任务 + //tableId + tableName联合判断是否需要建表 + if (ObjectUtils.isEmpty(taskAddDTO.getTableId())) {//无table_id则要新建表,已完成! + System.err.println("无tableId,修改task相关信息 + 新建表 + 绑定字段与任务"); + return Result.ok(taskService.noTableIdAndEditTask(taskAddDTO)); + } + else{// 有table_id,不用新建表 + System.err.println("有tableId,修改task相关信息 + 要删除原来的绑定字段与任务 + 修改绑定字段的采集情况");//有tableId、tableName + return Result.ok(taskService.haveTableIdAndEditTask(taskAddDTO)); + } + } + + } + //编辑任务(可能会换表,需要删除此任务之前配置的表和关联的columns) +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/CollectInfoEntity.java b/backend/src/main/java/com/unionbigdata/teaching/entity/CollectInfoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..58c1033d6e4787d1676ac2157034a6872c8ddce1 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/CollectInfoEntity.java @@ -0,0 +1,21 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 采集信息实体类 + */ +@Data +@TableName("collect_info") +public class CollectInfoEntity { + @TableId(type = IdType.AUTO) + private Integer id; + private Integer taskId; + private String tableName; + private String columnName; + private String columnValue; + private Integer createTime; // 修复:统一为Integer,和库表字段匹配 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/DataSource.java b/backend/src/main/java/com/unionbigdata/teaching/entity/DataSource.java new file mode 100644 index 0000000000000000000000000000000000000000..f4ff2b819a433b28b73fb87cfcaee5151c81889c --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/DataSource.java @@ -0,0 +1,16 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@TableName("data_source") +@Data +public class DataSource { + @TableId(value = "id",type = IdType.AUTO) + private Integer id; + + //数据源名称 + private String dataSourceName; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/DataTableConfigEntity.java b/backend/src/main/java/com/unionbigdata/teaching/entity/DataTableConfigEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..047b11e041726a0a175c6d9c8f6f7778167c7f37 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/DataTableConfigEntity.java @@ -0,0 +1,42 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; +import lombok.Data; + +import java.time.LocalDateTime; + +@TableName("data_table_config") // 对应你的表名 +@Data +public class DataTableConfigEntity { + @TableId(value = "id", type = IdType.AUTO) // 自增主键 + @NotNull(message = "Id不能为空!") + private Integer id; + + @NotNull(message = "字段数量不能为空") + @PositiveOrZero(message = "字段数量不能小于0") + private Integer fieldCount; // 对应数据库field_count(字段数量) + + @NotNull(message = "表名不能为空!") + private String tableName; // 对应table_name(用户创建的表名) + + @NotNull(message = "taskId不能为空!") + private Integer taskId; // 对应task_id(关联任务ID) + + @NotNull(message = "fillerId不能为空!") + private Integer fillerId; // 对应filler_id(关联用户ID) + + @NotNull(message = "isPrimaryKey不能为空!") + private Boolean isPrimaryKey; // 是否为主键 + + private Integer columnLength; // 精度 + + private Integer dataSourceId; // 对应datasource_id(关联数据源ID) + + private LocalDateTime createTime; // 对应create_time + + private LocalDateTime updateTime; // 对应update_time +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/FillDataColumnEntity.java b/backend/src/main/java/com/unionbigdata/teaching/entity/FillDataColumnEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..4ae6dfcf1f0bc46fed0c0cfd4cf82214a76671c2 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/FillDataColumnEntity.java @@ -0,0 +1,38 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +@TableName("fill_data_column") // 对应你的表名 +@Data +public class FillDataColumnEntity { + @TableId(value = "id", type = IdType.AUTO) + @NotNull(message = "Id不能为空!") + private Integer id; + @NotNull(message = "fillDataId不能为空!") + private Integer tableId; // 对应fill_data_id(关联fill_data的id) + + @NotNull(message = "字段名称不能为空!") + private String columnName; // 对应column_name(字段名) + + @NotNull(message = "字段类型不能为空!") + private String columnType; // 对应column_type(字段类型) + + private LocalDateTime createTime; + private LocalDateTime updateTime; + + // 是否被收藏 + private Integer isCollect; + + //注释或备注 + private String columnComment; + + //数据长度 + private Integer length; + +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/QualityRuleEntity.java b/backend/src/main/java/com/unionbigdata/teaching/entity/QualityRuleEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..b68698fb5ea2ea6e0f2b0ec9762728d00aaeddca --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/QualityRuleEntity.java @@ -0,0 +1,23 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import java.time.LocalDateTime; + +@Data +@TableName("quality_rule") +public class QualityRuleEntity { + @TableId(type = IdType.AUTO) + @NotBlank(message = "Id不能为空!") + private Integer id; // 主键ID(Long → Integer) + private Integer taskId; // 关联任务ID(Long → Integer) + private Integer creatorId; // 创建人ID(Long → Integer) + private String ruleDesc; // 规则描述 + private String ruleLevel; // 规则级别 + private String ruleName; // 规则名称 + private LocalDateTime createTime; + private LocalDateTime updateTime; +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/RuleParamEntity.java b/backend/src/main/java/com/unionbigdata/teaching/entity/RuleParamEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..0eeedcb329511b04033f6348223698effbe9c2cf --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/RuleParamEntity.java @@ -0,0 +1,20 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.time.LocalDateTime; + +@Data +@TableName("rule_param") +public class RuleParamEntity { + @TableId(type = IdType.AUTO) + private Integer paramId; // 主键ID(Long → Integer) + private Integer ruleId; // 关联质检规则ID(Long → Integer) + private String paramName; // 数据项名(字段名):age、学年、年级 + private String paramType; // 运算符-AND/OR-高亮色:<-OR-red + private String paramValue; // 条件值:20、2,3 + private LocalDateTime createTime; + private LocalDateTime updateTime; +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/SensitiveWord.java b/backend/src/main/java/com/unionbigdata/teaching/entity/SensitiveWord.java new file mode 100644 index 0000000000000000000000000000000000000000..d67bbcb25b63a943bd0be7df8125d7a649644a69 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/SensitiveWord.java @@ -0,0 +1,27 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@TableName("sensitive_word") +@Data +public class SensitiveWord { + @TableId(value = "id",type = IdType.AUTO) + private Long id; + + //敏感词 + private String wordContent; + + //创建时间 + private LocalDateTime createTime; + + //更新时间 + private LocalDateTime updateTime; + + //是否启用 0不启用,1启用 + private Integer isEnabled; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/Task.java b/backend/src/main/java/com/unionbigdata/teaching/entity/Task.java new file mode 100644 index 0000000000000000000000000000000000000000..35f4ef0f536adde363f142658ad54e568923a27e --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/entity/Task.java @@ -0,0 +1,50 @@ +package com.unionbigdata.teaching.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.time.LocalDateTime; + +@TableName("task") +@Data +public class Task { + @TableId(value = "id",type = IdType.AUTO) + private Integer id; + + //任务名称 + private String taskName; + + //发布时间 + private LocalDateTime publishTime; + + //创建时间 + private LocalDateTime createTime; + + //更新时间 + private LocalDateTime updateTime; + + //状态 + @TableField(fill = FieldFill.INSERT)//FieldFill.INSERT表示在执行insert语句时才会有默认值“未发布” + private String status = "未发布"; + + //创建人id + private Integer creatorId; + + //处理人id + private Integer handlerId; + + //任务描述 + private String taskDescription; + + //是否开启敏感词检测 + private Integer isSensitiveDetection; + + //版本号 + private String version; + + //数据源id,新建任务后,根据数据源id可以找到对应的数据库,进而找到对应的表 + private Integer dataSourceId; + + //数据表id,新建任务后,根据数据表id可以在对应数据源中找到对应的表 + private Integer tableId; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/CollectInfoMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/CollectInfoMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..67eb93bacc04db371a53a0f547842efa6ba45d7b --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/CollectInfoMapper.java @@ -0,0 +1,12 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.unionbigdata.teaching.entity.CollectInfoEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 采集信息Mapper接口 + */ +@Mapper +public interface CollectInfoMapper extends BaseMapper { +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/DataSourceMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/DataSourceMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..03758d4c5eac4a8dfb43d24f13f2c210c8ef7a06 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/DataSourceMapper.java @@ -0,0 +1,7 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.unionbigdata.teaching.entity.DataSource; + +public interface DataSourceMapper extends BaseMapper { +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/DataTableConfigMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/DataTableConfigMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..52b26012e29c1f2cd0aa10d0e9daa4664e5fcc39 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/DataTableConfigMapper.java @@ -0,0 +1,10 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.unionbigdata.teaching.entity.DataTableConfigEntity; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DataTableConfigMapper extends BaseMapper { + // 继承BaseMapper,自带增删改查;如需自定义SQL,可在此添加 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/FillDataColumnMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/FillDataColumnMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..2e4417fb35a6e0a0b1aa2d1d27193fa399d0c0b8 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/FillDataColumnMapper.java @@ -0,0 +1,92 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.unionbigdata.teaching.DTO.SelectColumnDTO; +import com.unionbigdata.teaching.entity.FillDataColumnEntity; +import org.apache.ibatis.annotations.*; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface FillDataColumnMapper extends BaseMapper { + // 根据fill_data_id查询对应的所有字段 + List selectByFillDataId(Long fillDataId); + + /** + * 批量插入任务与列的关联关系 + * 使用MyBatis的@Insert注解执行批量插入操作 + * 通过动态SQL构建插入语句,支持一次插入多条记录 + * + * @param taskId 任务ID,用于标识具体的任务 + * @param columnNames 列名列表,包含与任务关联的所有列ID + */ +// 批量插入fill_data_column表(适配List) + @Insert("") + int batchInsertTaskColumnRelation( + @Param("taskId") Integer taskId, + @Param("columnNames") List columnNames, + @Param("tableId") Integer tableId + ); + + /** + * 批量更新:仅当isCollect值与数据库不一致时更新(纯UPDATE,不新增) + */ + @Update("") + int batchUpdateTaskColumnRelation( + @Param("taskId") Integer taskId, + @Param("columnNames") List columnNames + ); + + /** + * 根据taskId删除fill_data_column表中对应的所有记录 + * @param taskId 任务ID(不可为null,否则会触发空值防护,不执行删除) + * @return 被删除的记录行数(便于业务层判断删除效果) + */ + @Delete("") + int deleteBatchByTaskId(@Param("taskId") Integer taskId); + + + + // 通过task_id查询column_name和is_collect + @Select("SELECT column_name, is_collect FROM fill_data_column WHERE task_id = #{taskId}") + List> getColumnCollectByTaskId(@Param("taskId") Integer taskId); + + + //根据taskId删除fill_data_columns表中的关系信息 + @Delete("DELETE FROM fill_data_column WHERE task_id = #{taskId}") + int deleteByTaskId(@Param("taskId") Integer taskId); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/QualityRuleMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/QualityRuleMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..9ee17fab1992e248b6cc60dc3b71d8022ef01f94 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/QualityRuleMapper.java @@ -0,0 +1,23 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; // ✅ 必须加这个继承 +import com.unionbigdata.teaching.entity.QualityRuleEntity; +import com.unionbigdata.teaching.vo.QualityResultVO; +import org.apache.ibatis.annotations.Param; +import java.time.LocalDateTime; +import java.util.List; + +// ✅ 关键:继承 BaseMapper ,泛型必须是你的实体类 +public interface QualityRuleMapper extends BaseMapper { + + // 查询全部质检结果 + List selectAllQualityResults(); + + // 组合查询质检结果 + // QualityRuleMapper.java + List selectQualityResultsByCombination( + @Param("taskName") String taskName, // 替换为taskName + @Param("startTime") LocalDateTime startTime, + @Param("endTime") LocalDateTime endTime + ); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/RuleParamMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/RuleParamMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..d7cbe897c9acf0bc8efa60a3facc40decbc254d6 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/RuleParamMapper.java @@ -0,0 +1,24 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.apache.ibatis.annotations.Mapper; +import com.unionbigdata.teaching.entity.RuleParamEntity; +import java.util.List; + +@Mapper +public interface RuleParamMapper extends BaseMapper { + // 根据规则ID查参数 + default List getParamByRuleId(Integer ruleId){ + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(RuleParamEntity::getRuleId, ruleId); + return this.selectList(wrapper); + } + + // 根据规则ID删参数 + default void deleteByRuleId(Integer ruleId){ + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(RuleParamEntity::getRuleId, ruleId); + this.delete(wrapper); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/SensitiveWordMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/SensitiveWordMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..ddbebf471e71a67a38d51beab48dd8214b19fa9e --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/SensitiveWordMapper.java @@ -0,0 +1,54 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.unionbigdata.teaching.entity.SensitiveWord; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface SensitiveWordMapper extends BaseMapper { +/** + * 查询敏感词列表的方法 + * @return 返回敏感词列表,包含所有敏感词信息的集合 + */ + List findSensitiveWordList(); + +/** + * 根据ID删除记录 + * @param id 要删除的记录ID + * @return 删除操作的结果,通常返回受影响的行数或成功/失败标志 + */ + Integer deleteById(Integer id); + +/** + * 保存敏感词信息的方法声明 + * + * @param sensitiveWord 包含敏感词信息的对象 + * @return 如果保存成功返回true,否则返回false + */ + boolean save(SensitiveWord sensitiveWord); // 声明一个保存敏感词的方法,返回布尔值表示操作是否成功 + +/** + * 批量更新敏感词信息 + * @param sensitiveWordList 敏感词列表,包含需要更新的敏感词信息 + * @return 更新操作影响的记录数,用于判断更新是否成功 + */ + int updateBatch(List sensitiveWordList); + +/** + * 根据敏感词ID查询敏感词信息 + * @param id 敏感词的唯一标识ID + * @return 返回对应的敏感词对象,如果未找到则返回null + */ + SensitiveWord findSensitiveWordById(Integer id); + +/** + * 查询所有启用的词语内容 + * + * @return 返回启用的词语内容列表,每个元素是一个字符串 + */ + @Select("select word_content from sensitive_word where is_enabled = 1") + List selectEnabledWordContents(); +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/TableOperateMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/TableOperateMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..6483cb0a16dd89aed72a1f4e3b155b65a54a98f2 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/TableOperateMapper.java @@ -0,0 +1,42 @@ +package com.unionbigdata.teaching.mapper; + +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Update; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Param; +import java.util.List; +import java.util.Map; + +public interface TableOperateMapper { + // 原有方法:建表+列表名 + @Update("${createTableSql}") + void executeCreateTableSql(@Param("createTableSql") String createTableSql); + + //返回item是 (table_name,id)的list + @Select("SELECT table_name, id FROM data_table_config WHERE data_source_id = #{id}") + List> listAllTableNames(@Param("id") Long id); + + // ========== 新增:查询表结构(字段信息) ========== + @Select("SELECT COLUMN_NAME AS columnName, DATA_TYPE AS columnType, CHARACTER_MAXIMUM_LENGTH AS columnLength, COLUMN_COMMENT AS columnComment " + + "FROM INFORMATION_SCHEMA.COLUMNS " + + "WHERE TABLE_SCHEMA = (SELECT DATABASE()) AND TABLE_NAME = #{tableName}") + List> getTableColumns(@Param("tableName") String tableName); + + // ========== 新增:查询表数据(前10条,可自定义数量) ========== + @Select("SELECT * FROM ${tableName} LIMIT 10") + List> getTableData(@Param("tableName") String tableName); + + //根据tableId获取tableName + @Select("SELECT table_name FROM data_table_config WHERE id = #{tableId}") + String getTableNameById(@Param("tableId") Integer tableId); + + + //根据taskId删除该任务对应的表 + @Update("DROP TABLE IF EXISTS ${tableName}") + void dropTableByTableName(@Param("tableName") String tableName); + + + //根据taskId删除该任务对应的表 + @Delete("delete from data_table_config where task_id = #{taskId}") + void deleteTableByTaskId(@Param("taskId") Integer taskId); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/TaskMapper.java b/backend/src/main/java/com/unionbigdata/teaching/mapper/TaskMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..6cd9c685114fce5687bd1c1ec4cbc0a4b9280430 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/TaskMapper.java @@ -0,0 +1,30 @@ +package com.unionbigdata.teaching.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.unionbigdata.teaching.entity.Task; +import org.apache.ibatis.annotations.*; + +import java.net.Inet4Address; + +public interface TaskMapper extends BaseMapper { + // 入参为Task实体类,和BaseMapper的泛型一致,更规范 + @Insert("insert into task (task_name, version, task_description, is_sensitive_detection, data_source_id, create_time, table_id) " + + "values (#{taskName}, #{version}, #{taskDescription}, #{isSensitiveDetection}, #{dataSourceId}, NOW(), #{tableId}})") + // 回写自增id到Task对象的id字段 + @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") + int insertTask(Task task); + + @Update("update task " + + "set table_id = #{tableId} " + + "where id = #{taskId}") + int updateTableIdByTaskId(Integer taskId, Integer tableId); + + + /** + * 根据taskId查询对应的表id + * @param taskId 任务ID(对应task表的id字段,bigint类型) + * @return 任务关联的表id,无数据时返回null + */ + @Select("SELECT table_id FROM task WHERE id = #{taskId}") + Integer getTableIdByTaskId(@Param("taskId") Integer taskId); +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/FillDataColumnMapper.xml b/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/FillDataColumnMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..d37c2fb009b9b6244463f5c9d9e71396784b3d79 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/FillDataColumnMapper.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/SensitiveWMapper.xml b/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/SensitiveWMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..bd031ce86020094f23b79ee4f9926900e7d78659 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/SensitiveWMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + delete from sensitive_word + where id = #{id} + + + + + + + insert into sensitive_word (is_enabled, word_content) + values (#{isEnabled}, #{wordContent}) + + + + + update sensitive_word + + word_content = case id + + when #{item.id} then #{item.wordContent} + + end, + is_enabled = case id + + when #{item.id} then #{item.isEnabled} + + end + + where id in + + #{item.id} + + + + \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/ICollectInfoService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/ICollectInfoService.java new file mode 100644 index 0000000000000000000000000000000000000000..008f7844e1134c39bcaee51551a34edab97485bc --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/ICollectInfoService.java @@ -0,0 +1,18 @@ +package com.unionbigdata.teaching.sevice; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.unionbigdata.teaching.DTO.CollectInfoColumnDTO; +import com.unionbigdata.teaching.DTO.CollectInfoSubmitDTO; +import com.unionbigdata.teaching.entity.CollectInfoEntity; +import java.util.List; +import java.util.Map; + +/** + * 采集信息Service接口 + */ +public interface ICollectInfoService extends IService { + // 根据task_id获取需要采集的列名 + List getTableColumnsByTaskId(Integer taskId); + // 批量上报采集数据 + Integer submitCollectInfo(CollectInfoSubmitDTO submitDTO); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/IDataSourceService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/IDataSourceService.java new file mode 100644 index 0000000000000000000000000000000000000000..01e0eb8da983406c684ab61d27816ca9b4781721 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/IDataSourceService.java @@ -0,0 +1,7 @@ +package com.unionbigdata.teaching.sevice; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.unionbigdata.teaching.entity.DataSource; + +public interface IDataSourceService extends IService { +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/IDataTableConfigService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/IDataTableConfigService.java new file mode 100644 index 0000000000000000000000000000000000000000..8900bf41350e8198babb36c2bb626ad88e0343ed --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/IDataTableConfigService.java @@ -0,0 +1,12 @@ +package com.unionbigdata.teaching.sevice; + +import com.unionbigdata.teaching.vo.DataTableConfigVO; + +import java.util.List; + +public interface IDataTableConfigService { + // 创建数据表配置(可视化建表) + Integer createTableConfig(DataTableConfigVO configVO); + // 根据用户ID查询其创建的表配置 + List listByFillerId(Long fillerId); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/IFillDataService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/IFillDataService.java new file mode 100644 index 0000000000000000000000000000000000000000..9c830436d67c0ce2f98221fa19d923ddafbe7ce4 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/IFillDataService.java @@ -0,0 +1,13 @@ +package com.unionbigdata.teaching.sevice; + +import com.unionbigdata.teaching.vo.FillDataColumnVO; + +import java.util.List; + +public interface IFillDataService { + + // 批量保存填报数据列 + void saveFillDataColumns(List columnVOs); + // 根据填报记录ID查询对应的字段数据 + List listColumnsByFillDataId(Long fillDataId); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/IQualityCheckService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/IQualityCheckService.java new file mode 100644 index 0000000000000000000000000000000000000000..3668ed2c43f02f34cd465fd791e37ee1a990cd21 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/IQualityCheckService.java @@ -0,0 +1,9 @@ +package com.unionbigdata.teaching.sevice; + +import com.unionbigdata.teaching.DTO.CheckResultDTO; +import java.util.List; + +public interface IQualityCheckService { + List executeQualityCheck(String taskName); + List executeQualityCheckByTaskId(Integer taskId); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/IQualityRuleService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/IQualityRuleService.java new file mode 100644 index 0000000000000000000000000000000000000000..1a1f60aac3c9d7dd57c275c46c84a1b07e9af812 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/IQualityRuleService.java @@ -0,0 +1,32 @@ +package com.unionbigdata.teaching.sevice; + +import com.baomidou.mybatisplus.extension.service.IService; + +import com.unionbigdata.teaching.entity.QualityRuleEntity; +import com.unionbigdata.teaching.vo.QualityResultVO; +import com.unionbigdata.teaching.vo.QualityRuleVO; + +import java.time.LocalDateTime; +import java.util.List; + +public interface IQualityRuleService extends IService { + // ✅ 只传 QualityRuleVO 一个参数,和你Controller调用的一致 + // 原来的写法:boolean saveRule(Integer taskId, Integer creatorId, List qualityRules); +// 修改后的写法:直接传封装好的DTO + boolean saveRule(Integer taskId, Integer creatorId, List qualityRules); + + // 内部方法 不变 + boolean updateRule(QualityRuleVO qualityRuleVO); + boolean removeSingleParam(Integer paramId); + boolean removeRule(Integer ruleId); + List listAllQualityResults(); + + // 2. 按时间范围筛选质检结果 + // IQualityRuleService.java + // 接口入参改为 String taskName + List listQualityResultsByCombination( + String taskName, + String startTimeStr, + String endTimeStr + ); +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/ISensitiveWordService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/ISensitiveWordService.java new file mode 100644 index 0000000000000000000000000000000000000000..2457f0b10c3fd038549c5ce246fe05643dedbd89 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/ISensitiveWordService.java @@ -0,0 +1,32 @@ +package com.unionbigdata.teaching.sevice; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.unionbigdata.teaching.DTO.DynamicTableRequestDTO; +import com.unionbigdata.teaching.entity.SensitiveWord; +import com.unionbigdata.teaching.vo.SensitiveWordVO; +import org.springframework.stereotype.Service; + +import java.util.List; + +public interface ISensitiveWordService extends IService { + + List findAllSensitiveWord(); + +/** + * 删除敏感词的方法 + * @param id 需要删除的敏感词的id + * @return 返回操作结果,Integer类型,通常用于表示删除的记录数或操作状态 + */ + Integer deleteSensitiveWord(Integer id); + + + boolean addSensitiveWord(SensitiveWord sensitiveWord); + + Integer updateSensitiveWordBatch(List add, List update, List delete); + + Object checkAndReplaceSensitiveWord(DynamicTableRequestDTO dynamicDTO); + + String cs(String str); + +// int updateSensitiveWordBatch(List sensitiveWordList); +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/ITableOperateService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/ITableOperateService.java new file mode 100644 index 0000000000000000000000000000000000000000..e220fe493f168d1ddf0a406a7327da33a904afed --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/ITableOperateService.java @@ -0,0 +1,19 @@ +package com.unionbigdata.teaching.sevice; + +import com.unionbigdata.teaching.vo.TableCreateVO; +import com.unionbigdata.teaching.common.Result; +import org.apache.ibatis.annotations.Select; + +import java.util.List; +import java.util.Map; + +public interface ITableOperateService{ + // 原有方法:建表+列表名 + Integer createTableByVisual(TableCreateVO tableCreateVO); + Result>> listAllTableNames(Long id); + + // ========== 新增:查询表结构+数据 ========== + Result>> getTableColumns(String tableName,Integer taskId,Integer nowTableId); + Result>> getTableData(String tableName); + +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/ITaskService.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/ITaskService.java new file mode 100644 index 0000000000000000000000000000000000000000..7d70c18b6f19b108df8a200a7299ed158a0c3088 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/ITaskService.java @@ -0,0 +1,58 @@ +package com.unionbigdata.teaching.sevice; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.unionbigdata.teaching.DTO.DynamicTableRequestDTO; +import com.unionbigdata.teaching.DTO.TaskAddDTO; +import com.unionbigdata.teaching.entity.Task; +import com.unionbigdata.teaching.vo.TaskVO; + +import java.time.LocalDate; +import java.util.List; +import java.util.Map; + +public interface ITaskService extends IService { + + Map getTaskById(Integer id); + +/** + * 查询任务列表的方法 + * @param timeType 时间类型,用于指定查询的时间范围类型 + * @param startDate 开始日期,查询范围的起始时间 + * @param endDate 结束日期,查询范围的结束时间 + * @param taskName 任务名称,用于筛选特定名称的任务 + * @return 返回任务列表,包含符合条件的TaskVO对象集合 + */ + List queryTaskList(String timeType, LocalDate startDate, LocalDate endDate, String taskName); + +/** + * 数据收集方法 + * 用于根据动态表格请求DTO对象收集并返回相关数据 + * + * @param dynamicDTO 动态表格请求DTO对象,包含收集数据所需的参数和条件 + * @return 返回收集到的数据,类型为Object,具体类型取决于实现 + */ + Object dataCollect(DynamicTableRequestDTO dynamicDTO); + +/** + * 创建数据表的方法 + * @param taskAddDTO 包含任务添加或更新信息的DTO对象 + * @return 返回Boolean类型结果,表示创建操作是否成功 + */ + Boolean noTableIdAndAddTask(TaskAddDTO taskAddDTO); + +/** + * 更新任务表列关系的方法 + * + * @param taskAddDTO 任务添加数据传输对象,包含任务相关的信息 + * @return 更新操作是否成功,返回Boolean类型表示操作结果 + */ + Boolean haveTableIdAndAddTask(TaskAddDTO taskAddDTO); + + Object haveTableIdAndEditTask(TaskAddDTO taskAddDTO); + + Object noTableIdAndEditTask(TaskAddDTO taskAddDTO); + + Map getTaskDetailByTaskId(Integer taskId); + + Boolean removeTaskBatchByIds(List ids); +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/CollectInfoServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/CollectInfoServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..235a07750c06b878ed9f993fdda176116342d86c --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/CollectInfoServiceImpl.java @@ -0,0 +1,156 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.unionbigdata.teaching.DTO.CollectInfoColumnDTO; +import com.unionbigdata.teaching.DTO.CollectInfoSubmitDTO; +import com.unionbigdata.teaching.entity.CollectInfoEntity; +import com.unionbigdata.teaching.mapper.CollectInfoMapper; +import com.unionbigdata.teaching.sevice.ICollectInfoService; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +@Service +public class CollectInfoServiceImpl extends ServiceImpl implements ICollectInfoService { + private static final Logger log = LoggerFactory.getLogger(CollectInfoServiceImpl.class); + + @Resource + private JdbcTemplate jdbcTemplate; + + // 根据taskId获取需要采集的列名 + @Override + public List getTableColumnsByTaskId(Integer taskId) { + List columnList = new ArrayList<>(); + if (taskId == null || taskId <= 0) { + log.warn("【获取列名】taskId为空或无效,taskId={}", taskId); + return columnList; + } + String columnSql = "SELECT column_name, column_type, column_comment, length " + + "FROM fill_data_column WHERE task_id = ? AND is_collect = 1"; + List> columns = jdbcTemplate.queryForList(columnSql, taskId); + + for (Map column : columns) { + CollectInfoColumnDTO dto = new CollectInfoColumnDTO(); + dto.setColumnName(column.get("column_name").toString()); + dto.setColumnType(column.get("column_type").toString()); + dto.setColumnComment(column.get("column_comment") == null ? "" : column.get("column_comment").toString()); + dto.setLength(column.get("length") == null ? 0 : Integer.parseInt(column.get("length").toString())); + columnList.add(dto); + } + log.info("【获取列名】taskId={}, 查询到的数据库字段名:{}", taskId, columnList.stream().map(CollectInfoColumnDTO::getColumnName).toList()); + return columnList; + } + + // 批量上报采集数据 - 【全漏洞修复版】核心方法 + @Override + @Transactional(rollbackFor = Exception.class) + public Integer submitCollectInfo(CollectInfoSubmitDTO submitDTO) { + // ============ 修复点1:参数校验,为空直接返回0,终止所有逻辑 ============ + if (submitDTO == null) { + log.error("【提交数据】入参为空,submitDTO=null"); + return 0; + } + if (submitDTO.getTableDataList() == null || submitDTO.getTableDataList().isEmpty()) { + log.warn("【提交数据】待插入数据为空,tableDataList=null/空"); + return 0; + } + Integer taskId = submitDTO.getTaskId(); + if (taskId == null || taskId <= 0) { + log.error("【提交数据】taskId为空/无效,taskId={}", taskId); + return 0; // ❗❗ 不传/传错taskId,直接返回0,不执行后续逻辑 ❗❗ + } + + // ============ 修复点2:根据taskId获取表名,获取不到直接返回0 ============ + String tableName = getTableNameByTaskId(taskId); + if (tableName == null || tableName.trim().isEmpty()) { + log.error("【提交数据】根据taskId={},未查询到对应的表名,入库失败", taskId); + return 0; // ❗❗ 无表名,直接返回0 ❗❗ + } + log.info("【提交数据】taskId={}, 匹配到目标表名:{}", taskId, tableName); + + // ============ 修复点3:获取数据库真实字段,无字段直接返回0 ============ + List dbRealColumns = getDbRealColumns(taskId); + if (dbRealColumns.isEmpty()) { + log.error("【提交数据】taskId={},未查询到对应的数据库采集字段,入库失败", taskId); + return 0; + } + + // ============ 修复点4:【核心】count从0开始计数,✅只有插入成功才+1 ✅ ============ + int successCount = 0; // 成功入库条数 + int failCount = 0; // 失败条数 + int totalCount = submitDTO.getTableDataList().size(); + + for (Map rowData : submitDTO.getTableDataList()) { + if (rowData == null || rowData.isEmpty()) { + failCount++; + continue; + } + try { + // 过滤只保留数据库存在的字段 + Map dbInsertData = new HashMap<>(); + for (String dbColumn : dbRealColumns) { + if (rowData.containsKey(dbColumn)) { + dbInsertData.put(dbColumn, rowData.get(dbColumn)); + } + } + if (dbInsertData.isEmpty()) { + failCount++; + log.warn("【提交数据】单条数据无有效入库字段,跳过:{}", rowData); + continue; + } + // 生成插入SQL + String columns = String.join("`, `", dbInsertData.keySet()); + String placeholders = String.join(",", Collections.nCopies(dbInsertData.size(), "?")); + String sql = "INSERT INTO `" + tableName + "` (`" + columns + "`) VALUES (" + placeholders + ")"; + + // ============ 执行插入并计数 ============ + jdbcTemplate.update(sql, dbInsertData.values().toArray()); + successCount++; // ✅ 只有插入成功,才+1 ✅ + log.info("【提交成功】表名:{}, 单条数据入库成功:{}", tableName, dbInsertData); + + } catch (Exception e) { + failCount++; + log.error("【提交失败】表名:{}, 单条数据入库失败,数据:{},失败原因:{}", tableName, rowData, e.getMessage()); + continue; + } + } + log.info("【提交完成】表名:{}, 总条数:{}, 成功入库:{}, 入库失败:{}", tableName, totalCount, successCount, failCount); + return successCount; // ✅ 返回【真实成功条数】✅ + } + + /** + * 根据taskId获取数据库真实表名 (task表→table_id → data_table_config表→table_name) + */ + private String getTableNameByTaskId(Integer taskId) { + try { + // 1. task表 根据id查table_id + String taskSql = "SELECT table_id FROM task WHERE id = ? LIMIT 1"; + List> taskList = jdbcTemplate.queryForList(taskSql, taskId); + if (taskList.isEmpty()) { + return null; + } + Integer tableId = Integer.parseInt(taskList.get(0).get("table_id").toString()); + + // 2. data_table_config表 根据table_id查table_name + String configSql = "SELECT table_name FROM data_table_config WHERE id = ? LIMIT 1"; + List tableNameList = jdbcTemplate.queryForList(configSql, String.class, tableId); + return tableNameList.isEmpty() ? null : tableNameList.get(0); + } catch (Exception e) { + log.error("【获取表名失败】taskId={}, 异常:{}", taskId, e.getMessage()); + return null; + } + } + + /** + * 根据taskId获取fill_data_column表中配置的采集字段名 + */ + private List getDbRealColumns(Integer taskId) { + String sql = "SELECT column_name FROM fill_data_column WHERE task_id = ? AND is_collect = 1"; + return jdbcTemplate.queryForList(sql, String.class, taskId); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/DataSourceServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/DataSourceServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..890c6d81caa25a75e8b009c187efba6d41cd8b0b --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/DataSourceServiceImpl.java @@ -0,0 +1,11 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.unionbigdata.teaching.entity.DataSource; +import com.unionbigdata.teaching.mapper.DataSourceMapper; +import com.unionbigdata.teaching.sevice.IDataSourceService; +import org.springframework.stereotype.Service; + +@Service +public class DataSourceServiceImpl extends ServiceImpl implements IDataSourceService{ +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/DataTableConfigServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/DataTableConfigServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..995e2df9e3fc8681b02c3fba1a512423086bd576 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/DataTableConfigServiceImpl.java @@ -0,0 +1,54 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.unionbigdata.teaching.entity.DataTableConfigEntity; +import com.unionbigdata.teaching.mapper.DataTableConfigMapper; +import com.unionbigdata.teaching.sevice.IDataTableConfigService; +import com.unionbigdata.teaching.vo.DataTableConfigVO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class DataTableConfigServiceImpl implements IDataTableConfigService { + @Resource + private DataTableConfigMapper tableConfigMapper; + + @Override + @Transactional + public Integer createTableConfig(DataTableConfigVO configVO) { + DataTableConfigEntity entity = new DataTableConfigEntity(); + entity.setFieldCount(configVO.getFieldCount()); + entity.setTableName(configVO.getTableName()); + entity.setTaskId(configVO.getTaskId()); + entity.setFillerId(configVO.getFillerId()); + tableConfigMapper.insert(entity); + return entity.getId(); + } + + @Override + public List listByFillerId(Long fillerId) { + List entities = tableConfigMapper.selectList( + Wrappers.lambdaQuery(DataTableConfigEntity.class) + .eq(DataTableConfigEntity::getFillerId, fillerId) + ); + return entities.stream().map(this::convertVO).collect(Collectors.toList()); + } + + private DataTableConfigVO convertVO(DataTableConfigEntity entity) { + DataTableConfigVO vo = new DataTableConfigVO(); + if (!ObjectUtils.isEmpty(entity)) { + vo.setId(entity.getId()); + vo.setFieldCount(entity.getFieldCount()); + vo.setTableName(entity.getTableName()); + vo.setTaskId(entity.getTaskId()); + vo.setFillerId(entity.getFillerId()); + vo.setCreateTime(entity.getCreateTime()); + } + return vo; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/FillDataServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/FillDataServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..96a9e98859a0e6ace3083f3bf7e5ee5edf71fcdc --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/FillDataServiceImpl.java @@ -0,0 +1,60 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.unionbigdata.teaching.entity.FillDataColumnEntity; +import com.unionbigdata.teaching.mapper.FillDataColumnMapper; +import com.unionbigdata.teaching.sevice.IFillDataService; +import com.unionbigdata.teaching.vo.FillDataColumnVO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class FillDataServiceImpl implements IFillDataService { + + @Resource + private FillDataColumnMapper fillDataColumnMapper; + + + @Override + @Transactional + public void saveFillDataColumns(List columnVOs) { + // 空值判断:避免空列表插入报错 + if (ObjectUtils.isEmpty(columnVOs)) { + return; + } + // VO转Entity + List entities = columnVOs.stream().map(vo -> { + FillDataColumnEntity entity = new FillDataColumnEntity(); + entity.setTableId(vo.getFillDataId()); + entity.setColumnName(vo.getColumnName()); + entity.setColumnType(vo.getColumnType()); + return entity; + }).collect(Collectors.toList()); + + // 修复:循环插入(兼容所有版本,大学生项目足够用) + for (FillDataColumnEntity entity : entities) { + fillDataColumnMapper.insert(entity); + } + } + + @Override + public List listColumnsByFillDataId(Long tableId) { + List entities = fillDataColumnMapper.selectByFillDataId(tableId); + return entities.stream().map(this::convertVO).collect(Collectors.toList()); + } + + private FillDataColumnVO convertVO(FillDataColumnEntity entity) { + FillDataColumnVO vo = new FillDataColumnVO(); + if (!ObjectUtils.isEmpty(entity)) { + vo.setId(entity.getId()); + vo.setFillDataId(entity.getTableId()); + vo.setColumnName(entity.getColumnName()); + vo.setColumnType(entity.getColumnType()); + } + return vo; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/QualityCheckServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/QualityCheckServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..4c68ea53b71051a079e4608384f851acec81b28f --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/QualityCheckServiceImpl.java @@ -0,0 +1,270 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.unionbigdata.teaching.entity.Task; +import com.unionbigdata.teaching.mapper.TaskMapper; +import com.unionbigdata.teaching.utils.SensitiveWordManager; +import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import com.unionbigdata.teaching.DTO.CheckResultDTO; +import com.unionbigdata.teaching.entity.QualityRuleEntity; +import com.unionbigdata.teaching.entity.RuleParamEntity; +import com.unionbigdata.teaching.mapper.QualityRuleMapper; +import com.unionbigdata.teaching.mapper.RuleParamMapper; +import com.unionbigdata.teaching.sevice.IQualityCheckService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import java.util.*; + +@Service +public class QualityCheckServiceImpl extends ServiceImpl implements IQualityCheckService { + + @Resource + private RuleParamMapper ruleParamMapper; + + @Resource + private QualityRuleMapper qualityRuleMapper; + + @Resource + private JdbcTemplate jdbcTemplate; + @Autowired + private TaskMapper taskMapper; + + @Resource + private SensitiveWordManager sensitiveWordManager; + + @Override + public List executeQualityCheck(String taskName) { + Integer taskId = getTaskIdByTaskName(taskName); + if(taskId == null || taskId <= 0){ + return new ArrayList<>(); + } + return executeQualityCheckByTaskId(taskId); + } + + private List getQualityRuleEntityListByTaskId(Integer taskId){ + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(QualityRuleEntity::getTaskId, taskId); + List qualityRuleList = qualityRuleMapper.selectList(wrapper); + return qualityRuleList; + } + + @Override + public List executeQualityCheckByTaskId(Integer taskId) { + List resultList = new ArrayList<>(); + String taskSql = "SELECT * FROM task WHERE id = ?"; + List> taskList = jdbcTemplate.queryForList(taskSql, taskId); + if (taskList == null || taskList.isEmpty()) { + return resultList; + } + Map fullRecord = taskList.get(0); + Integer dataSourceId = fullRecord.get("data_source_id") == null ? 0 : Integer.parseInt(fullRecord.get("data_source_id").toString()); + Integer tableId = fullRecord.get("table_id") == null ? 0 : Integer.parseInt(fullRecord.get("table_id").toString()); + + String configSql = "SELECT * FROM data_table_config WHERE id = ?"; + List> configList = jdbcTemplate.queryForList(configSql, tableId); + if (configList == null || configList.isEmpty()) { + return resultList; + } + Map tableConfig = configList.get(0); + String tableName = (String) tableConfig.get("table_name"); + if (tableName == null || "".equals(tableName.trim())) { + return resultList; + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(QualityRuleEntity::getTaskId, taskId); + List qualityRuleList = qualityRuleMapper.selectList(wrapper); + if (qualityRuleList == null || qualityRuleList.isEmpty()) { + return resultList; + } + + List allRuleParam = new ArrayList<>(); + for (QualityRuleEntity rule : qualityRuleList) { + List paramList = ruleParamMapper.getParamByRuleId(rule.getId()); + allRuleParam.addAll(paramList); + } + if (allRuleParam.isEmpty()) { + return resultList; + } + + Map> columnParamMap = new HashMap<>(); + for (RuleParamEntity param : allRuleParam) { + columnParamMap.computeIfAbsent(param.getParamName(), k -> new ArrayList<>()).add(param); + } + Set checkColumnSet = columnParamMap.keySet(); + + String querySql = "SELECT * FROM " + tableName; + List> businessDataList = jdbcTemplate.queryForList(querySql); + if (businessDataList == null || businessDataList.isEmpty()) { + return resultList; + } + + //判断task是否开启敏感词过滤 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Task::getId, taskId).select(Task::getIsSensitiveDetection); + Task task = taskMapper.selectOne(queryWrapper); + Integer isSensitiveDetection = task.getIsSensitiveDetection(); + + + for (Map singleData : businessDataList) { + CheckResultDTO dto = new CheckResultDTO(); + + // ======================== 第二步:先执行敏感词过滤(挪到setData之前) ======================== + if (isSensitiveDetection == 1) { // 开启敏感词过滤 + for (String columnName : checkColumnSet) { + if (!singleData.containsKey(columnName)) { + continue; + } + Object columnValue = singleData.get(columnName); + // 安全转换为String + String columnValueStr = columnValue == null ? "" : columnValue.toString(); + // 替换敏感词 + String replacedValue = sensitiveWordManager.replaceSensitiveWord(columnValueStr); + + // 若有敏感词被替换,回写过滤后的值到singleData,并标记该字段跳过质检 + if (!columnValueStr.equals(replacedValue)) { + singleData.put(columnName, replacedValue); // 覆盖原始值 + } + } + } + dto.setData(singleData); + Map highlightMap = new HashMap<>(8); + + + //质检 + for (String columnName : checkColumnSet) { + if (!singleData.containsKey(columnName)) { + continue; + } + List paramList = columnParamMap.get(columnName); + Object columnValue = singleData.get(columnName); + String matchColor = null; + + for (RuleParamEntity param : paramList) { + String paramType = param.getParamType(); + String paramValue = param.getParamValue(); + String operator = parseOperator(paramType); + String configColor = parseHighlightColor(paramType); + + if (judgeCondition(columnValue, operator, paramValue)) { + matchColor = configColor; + break; + } + } + + if (matchColor != null) { + highlightMap.put(columnName, matchColor); + } + } + dto.setHighlightMap(highlightMap); + resultList.add(dto); + } + return resultList; + } + + private String parseOperator(String paramType) { + if (paramType == null || paramType.trim().length() == 0) { + return ""; + } + String type = paramType.trim().toLowerCase(); + if (type.startsWith("isnotnull")) { + return "isnotnull"; + } else if (type.startsWith("isnull")) { + return "isNull"; + } else if (type.startsWith("between")) { + return "BETWEEN"; + } else if (type.startsWith("<=") || type.startsWith("<-=")) { + return "<="; + } else if (type.startsWith(">=") || type.startsWith(">-=")) { + return ">="; + } else if (type.startsWith("!=")) { + return "!="; + } else if (type.startsWith(">")) { + return ">"; + } else if (type.startsWith("<")) { + return "<"; + } else if (type.startsWith("=")) { + return "="; + } else if (type.startsWith("like")) { + return "LIKE"; + } else if (type.startsWith("not_like")) { + return "NOT_LIKE"; + } + return ""; + } + + private String parseHighlightColor(String paramType) { + if (paramType == null || paramType.trim().length() == 0) { + return null; + } + String[] typeSplit = paramType.split("-"); + for (int i = typeSplit.length - 1; i >= 0; i--) { + String color = typeSplit[i].trim(); + if (!color.isEmpty() && !"and".equalsIgnoreCase(color) && !"or".equalsIgnoreCase(color)) { + return color; + } + } + return null; + } + + private Integer getTaskIdByTaskName(String taskName) { + String sql = "SELECT id FROM task WHERE task_name = ?"; + List idList = jdbcTemplate.queryForList(sql, Integer.class, taskName); + return idList == null || idList.isEmpty() ? null : idList.get(0); + } + + private boolean judgeCondition(Object columnValue, String operator, String paramValue) { + boolean isColumnNull = false; + String columnValStr = ""; + if (columnValue == null) { + isColumnNull = true; + } else { + columnValStr = columnValue.toString().trim(); + isColumnNull = columnValStr.isEmpty(); + } + + if ("isnotnull".equals(operator)) { + return !isColumnNull; + } + if ("isNull".equals(operator)) { + return isColumnNull; + } + if (isColumnNull) { + return false; + } + + if ("BETWEEN".equals(operator)) { + if (paramValue == null || !paramValue.contains(",")) return false; + String[] range = paramValue.trim().split(","); + if (range.length != 2) return false; + Double min = Double.parseDouble(range[0].trim()); + Double max = Double.parseDouble(range[1].trim()); + Double val = Double.parseDouble(columnValStr); + return val > min && val <= max; + } + + try { + Double val = Double.parseDouble(columnValStr); + Double ruleVal = Double.parseDouble(paramValue.trim()); + switch (operator) { + case "=": return val.equals(ruleVal); + case "!=": return !val.equals(ruleVal); + case ">": return val > ruleVal; + case "<": return val < ruleVal; + case ">=": return val >= ruleVal; + case "<=": return val <= ruleVal; + default: break; + } + } catch (Exception e) { } + + if ("LIKE".equals(operator)) { + return columnValStr.contains(paramValue.trim()); + } + if ("NOT_LIKE".equals(operator)) { + return !columnValStr.contains(paramValue.trim()); + } + return false; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/QualityRuleServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/QualityRuleServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..a0a643983e7c0150e34746f890d7cd47a30a917e --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/QualityRuleServiceImpl.java @@ -0,0 +1,171 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.unionbigdata.teaching.vo.QualityResultVO; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import com.unionbigdata.teaching.entity.QualityRuleEntity; +import com.unionbigdata.teaching.entity.RuleParamEntity; +import com.unionbigdata.teaching.mapper.QualityRuleMapper; +import com.unionbigdata.teaching.mapper.RuleParamMapper; +import com.unionbigdata.teaching.sevice.IQualityRuleService; +import com.unionbigdata.teaching.vo.QualityRuleVO; +import com.unionbigdata.teaching.vo.RuleParamVO; + + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class QualityRuleServiceImpl extends ServiceImpl implements IQualityRuleService { + + @Autowired + private RuleParamMapper ruleParamMapper; + + @Autowired + private QualityRuleMapper qualityRuleMapper; + + // ✅ 核心适配:从HttpServletRequest中自动获取Controller传入的 taskId 和 creatorId + // 无需修改Controller、无需改VO、无需传参,完美兼容你的所有代码 + private Integer getRequestParam(String paramName) { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes == null) return null; + HttpServletRequest request = attributes.getRequest(); + String paramValue = request.getParameter(paramName); + return paramValue == null || paramValue.trim().isEmpty() ? null : Integer.parseInt(paramValue); + } + + // ✅ 只重写:saveRule(QualityRuleVO qualityRuleVO) 单参数方法,和接口一致 + @Override + @Transactional(rollbackFor = Exception.class) + public boolean saveRule(Integer taskId, Integer creatorId, List qualityRules) { + // 自动获取前端传入的 taskId 和 creatorId (从Controller的@RequestParam中取) + for (QualityRuleVO ruleVO : qualityRules){ + if (ruleVO.getId() == null) { + // 新增规则 + QualityRuleEntity rule = new QualityRuleEntity(); + BeanUtils.copyProperties(ruleVO, rule); + // ✅ 赋值到实体类,存入数据库,解决VO无字段的问题 + rule.setTaskId(taskId); + rule.setCreatorId(creatorId); + + //新增rule,将id设为null,让mybatis-plus判定为新增,否则是update + rule.setId(null); + this.save(rule); + Integer ruleId = rule.getId(); + List paramList = ruleVO.getParamList().stream().map(vo -> { + RuleParamEntity param = new RuleParamEntity(); + BeanUtils.copyProperties(vo, param); + param.setRuleId(ruleId); + return param; + }).collect(Collectors.toList()); + paramList.forEach(param -> ruleParamMapper.insert(param)); + } else { + // 编辑规则:只更新内容,taskId和creatorId不变 + updateRule(ruleVO); + } + } + + return true; + } + + // ✅ 内部编辑方法 不变 + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateRule(QualityRuleVO qualityRuleVO) { + QualityRuleEntity rule = new QualityRuleEntity(); + BeanUtils.copyProperties(qualityRuleVO, rule); + this.updateById(rule); + Integer ruleId = rule.getId(); + + ruleParamMapper.deleteByRuleId(ruleId); + List paramList = qualityRuleVO.getParamList().stream().map(vo -> { + RuleParamEntity param = new RuleParamEntity(); + BeanUtils.copyProperties(vo, param); + param.setRuleId(ruleId); + return param; + }).collect(Collectors.toList()); + paramList.forEach(param -> ruleParamMapper.insert(param)); + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean removeSingleParam(Integer paramId) { + return ruleParamMapper.deleteById(paramId) > 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean removeRule(Integer ruleId) { + ruleParamMapper.deleteByRuleId(ruleId); + return this.removeById(ruleId); + } + + + + @Override + public List listAllQualityResults() { + log.info("查询所有质检结果"); + // 新代码:用组合查询方法替代,不传参数即查询所有结果 + return baseMapper.selectQualityResultsByCombination(null, null, null); + } + /** + * 按时间范围筛选质检结果 + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + + + // QualityRuleServiceImpl.java + @Override + public List listQualityResultsByCombination( + String taskName, + String startTimeStr, + String endTimeStr + ) { + log.info("组合筛选:taskName={}, startTime={}, endTime={}", taskName, startTimeStr, endTimeStr); + + LocalDateTime startTime = null; + LocalDateTime endTime = null; + LocalDateTime now = LocalDateTime.now(); + + // 1. 处理开始时间(仅传startTime时,endTime默认为当前时间) + if (startTimeStr != null && !startTimeStr.trim().isEmpty()) { + startTime = LocalDateTime.parse(startTimeStr + "T00:00:00"); + if (endTimeStr == null || endTimeStr.trim().isEmpty()) { + endTime = now; + } + } + + // 2. 处理结束时间(仅传endTime时,startTime默认为系统最早时间) + if (endTimeStr != null && !endTimeStr.trim().isEmpty()) { + endTime = LocalDateTime.parse(endTimeStr + "T23:59:59"); + if (startTimeStr == null || startTimeStr.trim().isEmpty()) { + startTime = LocalDateTime.of(2000, 1, 1, 0, 0, 0); + } + } + + // 3. 时间范围合法性校验 + if (startTime != null && endTime != null) { + if (endTime.isBefore(startTime)) { + throw new IllegalArgumentException("结束时间不能早于开始时间"); + } + } + + // 4. 调用Mapper查询 + return baseMapper.selectQualityResultsByCombination(taskName, startTime, endTime); + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/SensitiveWordServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/SensitiveWordServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..f7ec997be20113cb5c2f431894bd464b0fa9612d --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/SensitiveWordServiceImpl.java @@ -0,0 +1,222 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.unionbigdata.teaching.DTO.DynamicTableRequestDTO; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.entity.SensitiveWord; +import com.unionbigdata.teaching.mapper.SensitiveWordMapper; +import com.unionbigdata.teaching.sevice.ISensitiveWordService; +import com.unionbigdata.teaching.utils.SensitiveWordManager; +import com.unionbigdata.teaching.vo.SensitiveWordVO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; +import java.util.Map; + +@Service +public class SensitiveWordServiceImpl extends ServiceImpl implements ISensitiveWordService{ + + @Resource + private SensitiveWordMapper sensitiveWordMapper; + + @Resource + private SensitiveWordManager sensitiveWordManager; + +/** + * 查找所有敏感词信息 + * @return 返回敏感词视图对象列表(SensitiveWordVO) + */ + @Override + public List findAllSensitiveWord() { + // 从数据库中获取所有敏感词数据 + List sensitiveWordList = sensitiveWordMapper.findSensitiveWordList(); + // 将实体对象列表转换为视图对象列表并返回 + return sensitiveWordList.stream().map(this::convertSensitiveWordVO).toList(); + } + + private SensitiveWordVO convertSensitiveWordVO(SensitiveWord sensitiveWord) { + SensitiveWordVO sensitiveWordVO = new SensitiveWordVO(); + if (!ObjectUtils.isEmpty(sensitiveWord)) { + sensitiveWordVO.setId(sensitiveWord.getId()); + sensitiveWordVO.setWordContent(sensitiveWord.getWordContent()); + sensitiveWordVO.setIsEnabled(sensitiveWord.getIsEnabled()); + } + return sensitiveWordVO; + } + +/** + * 删除敏感词方法 + * @param id 敏感词ID + * @return 返回删除的记录数,通常为1表示成功删除,0表示未找到对应记录 + */ + @Override + public Integer deleteSensitiveWord(Integer id) { + // 调用敏感词数据访问层的删除方法,根据ID删除敏感词 + return sensitiveWordMapper.deleteById(id); + } + + +/** + * 添加敏感词方法 + * @param sensitiveWord 敏感词对象,包含需要添加的敏感词信息 + * @return 返回操作结果,true表示添加成功,false表示添加失败 + */ + @Override + public boolean addSensitiveWord(SensitiveWord sensitiveWord) { + // 调用敏感词映射器的save方法,保存敏感词信息并返回操作结果 + return sensitiveWordMapper.save(sensitiveWord); + } + +/** + * 批量更新敏感词信息的方法 + * 包括新增、修改和删除三种操作 + * + * @param addSensitiveWordList 需要新增的敏感词列表 + * @param updateSensitiveWordList 需要修改的敏感词列表 + * @param deleteSensitiveWordList 需要删除的敏感词列表 + * @return 返回操作结果,此处固定返回0 + */ + @Override + public Integer updateSensitiveWordBatch(List addSensitiveWordList, List updateSensitiveWordList, List deleteSensitiveWordList) { + // 遍历新增敏感词列表,逐个保存 + for (SensitiveWord sensitiveWord : addSensitiveWordList) { + sensitiveWordMapper.save(sensitiveWord); + } + // 遍历更新敏感词列表,逐个更新 + for (SensitiveWord sensitiveWord : updateSensitiveWordList) { + sensitiveWordMapper.updateById(sensitiveWord); + } + // 遍历删除敏感词列表,逐个删除 + for (Integer id : deleteSensitiveWordList) { + sensitiveWordMapper.deleteById(id); + } + return 0; + } + + // 批量修改的实现 +// @Override +// public int updateSensitiveWordBatch(List sensitiveWordList) { +// for( SensitiveWord sensitiveWord : sensitiveWordList){ +// Long id = sensitiveWord.getId(); +// } +// // 调用Mapper的批量更新方法 +// return sensitiveWordMapper.updateBatch(sensitiveWordList); +// } + +/** + * 检查并替换动态表格数据中的敏感词 + * 该方法会遍历表格中的每一行数据,对指定字段进行敏感词检测和替换 + * + * @param dynamicDTO 包含任务ID、字段名和表格数据的动态请求DTO + * @return 返回值为null,因为修改是直接作用于传入的dynamicDTO对象 + */ + @Override + public Object checkAndReplaceSensitiveWord(DynamicTableRequestDTO dynamicDTO) { + // 获取任务ID + Integer id = dynamicDTO.getTaskId(); + // 获取需要处理的字段名列表 + List filedName = dynamicDTO.getFiledName(); + // 获取表格所有行数据 + List> tableRows = dynamicDTO.getTableRows(); + + int rowNum = 1; // 新增:用于记录当前处理的行号 + // 2. 遍历每一行数据,进行敏感词检测+替换 +// for (Map row : tableRows) { +// // 遍历该行的每个字段 +// // 新增:打印当前处理的行号 + 处理前的原始数据(方便对比) +// System.out.println("========== 开始处理第 " + rowNum + " 行数据 =========="); +// System.out.println("处理前的原始数据:" + row); +// // 对每个字段进行处理 +// for (String name : filedName) { +// // 获取字段值(注意类型转换,前端传的是String) +// String fieldValue = (row.get(name) == null) ? "" : row.get(name).toString(); +// // 敏感词替换 +// String replacedValue = sensitiveWordManager.replaceSensitiveWord(fieldValue); +// // 替换后写回Map +// row.put(name, replacedValue); +// } +// // 新增:打印处理后的行数据(对比原始数据,确认敏感词是否替换成功) +// System.out.println("处理后的行数据:" + row); +// System.out.println("========== 第 " + rowNum + " 行数据处理完成 ==========\n"); +// rowNum++; +// } + for (Map row : tableRows) { + // 打印行号和原始数据 + System.out.println("========== 开始处理第 " + rowNum + " 行数据 =========="); + System.out.println("处理前的原始数据:" + row); + + // 遍历该行的每个字段 + for (String name : filedName) { + Object originalValue = row.get(name); // 先获取原始值(不直接转String) + String fieldValue = ""; + String valueType = ""; // 记录字段值的类型 + + // ========== 核心:判断字段值的具体类型 ========== + if (originalValue == null) { + valueType = "null"; + fieldValue = ""; // null 转空字符串 + } else if (originalValue instanceof String) { + valueType = "String(字符串)"; + fieldValue = (String) originalValue; // 直接强转,避免多余的 toString() + } else if (originalValue instanceof Integer) { + valueType = "Integer(整数)"; + fieldValue = originalValue.toString(); // 数字转字符串(敏感词替换需要字符串) + } else if (originalValue instanceof Double) { + valueType = "Double(浮点数)"; + fieldValue = originalValue.toString(); + } else if (originalValue instanceof Boolean) { + valueType = "Boolean(布尔值)"; + fieldValue = originalValue.toString(); + } else { + // 其他类型(如Long、Float、日期等),统一转String + valueType = originalValue.getClass().getSimpleName() + "(其他类型)"; + fieldValue = originalValue.toString(); + } + + // 打印字段名、类型、原始值(方便调试) + System.out.println("字段名:" + name + " | 类型:" + valueType + " | 原始值:" + originalValue); + + // 敏感词替换(仅针对字符串有效,非字符串类型替换后还是原格式) + String replacedValue = sensitiveWordManager.replaceSensitiveWord(fieldValue); + + // ========== 可选:将替换后的值转回原类型(如果需要) ========== + Object finalValue = replacedValue; + if (originalValue instanceof Integer) { + try { + finalValue = Integer.parseInt(replacedValue); // 字符串转回整数 + } catch (NumberFormatException e) { + finalValue = originalValue; // 转换失败则保留原值 + System.out.println("字段 " + name + " 替换后无法转回Integer,保留原值:" + originalValue); + } + } else if (originalValue instanceof Double) { + try { + finalValue = Double.parseDouble(replacedValue); + } catch (NumberFormatException e) { + finalValue = originalValue; + System.out.println("字段 " + name + " 替换后无法转回Double,保留原值:" + originalValue); + } + } else if (originalValue instanceof Boolean) { + finalValue = Boolean.parseBoolean(replacedValue); + } + + // 替换后写回Map(保留原类型,更精准) + row.put(name, finalValue); + } + + // 打印处理后的行数据 + System.out.println("处理后的行数据:" + row); + System.out.println("========== 第 " + rowNum + " 行数据处理完成 ==========\n"); + rowNum++; + } + return null; + } + + @Override + public String cs(String str) { + return sensitiveWordManager.replaceSensitiveWord(str); + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/TableOperateServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/TableOperateServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..04a06915f630340d98db59474c7b0cdf1b32c93c --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/TableOperateServiceImpl.java @@ -0,0 +1,296 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.unionbigdata.teaching.entity.DataTableConfigEntity; +import com.unionbigdata.teaching.entity.Task; +import com.unionbigdata.teaching.mapper.DataTableConfigMapper; +import com.unionbigdata.teaching.mapper.FillDataColumnMapper; +import com.unionbigdata.teaching.mapper.TableOperateMapper; +import com.unionbigdata.teaching.mapper.TaskMapper; +import com.unionbigdata.teaching.sevice.ITableOperateService; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.vo.TableCreateVO; +import com.unionbigdata.teaching.vo.TableFieldVO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class TableOperateServiceImpl implements ITableOperateService { + + private final TableOperateMapper tableOperateMapper; + private final DataTableConfigMapper dataTableConfigMapper; + + @Resource + private FillDataColumnMapper fillDataColumnMapper; + + @Resource + private TaskMapper taskMapper; + + public TableOperateServiceImpl(TableOperateMapper tableOperateMapper, DataTableConfigMapper dataTableConfigMapper) { + this.tableOperateMapper = tableOperateMapper; + this.dataTableConfigMapper = dataTableConfigMapper; + } + + // 原有方法:建表+列表名 + @Override + @Transactional(rollbackFor = Exception.class) + public Integer createTableByVisual(TableCreateVO tableCreateVO) { + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(DataTableConfigEntity::getTableName, tableCreateVO.getTableName()); + if (dataTableConfigMapper.selectCount(wrapper) > 0) { + System.err.println("表名[" + tableCreateVO.getTableName() + "]已存在,请更换表名"); + return null; + } + + //获取创建表的mysql语句 + String createTableSql = buildCreateTableSql(tableCreateVO); + System.err.println(createTableSql); + //创建表 + tableOperateMapper.executeCreateTableSql(createTableSql); + + + //将表结构信息保存到数据库 + DataTableConfigEntity configEntity = new DataTableConfigEntity(); + configEntity.setTableName(tableCreateVO.getTableName()); + configEntity.setFieldCount(tableCreateVO.getFields().size()); + configEntity.setTaskId(tableCreateVO.getTaskId()); + configEntity.setFillerId(tableCreateVO.getFillerId()); + configEntity.setCreateTime(LocalDateTime.now()); + configEntity.setUpdateTime(LocalDateTime.now()); + configEntity.setDataSourceId(tableCreateVO.getDataSourceId()); + dataTableConfigMapper.insert(configEntity); + System.err.println("表[" + tableCreateVO.getTableName() + "]创建成功"); + return configEntity.getId(); + } + + @Override + public Result>> listAllTableNames(Long id) { + List> tableNameAndId = tableOperateMapper.listAllTableNames(id); + // 定义新的列表存储转换后的数据(也可以直接在原列表上修改) + List> convertedList = new ArrayList<>(); + +// 遍历每个Map,进行类型转换 + for (Map item : tableNameAndId) { + // 1. 处理table_name:转String(空值时设为"",避免null) + Object tableNameObj = item.get("table_name"); + String tableName = tableNameObj != null ? tableNameObj.toString() : ""; + + // 2. 处理id:转Integer(兼容Long/Number类型,空值时设为0或null,根据业务选) + Object idObj = item.get("id"); + Integer idVal = null; + if (idObj != null) { + if (idObj instanceof Number) { + // 兼容数据库返回的Long/Integer/Short等数字类型 + idVal = ((Number) idObj).intValue(); + } else { + // 若id是字符串形式(如"123"),尝试解析为Integer + try { + idVal = Integer.parseInt(idObj.toString()); + } catch (NumberFormatException e) { + // 解析失败时的兜底处理(根据业务需求,可抛异常或设为0) + idVal = 0; + System.out.println("id字段转换失败,值为:" + idObj + ",已设为0"); + } + } + } + + // 3. 把转换后的值放回新Map(或覆盖原Map) + Map convertedItem = new HashMap<>(); + convertedItem.put("tableName", tableName); // String类型 + convertedItem.put("tableId", idVal); // Integer类型 + convertedList.add(convertedItem); + } + return Result.ok(convertedList); + } + + + // 根据任务id查询该任务绑定的表 + public Integer getTableIdByTaskId(Integer taskId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", taskId) + .select("table_id"); + + Task task = taskMapper.selectOne(queryWrapper); + return task != null ? task.getTableId() : null; + } + + + // ========== 新增:查询表结构(字段信息) ========== + @Override + public Result>> getTableColumns(String tableName,Integer taskId,Integer nowTableId) { + // 先校验表是否存在 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(DataTableConfigEntity::getTableName, tableName); + if (dataTableConfigMapper.selectCount(wrapper) == 0) { + return Result.fail("表[" + tableName + "]不存在"); + } + + // 查询该表结构 + List> columns = tableOperateMapper.getTableColumns(tableName); + + + //打印columns +// System.err.println("columns:"+columns); + //过滤不需要展示的字段 + columns.removeIf(map -> { + return "id".equals(map.get("columnName")); + }); + columns.removeIf(map ->{ + return "create_time".equals(map.get("columnName")); + }); + columns.removeIf(map ->{ + return "update_time".equals(map.get("columnName")); + }); + + //完成该任务与该表字段的采集情况匹配 + //获取该任务与该表字段的采集情况 + Integer tableId = getTableIdByTaskId(taskId); + if(taskId == null){// 该任务还未绑定任何表,是新增任务的流程,还处于选表状态 + //默认设为不采集 + int n = columns.size(); + for(int i=0;i column = columns.get(i); + column.put("isCollect",0);//前端显示时,默认都不采集 + } + } + else {// 该任务已经绑定了表 + if (tableId == nowTableId){//要查询的表是当前已经绑定过的表 + //获取该任务与该表字段的采集情况 + List> collectList = fillDataColumnMapper.getColumnCollectByTaskId(taskId); + int n = columns.size(); + for (int i = 0; i < n; i++) { + Map column = columns.get(i); + // 1. 先给每个字段设置【默认不采集】(解决默认值缺失的问题) + column.put("isCollect", 0); + + // 2. 遍历采集情况,匹配字段名 + for (int j = 0; j < collectList.size(); j++) { + Map collect = collectList.get(j); + + // 3. 先判空,避免空指针异常(核心修复点) + Object columnNameCol = column.get("columnName"); + Object columnNameCollect = collect.get("column_name"); + if (columnNameCol == null || columnNameCollect == null) { + continue; // 字段名为空则跳过,避免NPE + } + + // 4. 匹配字段名 + if (columnNameCol.equals(columnNameCollect)) { + // 匹配到则设置【采集状态】 + Integer isCollect; + + // 方法1:安全转换(推荐) + Object collectValue = collect.get("is_collect"); + if (collectValue instanceof Integer) { + isCollect = ((Integer) collectValue) == 1 ? 1 : 0; + } else if (collectValue instanceof Boolean) { + isCollect = ((Boolean) collectValue) ? 1 : 0; + } else { + isCollect = 0; // 默认值 + } + + column.put("isCollect", isCollect); + break; + } + } + } + } + else { //要查询的表是当前还未绑定过的表 + // + //默认设为不采集 + int n = columns.size(); + for(int i=0;i column = columns.get(i); + column.put("isCollect",0);//前端显示时,默认都不采集 + } + } + + } + return Result.ok(columns); + } + + // ========== 新增:查询表数据 ========== + @Override + public Result>> getTableData(String tableName) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(DataTableConfigEntity::getTableName, tableName); + if (dataTableConfigMapper.selectCount(wrapper) == 0) { + return Result.fail("表[" + tableName + "]不存在"); + } + List> data = tableOperateMapper.getTableData(tableName); + return Result.ok(data); + } + + // 原有方法:生成建表SQL + // 文件名:TableOperateServiceImpl.java(所在包:com.unionbigdata.teaching.service.impl) + /** + * 拼接建表SQL(适配新的字段配置:主键/精度/空值) + */ + private String buildCreateTableSql(TableCreateVO tableCreateVO) { + StringBuilder createSql = new StringBuilder(); + // 表名加反引号 防止中文/关键字报错 + createSql.append("CREATE TABLE IF NOT EXISTS `").append(tableCreateVO.getTableName()).append("` ("); + //自增主键 + createSql.append("`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,"); + + List fields = tableCreateVO.getFields(); + int fieldSize = fields.size(); + for (int i = 0; i < fieldSize; i++) { + TableFieldVO field = fields.get(i); + // 1. 拼接字段名 + createSql.append("`").append(field.getColumnName()).append("` "); + + // 2. 拼接字段类型 + 长度 + 精度【核心】 + createSql.append(field.getColumnType()); + if (field.getColumnLength() != null && field.getColumnLength() > 0) { + createSql.append("(").append(field.getColumnLength()); + // 精度有值 则拼接小数位数 例如 DECIMAL(10,2) 就是长度10,2位小数 + if (field.getColumnPrecision() != null && !field.getColumnPrecision().trim().isEmpty()) { + createSql.append(",").append(field.getColumnPrecision().trim()); + } + createSql.append(")"); + } + + // 3. 拼接主键约束 ✅ 你的字段:isPrimaryKey + // true=是主键 → 加 PRIMARY KEY,false=否 → 不加 + if (Boolean.TRUE.equals(field.getIsPrimaryKey())) { + createSql.append(" PRIMARY KEY"); + } + + // 4. 拼接非空约束 ✅ 你的字段:isnullable (全小写) + // true = 允许为空 → 不加约束;false = 不允许为空 → 加 NOT NULL + if (!field.isIsnullable()) { + createSql.append(" NOT NULL"); + } + + // 5. 拼接备注 ✅ 你的字段:columnComment + if (field.getColumnComment() != null && !field.getColumnComment().trim().isEmpty()) { + createSql.append(" COMMENT '").append(field.getColumnComment().trim()).append("'"); + } + + // 6. 字段之间加逗号 最后一个字段不加 避免SQL语法错误 + if (i != fieldSize - 1) { + createSql.append(","); + } + } + + // 固定添加创建时间、更新时间字段 + createSql.append(", create_time DATETIME DEFAULT CURRENT_TIMESTAMP"); + createSql.append(", update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"); + + // 表引擎和字符集 固定配置 + createSql.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + + return createSql.toString(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/TaskServiceImpl.java b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/TaskServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..1808092f072666358b776bc48da89b6137f88fa3 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/TaskServiceImpl.java @@ -0,0 +1,490 @@ +package com.unionbigdata.teaching.sevice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.unionbigdata.teaching.DTO.DynamicTableRequestDTO; +import com.unionbigdata.teaching.DTO.SelectColumnDTO; +import com.unionbigdata.teaching.DTO.TaskAddDTO; +import com.unionbigdata.teaching.entity.DataSource; +import com.unionbigdata.teaching.entity.QualityRuleEntity; +import com.unionbigdata.teaching.entity.Task; +import com.unionbigdata.teaching.mapper.*; +import com.unionbigdata.teaching.sevice.IQualityCheckService; +import com.unionbigdata.teaching.sevice.IQualityRuleService; +import com.unionbigdata.teaching.sevice.ITableOperateService; +import com.unionbigdata.teaching.sevice.ITaskService; +import com.unionbigdata.teaching.utils.SensitiveWordManager; +import com.unionbigdata.teaching.vo.*; +import jakarta.annotation.Resource; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class TaskServiceImpl extends ServiceImpl implements ITaskService { + + @Resource + private TaskMapper taskMapper; + + @Resource + private DataSourceMapper dataSourceMapper; + + @Resource + private DataTableConfigMapper dataTableConfigMapper; + + @Resource + private FillDataColumnMapper fillDataColumnMapper; + + @Resource + private TableOperateMapper tableOperateMapper; + + @Resource + private ITableOperateService tableOperateService; + + @Resource + private QualityRuleMapper qualityRuleMapper; + + @Resource + private IQualityRuleService qualityRuleService; + + //通过taskId查询该任务所用的质检规则 + private List getQualityRuleEntityListByTaskId(Integer taskId){ + List qualityRuleList = qualityRuleMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(QualityRuleEntity::getTaskId, taskId) + ); + return qualityRuleList; + } + + //根据taskId查询该任务对应的质检规则 + public List> getRuleListByTaskId(Integer taskId) { + //查询质检规则的个数,然后逐个获取 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(QualityRuleEntity::getTaskId, taskId); + List ruleList = qualityRuleMapper.selectList(queryWrapper); + + //遍历构造List + List> qualityRuleVOList = new ArrayList<>(); + for(int i=0;i map = new HashMap<>(); + QualityRuleEntity rule = ruleList.get(i); + + + map.put("ruleDesc",rule.getRuleDesc()); + map.put("ruleName",rule.getRuleName()); + map.put("ruleLevel",rule.getRuleLevel()); + + + qualityRuleVOList.add(map); + } + + return qualityRuleVOList; + } + + //通过taskId获取该任务的基本信息和所用质检规则 + @Override + public Map getTaskById(Integer taskId) { + Map dynamicJson = new HashMap<>(); + Task task = taskMapper.selectById(taskId); + + //获取全部的数据源(可优化为查询特定数据源) + List dataSourceList = dataSourceMapper.selectList(null); + List dataSourceVOList = dataSourceList.stream() + .map(this::convertDataSourceVO) + .collect(Collectors.toList()); + + if (!ObjectUtils.isEmpty(task)) { + dynamicJson.put("id",task.getId()); + dynamicJson.put("taskName",task.getTaskName()); + dynamicJson.put("version",task.getVersion());//任务版本 + dynamicJson.put("taskDescription",task.getTaskDescription()); + dynamicJson.put("isSensitiveDetection",task.getIsSensitiveDetection()); + dynamicJson.put("createTime",task.getCreateTime());//任务创建时间 + dynamicJson.put("dataSourceList",dataSourceVOList);//任务的数据源 + // --- 新增代码结束 --- + + dynamicJson.put("dataSourceList", dataSourceVOList); + } + + //根据taskId获取该任务所用的表id + Integer tableId = taskMapper.getTableIdByTaskId(taskId); + dynamicJson.put("tableId",tableId);//任务所用的表id + + //根据tableId获取表名 + String tableName = tableOperateMapper.getTableNameById(tableId); + dynamicJson.put("tableName",tableName);//任务所用的表名 + + //获取该任务所用质检规则 + + List> qualityRuleVOList = getRuleListByTaskId(taskId); + + //List qualityRuleList = getQualityRuleEntityListByTaskId(taskId); + dynamicJson.put("qualityRuleVOList",qualityRuleVOList);//任务的质检规则列表 + + return dynamicJson; + } + + @Override + public List queryTaskList(String timeType, LocalDate startDate, LocalDate endDate, String taskName) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + + // 1. 任务名称:仅当非空时添加模糊查询 + if (taskName != null && !taskName.trim().isEmpty()) { + queryWrapper.like("task_name", taskName.trim()); + } + + // 2. 时间范围:仅当startDate/endDate非空时添加区间条件 + // (timeType若仅用于区分时间字段,无值时不处理) + if (startDate != null) { + queryWrapper.ge(timeType, startDate); + } + if (endDate != null) { + queryWrapper.le(timeType, endDate); + } + + // 关键:若所有参数为空,QueryWrapper无任何条件 → 查询全部任务 + + //按创建时间降序 + queryWrapper.orderByDesc("create_time"); + List taskList = taskMapper.selectList(queryWrapper); + return taskList.stream() + .map(this::convertTaskVO) + .toList(); // Java16+简洁写法 + } + + @Override + public Object dataCollect(DynamicTableRequestDTO dynamicDTO) { + Integer taskId = dynamicDTO.getTaskId(); + //根据任务id查询到对应要填充的表的名称(1任务对1表,1表对n任务) + + //对数据进行清理(敏感词过滤、质检) + + //插入数据 + return null; + } + + private Integer addTaskOnly(TaskAddDTO taskAddDTO){ + Task task = new Task(); + BeanUtils.copyProperties(taskAddDTO,task); + int affectRows = taskMapper.insert(task); + if(affectRows > 0){ + //任务新增成功 + return task.getId(); + } + System.err.println("新增task失败"); + return null; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Boolean noTableIdAndAddTask(TaskAddDTO taskAddDTO) { + //无tableId,要新建task + 新建表 + 绑定字段与任务、表id + + + + //新建task,获取新建task的id +// taskAddDTO.setTableId(tableId); + Integer taskId = addTaskOnly(taskAddDTO); + System.err.println("taskId : " + taskId); + + + //将任务与质检规则进行绑定 + if(!ObjectUtils.isEmpty(taskAddDTO.getQualityRuleVOList())){ + List qualityRules = taskAddDTO.getQualityRuleVOList(); + boolean success = qualityRuleService.saveRule(taskId, taskAddDTO.getCreatorId(), qualityRules); + if(!success){ + throw new RuntimeException("新增质检规则失败,触发事务回滚"); + } + } + + + //新建表,获取新建table的id + TableCreateVO tableCreateVO = new TableCreateVO(); + taskAddDTO.setTaskId(taskId); + BeanUtils.copyProperties(taskAddDTO,tableCreateVO); + if(ObjectUtils.isEmpty(tableCreateVO.getFields())){ + throw new RuntimeException("字段为空,无法创建表,触发事务回滚"); + } + System.err.println("taskId : " + tableCreateVO.getTaskId()); + Integer tableId = tableOperateService.createTableByVisual(tableCreateVO); + // 3. 判断tableId是否为null:若为null,抛出异常触发回滚 + if (tableId == null) { + // 抛出运行时异常(Spring事务会捕获并回滚) + throw new RuntimeException("创建表失败,tableId为空,触发事务回滚"); + } + + + System.err.println("tableId : " + tableId); + + + //更新task与table的关联 + taskAddDTO.setTableId(tableId); + updateTask(taskAddDTO); + + //绑定字段与任务 + List fields = taskAddDTO.getFields(); + int fieldSize = fields.size(); + List temp = new ArrayList<>(); + for (int i = 0; i < fieldSize; i++) { + TableFieldVO field = fields.get(i); + SelectColumnDTO selectColumnDTO = new SelectColumnDTO(); + BeanUtils.copyProperties(field,selectColumnDTO); + selectColumnDTO.setLength(field.getColumnLength()); + selectColumnDTO.setIsCollect(1);//默认采集 + temp.add(selectColumnDTO); + } + if(temp != null && !temp.isEmpty()){ + fillDataColumnMapper.batchInsertTaskColumnRelation(taskId,temp,tableId); + } + else{ + throw new RuntimeException("字段为空,无法绑定字段与任务,触发事务回滚"); + } + + + //绑定任务的质检规则 +// qualityCheckService.executeQualityCheckByTaskId(taskId); +// QualityRuleVO qualityRuleVO = taskAddDTO.getQualityRuleVO(); +// qualityRuleVO.setTaskId(taskId); +// boolean success = qualityRuleService.saveRule(qualityRuleVO); +// if(!success){ +// throw new RuntimeException("新增质检规则失败,触发事务回滚"); +// } + + return Boolean.TRUE; + } + + @Override + public Boolean haveTableIdAndAddTask(TaskAddDTO taskAddDTO) { + //有tableId,要新建task + 绑定字段与任务 + + + //获取需要绑定的表 + Integer tableId = taskAddDTO.getTableId(); + //获取需要绑定的字段名 + List columnName = taskAddDTO.getSelectColumnDTO(); + + //更新字段名表,将任务与字段名进行绑定 + //先创建任务获取task_id + Task task = new Task(); + BeanUtils.copyProperties(taskAddDTO,task); + System.err.println("1212"); + Integer newTaskId;//用于获取新建任务的id + int affectRows = taskMapper.insert(task); + if(affectRows > 0){//任务新增成功 + //获取新增任务的task_id + newTaskId = task.getId(); + //再创建字段名表,将字段名与task_id进行绑定 + fillDataColumnMapper.batchInsertTaskColumnRelation(newTaskId,columnName,tableId); + + + //将任务与质检规则进行绑定 + if(!ObjectUtils.isEmpty(taskAddDTO.getQualityRuleVOList())){ + List qualityRules = taskAddDTO.getQualityRuleVOList(); + boolean success = qualityRuleService.saveRule(newTaskId, taskAddDTO.getCreatorId(), qualityRules); + if(!success){ + throw new RuntimeException("新增质检规则失败,触发事务回滚"); + } + } + } + else{ + throw new RuntimeException("新增任务失败,触发事务回滚"); + } + return Boolean.TRUE; + } + + private int updateTask(TaskAddDTO taskAddDTO){ + Task task = new Task(); + BeanUtils.copyProperties(taskAddDTO,task); + task.setId(taskAddDTO.getTaskId()); + return taskMapper.updateById(task); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Object haveTableIdAndEditTask(TaskAddDTO taskAddDTO) { + //编辑逻辑1-----表的字段之前存储过 + //有tableId,修改task相关信息 + 修改绑定字段的采集情况 + + + System.err.println(taskAddDTO); + //获取当前任务id + Integer taskId = taskAddDTO.getTaskId(); + + + //将任务与质检规则进行绑定 + if(!ObjectUtils.isEmpty(taskAddDTO.getQualityRuleVOList())){ + List qualityRules = taskAddDTO.getQualityRuleVOList(); + boolean success = qualityRuleService.saveRule(taskId, taskAddDTO.getCreatorId(), qualityRules); + if(!success){ + throw new RuntimeException("新增质检规则失败,触发事务回滚"); + } + } + + + //修改绑定字段的采集情况 + Integer nowTableId = taskAddDTO.getTableId();//此次编辑传输的表 + System.err.println("nowTableId:" + nowTableId); + Integer lastTableId = taskMapper.selectById(taskId).getTableId();//编辑前的表 + System.err.println("lastTableId:" + lastTableId); + + //修改task相关信息 + updateTask(taskAddDTO); + + if (lastTableId == null){ + throw new RuntimeException("任务不存在,ID:" + taskId); + } + if(lastTableId.equals(nowTableId)){//如果表没变,则直接更新字段的采集情况 + //更新字段名表,将任务与字段名进行绑定 + System.err.println("表没变"); + fillDataColumnMapper.batchUpdateTaskColumnRelation(taskId,taskAddDTO.getSelectColumnDTO()); + return Boolean.TRUE; + } + else {//如果表变了,则删除原有任务、表、列关系,再重新创建 + //删除原有任务、表、列关系 + System.err.println("表变了"); + fillDataColumnMapper.deleteBatchByTaskId(taskId); + //修改task表中的表id + taskMapper.updateTableIdByTaskId(taskId,taskAddDTO.getTableId()); + + //创建新任务、表、列关系 + fillDataColumnMapper.batchInsertTaskColumnRelation(taskId,taskAddDTO.getSelectColumnDTO(),nowTableId); + return Boolean.TRUE; + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Object noTableIdAndEditTask(TaskAddDTO taskAddDTO) { + //无tableId,修改task相关信息 + 要删除原来的(绑定字段与任务) + 新建表 + 绑定字段与任务 + + + + //获取当前任务id + Integer taskId = taskAddDTO.getTaskId(); + + //将任务与质检规则进行绑定 + if(!ObjectUtils.isEmpty(taskAddDTO.getQualityRuleVOList())){ + List qualityRules = taskAddDTO.getQualityRuleVOList(); + boolean success = qualityRuleService.saveRule(taskId, taskAddDTO.getCreatorId(), qualityRules); + if(!success){ + throw new RuntimeException("新增质检规则失败,触发事务回滚"); + } + } + + + //删除原有任务、表、列关系 + fillDataColumnMapper.deleteBatchByTaskId(taskId); + + + //新建表 + System.err.println("动态建表"); + TableCreateVO tableCreateVO = new TableCreateVO(); + BeanUtils.copyProperties(taskAddDTO,tableCreateVO); + //创建表 + Integer tableId = tableOperateService.createTableByVisual(tableCreateVO); + // 3. 判断tableId是否为null:若为null,抛出异常触发回滚 + if (tableId == null) { + // 抛出运行时异常(Spring事务会捕获并回滚) + throw new RuntimeException("创建表失败,tableId为空,触发事务回滚"); + } + //修改task相关信息 + taskAddDTO.setTableId(tableId); + int affectRows = updateTask(taskAddDTO); + + + //绑定字段与任务 + List fields = taskAddDTO.getFields(); + int fieldSize = fields.size(); + List temp = new ArrayList<>(); + for (int i = 0; i < fieldSize; i++) { + TableFieldVO field = fields.get(i); + SelectColumnDTO selectColumnDTO = new SelectColumnDTO(); + BeanUtils.copyProperties(field,selectColumnDTO); + selectColumnDTO.setLength(field.getColumnLength()); + selectColumnDTO.setIsCollect(1);//默认采集 + temp.add(selectColumnDTO); + } + fillDataColumnMapper.batchInsertTaskColumnRelation(taskId,temp,tableId); + + return null; + } + + @Override + public Map getTaskDetailByTaskId(Integer taskId) { + Map dynamicJson = new HashMap<>(); + Integer tableId = taskMapper.selectById(taskId).getTableId(); + String tableName = tableOperateMapper.getTableNameById(tableId); + + dynamicJson.put("tableName",tableName); + dynamicJson.put("tableId",tableId); + + return dynamicJson; + } + + //批量删除任务 + @Transactional(rollbackFor = Exception.class) + @Override + public Boolean removeTaskBatchByIds(List ids) {//会把该任务所用table删除 + + // 空值校验:避免无效循环 + if (ids == null || ids.isEmpty()) { + throw new IllegalArgumentException("待删除的任务ID列表不能为空"); + } + + for (Integer id : ids) { + if (id == null || id <= 0) { + throw new IllegalArgumentException("任务ID不能为null或非正整数:" + id); + } + //删除任务与字段的关系信息(fill_data_column) + fillDataColumnMapper.deleteBatchByTaskId(id); + + //删除该任务对应的表(从数据库中删除) + Integer tableId = taskMapper.selectById(id).getTableId(); + String tableName = tableOperateMapper.getTableNameById(tableId); + tableOperateMapper.dropTableByTableName(tableName); + + //删除该任务对应的表(从记录表名的表上删除,data_table_config) + tableOperateMapper.deleteTableByTaskId(id); + + // 删除task表中的任务,校验删除结果(task) + int taskDelCount = taskMapper.deleteById(id); + // 核心:如果任务删除失败(无数据可删),主动抛异常触发回滚 + if (taskDelCount == 0) { + throw new RuntimeException("任务ID=" + id + "不存在,删除失败,触发回滚"); + } + } + return Boolean.TRUE; + } + + private TaskVO convertTaskVO(Task task) { + TaskVO taskVO = new TaskVO(); + if (!ObjectUtils.isEmpty(task)) { + taskVO.setId(task.getId()); + taskVO.setTaskName(task.getTaskName()); + taskVO.setUpdateTime(task.getUpdateTime()); + taskVO.setUpdateTime(task.getUpdateTime()); + taskVO.setStatus(task.getStatus()); + taskVO.setTaskDescription(task.getTaskDescription()); + } + return taskVO; + } + + private DataSourceVO convertDataSourceVO(DataSource dataSource) { + DataSourceVO dataSourceVO = new DataSourceVO(); + if (!ObjectUtils.isEmpty(dataSource)) { + dataSourceVO.setId(dataSource.getId()); + dataSourceVO.setDataSourceName(dataSource.getDataSourceName()); + } + return dataSourceVO; + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/utils/RuleParamUtil.java b/backend/src/main/java/com/unionbigdata/teaching/utils/RuleParamUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..1fc23807c1055b3c82a37a7b11f829838b39f535 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/utils/RuleParamUtil.java @@ -0,0 +1,19 @@ +package com.unionbigdata.teaching.utils; + +import com.unionbigdata.teaching.entity.RuleParamEntity; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class RuleParamUtil { + // 按数据项分组规则参数 + public static Map> groupParamByColumnName(List paramList) { + Map> columnParamMap = new HashMap<>(); + if (paramList == null || paramList.isEmpty()) { + return columnParamMap; + } + columnParamMap = paramList.stream().collect(Collectors.groupingBy(RuleParamEntity::getParamName)); + return columnParamMap; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/utils/SensitiveWordManager.java b/backend/src/main/java/com/unionbigdata/teaching/utils/SensitiveWordManager.java new file mode 100644 index 0000000000000000000000000000000000000000..d36ba7fe1f9f56df62dd3ea3374af70704bf9945 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/utils/SensitiveWordManager.java @@ -0,0 +1,70 @@ +package com.unionbigdata.teaching.utils; +import com.unionbigdata.teaching.mapper.SensitiveWordMapper; +import org.springframework.stereotype.Component; + +import jakarta.annotation.PostConstruct; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 敏感词工具类:从数据库加载敏感词+缓存+替换逻辑 + */ +@Component +public class SensitiveWordManager { + // 缓存【启用状态】的敏感词(避免频繁查库) + private Set enabledSensitiveWords = new HashSet<>(); + // 敏感词匹配的正则表达式(预编译,提升性能) + private Pattern sensitiveWordPattern; + + // 注入敏感词Mapper,用于从数据库查询敏感词 + private final SensitiveWordMapper sensitiveWordMapper; + public SensitiveWordManager(SensitiveWordMapper sensitiveWordMapper) { + this.sensitiveWordMapper = sensitiveWordMapper; + } + + /** + * 项目启动时自动加载【启用的敏感词】到缓存 + */ + @PostConstruct + public void loadEnabledSensitiveWords() { + // 从数据库查询:is_enabled=1的敏感词内容 + List words = sensitiveWordMapper.selectEnabledWordContents(); + enabledSensitiveWords.clear(); + enabledSensitiveWords.addAll(words); + + // 构建敏感词正则(转义特殊字符,避免正则语法错误) + if (!enabledSensitiveWords.isEmpty()) { + StringBuilder regexBuilder = new StringBuilder(); + for (String word : enabledSensitiveWords) { + // Pattern.quote():转义敏感词中的特殊字符(如.、*、|等) + regexBuilder.append(Pattern.quote(word)).append("|"); + } + // 移除最后一个多余的"|" + regexBuilder.deleteCharAt(regexBuilder.length() - 1); + // 编译正则(忽略大小写,避免漏检“美国”和“美國”) + sensitiveWordPattern = Pattern.compile(regexBuilder.toString(), Pattern.CASE_INSENSITIVE); + } + } + + /** + * 核心方法:对单个字符串做敏感词替换(替换为等长度的*) + * @param text 待检测的文本 + * @return 替换敏感词后的文本 + */ + public String replaceSensitiveWord(String text) { + // 空值/无敏感词时直接返回原文本 + if (text == null || text.isEmpty() || sensitiveWordPattern == null) { + return text; + } + + Matcher matcher = sensitiveWordPattern.matcher(text); + // 匹配到敏感词则替换为等长度的“*” + return matcher.replaceAll(matchResult -> { + String matchedWord = matchResult.group(); + return "*".repeat(matchedWord.length()); + }); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/DataSourceVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/DataSourceVO.java new file mode 100644 index 0000000000000000000000000000000000000000..3d4b0286f5b33af3245a3c7f5fabeba9009b3086 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/DataSourceVO.java @@ -0,0 +1,17 @@ +package com.unionbigdata.teaching.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class DataSourceVO { + @Schema(description = "数据源id") + private Integer id; + + @Schema(description = "数据源名称") + private String dataSourceName; + + //暂时没用? +// @Schema(description = "任务id") +// private String taskId; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/DataTableConfigVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/DataTableConfigVO.java new file mode 100644 index 0000000000000000000000000000000000000000..1f91d83c95aa864ddc6600cd45f5ca5136a8ad83 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/DataTableConfigVO.java @@ -0,0 +1,24 @@ +package com.unionbigdata.teaching.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "数据表配置VO") +@Data +public class DataTableConfigVO { + @Schema(description = "表配置ID") + private Integer id; + @Schema(description = "字段数量") + private Integer fieldCount; + @Schema(description = "表名") + private String tableName; + @Schema(description = "任务ID") + private Integer taskId; + @Schema(description = "用户ID") + private Integer fillerId; + private LocalDateTime createTime; // 对应create_time + + private LocalDateTime updateTime; // 对应update_time +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/FillDataColumnVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/FillDataColumnVO.java new file mode 100644 index 0000000000000000000000000000000000000000..feba07198f1f7bf8c6b9b465c5c83a23ea38c244 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/FillDataColumnVO.java @@ -0,0 +1,19 @@ +package com.unionbigdata.teaching.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "填报数据列VO") +@Data +public class FillDataColumnVO { + @Schema(description = "列ID") + private Integer id; + @Schema(description = "关联填报记录ID") + private Integer fillDataId; + @Schema(description = "字段名") + private String columnName; + @Schema(description = "字段类型") + private String columnType; + @Schema(description = "字段值") + private String columnValue; +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/QualityResultVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/QualityResultVO.java new file mode 100644 index 0000000000000000000000000000000000000000..a80bae6cfa3b81a8735322696b499ce1ac2ca76f --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/QualityResultVO.java @@ -0,0 +1,25 @@ +package com.unionbigdata.teaching.vo; +import com.unionbigdata.teaching.entity.RuleParamEntity; +import lombok.Data; +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class QualityResultVO { + // 质检规则核心信息 + private Integer ruleId; // 质检规则ID + private String ruleName; // 规则名称 + private String ruleDesc; // 规则描述 + private String ruleLevel; // 规则等级(high/common) + + // 关联任务信息(从task表关联) + private Integer taskId; // 任务ID + private String taskName; // 任务名称(需从task表查询) + + // 时间信息 + private LocalDateTime createTime; // 创建时间 + private LocalDateTime updateTime; // 更新时间 + + // 关联参数列表 + private List paramList; // 规则参数(从rule_param表查询) +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/QualityRuleVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/QualityRuleVO.java new file mode 100644 index 0000000000000000000000000000000000000000..3d65d7f7aa9501c7fff41a07c3c23905c07caf3c --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/QualityRuleVO.java @@ -0,0 +1,16 @@ +package com.unionbigdata.teaching.vo; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.util.List; + +@Data +@TableName("quality_rule") +public class QualityRuleVO { + private Integer taskId; // 新增不传,编辑传 + private Integer id; // 新增不传,编辑传 + private String ruleDesc; // 必填 + private String ruleLevel; // 必填 high/common + private String ruleName; // 必填 + private List paramList; // 必填 规则参数集合 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/RuleParamVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/RuleParamVO.java new file mode 100644 index 0000000000000000000000000000000000000000..594f3208dc7a848ef9209627214bc4279ca981b3 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/RuleParamVO.java @@ -0,0 +1,13 @@ +package com.unionbigdata.teaching.vo; + +import lombok.Data; + +import com.baomidou.mybatisplus.annotation.TableName; + +@Data +@TableName("rule_param") +public class RuleParamVO { + private String paramName; // 必填 字段名 + private String paramType; // 必填 纯运算符 + private String paramValue; // 必填 条件值 +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/SensitiveWordVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/SensitiveWordVO.java new file mode 100644 index 0000000000000000000000000000000000000000..30488371b4a4a1e7d5fd9fb5888782db4767dd38 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/SensitiveWordVO.java @@ -0,0 +1,20 @@ +package com.unionbigdata.teaching.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "敏感词VO") +@Data +public class SensitiveWordVO { + + @Schema(description = "敏感词ID") + private Long id; + + //敏感词 + @Schema(description = "敏感词") + private String wordContent; + + //是否启用 + @Schema(description = "是否启用") + private Integer isEnabled; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/TableCreateVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/TableCreateVO.java new file mode 100644 index 0000000000000000000000000000000000000000..5f2b122b855234e99729d3ec35d4e5b1221a6c71 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/TableCreateVO.java @@ -0,0 +1,26 @@ +package com.unionbigdata.teaching.vo; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.util.List; + +@Data +public class TableCreateVO { + //用于新建表完成时,接收新建表的id + private Integer id; + + @NotBlank(message = "数据源id,不为空") + private Integer dataSourceId; + + @NotBlank(message = "表名不能为空") + private String tableName; // 用户自定义的表名 + + @NotEmpty(message = "至少需要1个字段") + private List fields; // 字段列表 + + private Integer taskId; // 关联的任务ID(从前端任务选择传入) + private Integer fillerId; // 关联的用户ID(从前端传入) + +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/TableFieldVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/TableFieldVO.java new file mode 100644 index 0000000000000000000000000000000000000000..a8ad5271a41dd9af4e675b1c0811bb771f13ded6 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/TableFieldVO.java @@ -0,0 +1,28 @@ +package com.unionbigdata.teaching.vo; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class TableFieldVO { + @NotBlank(message = "字段名不能为空") + private String columnName; // 字段名(如username) + + @NotBlank(message = "字段类型不能为空") + private String columnType; // 字段类型(如VARCHAR/INT/DECIMAL) + + @NotNull(message = "字段长度不能为空") // 修复1:Integer类型不能用@NotBlank,必须用@NotNull + private Integer columnLength; // 字段长度(如20/10) + + @NotNull(message = "是否主键不能为空!") + private Boolean isPrimaryKey; // 是否为主键 ✅ 你的字段名:isPrimaryKey + + @NotNull(message = "字段是否可空不能为空") // 修复2:boolean基本类型不能用@NotBlank,必须用@NotNull + private boolean isnullable; // 是否允许为空 ✅ 你的字段名:isnullable 【注意:全小写】 + + private String columnPrecision; // 精度 ✅ 你的字段名:columnPrecision (如填2 就是2位小数) + + //注释 或 字段备注 + private String columnComment; +} \ No newline at end of file diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/TaskVO.java b/backend/src/main/java/com/unionbigdata/teaching/vo/TaskVO.java new file mode 100644 index 0000000000000000000000000000000000000000..5c87c379931fb98d3b3eefa5c6d6ff08c12bc040 --- /dev/null +++ b/backend/src/main/java/com/unionbigdata/teaching/vo/TaskVO.java @@ -0,0 +1,30 @@ +package com.unionbigdata.teaching.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "任务VO") +@Data +public class TaskVO { + @Schema(description = "任务id") + private Integer id; + + @Schema(description = "任务名称") + private String taskName; + + @Schema(description = "发布时间") + private LocalDateTime publishTime; + + @Schema(description = "更新时间") + private LocalDateTime updateTime; + + @Schema(description = "状态") + private String status; + + @Schema(description = "任务描述") + private String taskDescription; +} diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 8f7cf050de5fea489d320783deb58eab8ba209f0..62f758fdc3c7c4b75217059ae071a36d0d1dda56 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -4,34 +4,53 @@ server: spring: application: name: data-acqusition-system + + # 您的数据库配置 datasource: - url: jdbc:mysql://localhost:3306/data-acqusition-system?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai + url: jdbc:mysql://localhost:3306/data_acqusition_system?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true username: root - password: 123456 + password: hyy4088.. driver-class-name: com.mysql.cj.jdbc.Driver + + # 建议添加连接池配置(提高性能) + hikari: + connection-timeout: 30000 + maximum-pool-size: 20 + minimum-idle: 5 + sql: init: - mode: never + mode: never # 您已手动导入数据,所以用never + mybatis-plus: + # 您的mapper文件路径 mapper-locations: classpath*:com/unionbigdata/teaching/mapper/xml/*.xml + + # 添加实体类包扫描 + type-aliases-package: com.unionbigdata.teaching.entity + global-config: db-config: id-type: auto + configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + map-underscore-to-camel-case: true # 自动下划线转驼峰 springdoc: swagger-ui: path: /swagger-ui.html tags-sorter: alpha operations-sorter: alpha + api-docs: path: /v3/api-docs + group-configs: - group: 'default' paths-to-match: '/**' - packages-to-scan: com.unionbigdata.teaching -# knife4j的增强配置,不需要增强可以不配 + packages-to-scan: com.unionbigdata.teaching.controller # 建议精确到controller包 + knife4j: enable: true setting: diff --git a/data-acqusition-system_VL/.gitignore b/data-acqusition-system_VL/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0be260d8505e90e7f6083969f6870e0f30986e4a --- /dev/null +++ b/data-acqusition-system_VL/.gitignore @@ -0,0 +1,59 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/node_modules/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### ### +dependency-reduced-pom.xml +### ### +__pycache__ +/logs/** +/**/.flattened-pom.xml +/**/rebel.xml +*.log +/**/node_modules/ +/**/.idea/ +/**/dist/ +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.loca + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +# dependencies +/node_modules +/.pnp +.pnp.js \ No newline at end of file diff --git a/frontend/web-management-react/src/views/test1/index.css b/data-acqusition-system_VL/README.md similarity index 100% rename from frontend/web-management-react/src/views/test1/index.css rename to data-acqusition-system_VL/README.md diff --git a/data-acqusition-system_VL/backend/mvnw b/data-acqusition-system_VL/backend/mvnw new file mode 100644 index 0000000000000000000000000000000000000000..19529ddf8c6eaa08c5c75ff80652d21ce4b72f8c --- /dev/null +++ b/data-acqusition-system_VL/backend/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/data-acqusition-system_VL/backend/mvnw.cmd b/data-acqusition-system_VL/backend/mvnw.cmd new file mode 100644 index 0000000000000000000000000000000000000000..249bdf3822221aa612d1da2605316cabd7b07e50 --- /dev/null +++ b/data-acqusition-system_VL/backend/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/data-acqusition-system_VL/backend/pom.xml b/data-acqusition-system_VL/backend/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..4689d0b3e5958bd3a7696622e1b694ea9b95b140 --- /dev/null +++ b/data-acqusition-system_VL/backend/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.4.1 + + + + com.unionbigdata + teaching + 0.0.1-SNAPSHOT + AI-Platform + AI Platform + + + + 17 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.mysql + mysql-connector-j + 8.0.33 + runtime + + + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.5 + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + 4.5.0 + + + + + org.projectlombok + lombok + 1.18.34 + provided + + + + cn.dev33 + sa-token-spring-boot3-starter + 1.44.0 + + + + + + + + + src/main/java + + **/*.xml + + + + src/main/resources + true + + **/*.* + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/BootStrapApplication.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/BootStrapApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..9d2df8dc90ce941e929578a7699250b79448a8c0 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/BootStrapApplication.java @@ -0,0 +1,26 @@ +package com.unionbigdata.teaching; + +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +@SpringBootApplication(scanBasePackages = "com.unionbigdata") +@MapperScan("com.unionbigdata.teaching.mapper") +@Slf4j +public class BootStrapApplication { + + public static void main(String[] args) { + ConfigurableApplicationContext application = SpringApplication.run(BootStrapApplication.class, args); + Environment env = application.getEnvironment(); + log.info("\n----------------------------------------------------------\n\t" + + "Application '{}' is running! Access URLs:\n\t" + + "Doc: \thttp://localhost:{}/doc.html\n"+ + "----------------------------------------------------------", + env.getProperty("spring.application.name"), + env.getProperty("server.port")); + } + +} diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/common/Result.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/common/Result.java new file mode 100644 index 0000000000000000000000000000000000000000..1363a5cac807325f3647b9325c26a5d41a407372 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/common/Result.java @@ -0,0 +1,83 @@ +package com.unionbigdata.teaching.common; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Data +@Accessors(chain = true) +public class Result implements Serializable { + public static final long serialVersionUID = 42L; + public static final String SUCCESS_CODE = "200"; + public static final String FAIL_CODE = "500"; + + public static final String SUCCESS_MSG = "success"; + public static final String FAIL_MSG = "fail"; + + private String code; + + private String msg; + private T content; + private String requestId; + /** + * 先保留原id,避免其他版本报错 + */ + private String id; + + public static Result ok() { + Result r = new Result(Result.SUCCESS_CODE, Result.SUCCESS_MSG); + return r; + } + + public static Result ok(T content) { + Result r = new Result(Result.SUCCESS_CODE, SUCCESS_MSG); + r.setContent(content); + return r; + } + + public static Result fail() { + Result r = new Result(Result.FAIL_CODE, Result.FAIL_MSG); + return r; + } + + public static Result fail(String msg) { + Result r = new Result(Result.FAIL_CODE, msg); + return r; + } + + public static Result error(String code, String msg) { + Result r = new Result(code, msg); + return r; + } + + public static Result error(String id, String code, String msg) { + Result r = new Result(id, code, msg); + return r; + } + + public Result() { + } + + public Result(String code, String msg) { + this.code = code; + this.msg = msg; + } + + public Result(String id, String code, String msg) { + this.requestId = id; + this.code = code; + this.msg = msg; + } + + public Result(T content) { + this.code = SUCCESS_CODE; + this.msg = Result.SUCCESS_MSG; + this.content = content; + } + + public boolean success() { + return SUCCESS_CODE.equals(this.code); + } + +} \ No newline at end of file diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/MyBatisPlusConfig.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/MyBatisPlusConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..e9a9655a2e51c1f1abb41960b651527312851dbe --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/MyBatisPlusConfig.java @@ -0,0 +1,22 @@ +package com.unionbigdata.teaching.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MyBatisPlusConfig { + /** + * 分页插件配置 + * + * @return + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } +} diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/SaTokenWebMvcConfig.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/SaTokenWebMvcConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..39f86021f5daeadb0ca42383fd7afe75926acc6e --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/SaTokenWebMvcConfig.java @@ -0,0 +1,31 @@ +package com.unionbigdata.teaching.config; + +import cn.dev33.satoken.interceptor.SaInterceptor; +import cn.dev33.satoken.stp.StpUtil; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class SaTokenWebMvcConfig implements WebMvcConfigurer { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new SaInterceptor(handle -> { + // 全局登录校验:未登录会抛异常 + StpUtil.checkLogin(); + })) + .addPathPatterns("/**") + // 放行登录、文档接口 + .excludePathPatterns( + "/auth/login", + "/error", + "/actuator/**", + "/v3/api-docs/**", + "/swagger-ui/**", + "/swagger-ui.html", + "/doc.html", + "/webjars/**" + ); + } +} diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/SwaggerConfig.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/SwaggerConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..f882c1b0e56838c3ffc6e7f205dcbf64b5458d73 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/config/SwaggerConfig.java @@ -0,0 +1,29 @@ +package com.unionbigdata.teaching.config; + +import io.swagger.v3.oas.models.OpenAPI; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class SwaggerConfig implements WebMvcConfigurer { + @Bean + public OpenAPI openApi() { + return new OpenAPI().info(new io.swagger.v3.oas.models.info.Info() + .description("数据补充采集系统") + .version("v1.0") + .title("数据补充采集系统")); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + // 添加 Swagger UI 静态资源路径 + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + // 添加 OpenAPI 文档访问路径 + registry.addResourceHandler("/v3/api-docs/**") + .addResourceLocations("classpath:/META-INF/resources/"); + } +} + diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/controller/AuthController.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/controller/AuthController.java new file mode 100644 index 0000000000000000000000000000000000000000..060f0efdd0186acc2a4e30bc95d2a42a275348a6 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/controller/AuthController.java @@ -0,0 +1,39 @@ +package com.unionbigdata.teaching.controller; + +import cn.dev33.satoken.stp.StpUtil; +import com.unionbigdata.teaching.common.Result; +import com.unionbigdata.teaching.sevice.IUserService; +import com.unionbigdata.teaching.vo.LoginResultVO; +import com.unionbigdata.teaching.vo.LoginVO; +import com.unionbigdata.teaching.vo.UserVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/auth") +@Tag(name = "授权") +@Slf4j +@RequiredArgsConstructor +public class AuthController { + + private final IUserService userService; + + @Operation(summary = "登录") + @PostMapping("/login") + public Result login(@RequestBody LoginVO loginVO) { + return Result.ok(userService.login(loginVO)); + } + + @Operation(summary = "退出") + @PostMapping("/logout") + public Result logout() { + StpUtil.logout(); + return Result.ok(); + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/controller/UserController.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/controller/UserController.java similarity index 92% rename from backend/src/main/java/com/unionbigdata/teaching/controller/UserController.java rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/controller/UserController.java index a9baf2f33625da6439d2dab620d6bab4de9e6987..cf4346ba29f777bbba8e0334dfbbb046b3eeed5e 100644 --- a/backend/src/main/java/com/unionbigdata/teaching/controller/UserController.java +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/controller/UserController.java @@ -5,6 +5,7 @@ import com.unionbigdata.teaching.sevice.IUserService; import com.unionbigdata.teaching.vo.UserVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -13,6 +14,7 @@ import java.util.List; @RestController @RequestMapping("/user") @Tag(name = "用户信息") +@Slf4j public class UserController { @Autowired @@ -21,7 +23,7 @@ public class UserController { @Operation(summary = "根据Id查询用户信息") @GetMapping("/{id}") public Result findById(@PathVariable Long id) { - return Result.ok(testService.findById(id)); + return Result.ok(testService.findById(2L)); } @Operation(summary = "新增用户") diff --git a/backend/src/main/java/com/unionbigdata/teaching/entity/UserEntity.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/entity/UserEntity.java similarity index 87% rename from backend/src/main/java/com/unionbigdata/teaching/entity/UserEntity.java rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/entity/UserEntity.java index 5fdf2f1ea9556e4e1425e03e06ff8cc9ecd465ac..45d91b413c131babdfeff2b74ee07b6b137fff56 100644 --- a/backend/src/main/java/com/unionbigdata/teaching/entity/UserEntity.java +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/entity/UserEntity.java @@ -12,9 +12,13 @@ public class UserEntity { @TableId(value = "id",type = IdType.AUTO) private Long id; + private String userName; + private String name; private Integer age; private Integer gender; + + private String password; } diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/handler/GlobalExceptionHandler.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..16f8ff0621065fb04abc8966bd162e6ca50228e7 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/handler/GlobalExceptionHandler.java @@ -0,0 +1,24 @@ +package com.unionbigdata.teaching.handler; + +import cn.dev33.satoken.exception.NotLoginException; +import com.unionbigdata.teaching.common.Result; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(NotLoginException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ResponseBody + public Object handleNotLogin(NotLoginException e) { + return Result.error("401", "未登录或登录已过期"); + } + + @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ResponseBody + public Object handleBadRequest(IllegalArgumentException e) { + return Result.error("400", e.getMessage()); + } +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/UserMapper.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/mapper/UserMapper.java similarity index 100% rename from backend/src/main/java/com/unionbigdata/teaching/mapper/UserMapper.java rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/mapper/UserMapper.java diff --git a/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/UserMapper.xml b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/UserMapper.xml similarity index 100% rename from backend/src/main/java/com/unionbigdata/teaching/mapper/xml/UserMapper.xml rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/mapper/xml/UserMapper.xml diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/IUserService.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/sevice/IUserService.java similarity index 66% rename from backend/src/main/java/com/unionbigdata/teaching/sevice/IUserService.java rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/sevice/IUserService.java index 2a651644d6957e333b125e8f5368cb542cfecb85..fab7e738bcc318b20b893a1121fc4f55e45280e8 100644 --- a/backend/src/main/java/com/unionbigdata/teaching/sevice/IUserService.java +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/sevice/IUserService.java @@ -1,5 +1,7 @@ package com.unionbigdata.teaching.sevice; +import com.unionbigdata.teaching.vo.LoginResultVO; +import com.unionbigdata.teaching.vo.LoginVO; import com.unionbigdata.teaching.vo.UserVO; import java.util.List; @@ -16,6 +18,7 @@ public interface IUserService { /** * 保存用户 + * * @param userVO * @return */ @@ -23,7 +26,16 @@ public interface IUserService { /** * 查询用户列表 + * * @return */ List findUserList(); + + /** + * 用户登录 + * + * @param loginVO + * @return + */ + LoginResultVO login(LoginVO loginVO); } diff --git a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/UserServiceImpl.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/UserServiceImpl.java similarity index 60% rename from backend/src/main/java/com/unionbigdata/teaching/sevice/impl/UserServiceImpl.java rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/UserServiceImpl.java index d141858ad72e9402d2853d081be7a02f70ec9d19..4cd74d451253871766115842df6ca7dd5bccbb93 100644 --- a/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/UserServiceImpl.java +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/sevice/impl/UserServiceImpl.java @@ -1,15 +1,19 @@ package com.unionbigdata.teaching.sevice.impl; +import cn.dev33.satoken.stp.SaTokenInfo; +import cn.dev33.satoken.stp.StpUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.unionbigdata.teaching.entity.UserEntity; import com.unionbigdata.teaching.mapper.UserMapper; import com.unionbigdata.teaching.sevice.IUserService; +import com.unionbigdata.teaching.vo.LoginResultVO; +import com.unionbigdata.teaching.vo.LoginVO; import com.unionbigdata.teaching.vo.UserVO; import jakarta.annotation.Resource; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.ObjectUtils; -import java.util.ArrayList; import java.util.List; @Service @@ -54,4 +58,20 @@ public class UserServiceImpl implements IUserService { } + @Override + public LoginResultVO login(LoginVO loginVO) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(UserEntity::getUserName, loginVO.getUserName()); + UserEntity userEntity = userMapper.selectOne(wrapper); + if (ObjectUtils.isEmpty(userEntity)) { + throw new IllegalArgumentException("未找到该用户!"); + } + if (ObjectUtils.notEqual(userEntity.getPassword(), loginVO.getPassword())) { + throw new IllegalArgumentException("用户名或密码错误!"); + } + Long userId = userEntity.getId(); + StpUtil.login(userId); + SaTokenInfo tokenInfo = StpUtil.getTokenInfo(); + return new LoginResultVO(tokenInfo.getTokenName(), tokenInfo.getTokenValue(), userId); + } } diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/LoginResultVO.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/LoginResultVO.java new file mode 100644 index 0000000000000000000000000000000000000000..a0536d12176a055c415167ab91140732515b2851 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/LoginResultVO.java @@ -0,0 +1,22 @@ +package com.unionbigdata.teaching.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Schema(description = "用户登录结果VO") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoginResultVO { + + @Schema(description = "token名称") + private String tokenName; + + @Schema(description = "token值") + private String tokenValue; + + @Schema(description = "登录ID") + private Long loginId; +} diff --git a/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/LoginVO.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/LoginVO.java new file mode 100644 index 0000000000000000000000000000000000000000..97761e4eb7ab9b0da01648daa6a177896a386af5 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/LoginVO.java @@ -0,0 +1,15 @@ +package com.unionbigdata.teaching.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户登录VO") +@Data +public class LoginVO { + + @Schema(description = "用户名") + private String userName; + + @Schema(description = "密码") + private String password; +} diff --git a/backend/src/main/java/com/unionbigdata/teaching/vo/UserVO.java b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/UserVO.java similarity index 78% rename from backend/src/main/java/com/unionbigdata/teaching/vo/UserVO.java rename to data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/UserVO.java index 19cb3fce9a3124d563246d76cfbbe0a77b8abcab..8102952015e2e176b5ab3e6ff4c0ca5fcdf11d7e 100644 --- a/backend/src/main/java/com/unionbigdata/teaching/vo/UserVO.java +++ b/data-acqusition-system_VL/backend/src/main/java/com/unionbigdata/teaching/vo/UserVO.java @@ -10,12 +10,15 @@ public class UserVO { @Schema(description = "id") private Long id; + @Schema(description = "用户名") + private String userName; + @Schema(description = "姓名") private String name; @Schema(description = "年龄") private Integer age; - @Schema(description = "x性别") + @Schema(description = "性别") private Integer gender; } diff --git a/data-acqusition-system_VL/backend/src/main/resources/application.yml b/data-acqusition-system_VL/backend/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..937c75b75fa83262d961ae3f5ce7a26f5e5fb857 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/resources/application.yml @@ -0,0 +1,58 @@ +server: + port: 8080 + +spring: + application: + name: data-acqusition-system + datasource: + url: jdbc:mysql://localhost:3306/data-acqusition-system?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + sql: + init: + mode: never + mvc: + pathmatch: + matching-strategy: ant_path_matcher +mybatis-plus: + mapper-locations: classpath*:com/unionbigdata/teaching/mapper/xml/*.xml + global-config: + db-config: + id-type: auto + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + +springdoc: + swagger-ui: + path: /swagger-ui.html + tags-sorter: alpha + operations-sorter: alpha + api-docs: + path: /v3/api-docs + group-configs: + - group: 'default' + paths-to-match: '/**' + packages-to-scan: com.unionbigdata.teaching + override-with-generic-response: false +# knife4j的增强配置,不需要增强可以不配 +knife4j: + enable: true + setting: + language: zh_cn + +sa-token: + # token 名称(前端/调用方需要放到 header 里) + token-name: x-token-id + # token 有效期(秒),30天 + timeout: 2592000 + # 临时有效期(活跃超时),-1 表示不限制 + active-timeout: -1 + # 允许同账号多端登录 + is-concurrent: true + # 多端登录共享同一个 token + is-share: true + # token 风格 + token-style: uuid + # 日志 + is-log: true \ No newline at end of file diff --git a/data-acqusition-system_VL/backend/src/main/resources/ddl.sql b/data-acqusition-system_VL/backend/src/main/resources/ddl.sql new file mode 100644 index 0000000000000000000000000000000000000000..6a9456cd31557f4d110c9c0a9ba547e5e13f8ca8 --- /dev/null +++ b/data-acqusition-system_VL/backend/src/main/resources/ddl.sql @@ -0,0 +1,15 @@ +CREATE DATABASE IF NOT EXISTS `data-acqusition-system` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; + +-- demo表,可删除 +create table user +( + id bigint auto_increment + primary key, + user_name varchar(50) null comment '用户名', + name varchar(50) null comment '名称', + age int null comment '年龄', + gender int null comment '性别', + password varchar(100) default '123456' null comment '密码' +) + comment '用户信息表' charset = utf8mb4; + diff --git "a/data-acqusition-system_VL/document/Java \345\267\245\345\205\267\345\256\211\350\243\205.docx" "b/data-acqusition-system_VL/document/Java \345\267\245\345\205\267\345\256\211\350\243\205.docx" new file mode 100644 index 0000000000000000000000000000000000000000..0b9e338d17f0756a922b7e07d998c73969b86a74 Binary files /dev/null and "b/data-acqusition-system_VL/document/Java \345\267\245\345\205\267\345\256\211\350\243\205.docx" differ diff --git "a/data-acqusition-system_VL/document/\345\211\215\347\253\257\347\216\257\345\242\203\346\220\255\345\273\272.docx" "b/data-acqusition-system_VL/document/\345\211\215\347\253\257\347\216\257\345\242\203\346\220\255\345\273\272.docx" new file mode 100644 index 0000000000000000000000000000000000000000..eec72b43fb9b682e766403833c11ed46bdc6ecb7 Binary files /dev/null and "b/data-acqusition-system_VL/document/\345\211\215\347\253\257\347\216\257\345\242\203\346\220\255\345\273\272.docx" differ diff --git "a/data-acqusition-system_VL/document/\346\225\260\346\215\256\351\207\207\351\233\206\347\263\273\347\273\237_0104.pptx" "b/data-acqusition-system_VL/document/\346\225\260\346\215\256\351\207\207\351\233\206\347\263\273\347\273\237_0104.pptx" new file mode 100644 index 0000000000000000000000000000000000000000..2f76c2e976cc77cbf3fc63257bf632c026a7ad34 Binary files /dev/null and "b/data-acqusition-system_VL/document/\346\225\260\346\215\256\351\207\207\351\233\206\347\263\273\347\273\237_0104.pptx" differ diff --git "a/data-acqusition-system_VL/document/\350\241\245\345\205\205\351\207\207\351\233\206\347\263\273\347\273\237.rp" "b/data-acqusition-system_VL/document/\350\241\245\345\205\205\351\207\207\351\233\206\347\263\273\347\273\237.rp" new file mode 100644 index 0000000000000000000000000000000000000000..de567bed9dd2c29ace5ec57b28e3458dd98b58ae Binary files /dev/null and "b/data-acqusition-system_VL/document/\350\241\245\345\205\205\351\207\207\351\233\206\347\263\273\347\273\237.rp" differ diff --git "a/data-acqusition-system_VL/document/\350\241\245\345\205\205\351\207\207\351\233\206\347\263\273\347\273\237\345\216\237\345\236\213\345\233\276.zip" "b/data-acqusition-system_VL/document/\350\241\245\345\205\205\351\207\207\351\233\206\347\263\273\347\273\237\345\216\237\345\236\213\345\233\276.zip" new file mode 100644 index 0000000000000000000000000000000000000000..beef259ed1c106aa15dc0d735a627062c51b2015 Binary files /dev/null and "b/data-acqusition-system_VL/document/\350\241\245\345\205\205\351\207\207\351\233\206\347\263\273\347\273\237\345\216\237\345\236\213\345\233\276.zip" differ diff --git a/frontend/web-management-react/.gitignore b/data-acqusition-system_VL/frontend/web-management-react/.gitignore similarity index 100% rename from frontend/web-management-react/.gitignore rename to data-acqusition-system_VL/frontend/web-management-react/.gitignore diff --git a/frontend/web-management-react/README.md b/data-acqusition-system_VL/frontend/web-management-react/README.md similarity index 100% rename from frontend/web-management-react/README.md rename to data-acqusition-system_VL/frontend/web-management-react/README.md diff --git a/frontend/web-management-react/config/env.js b/data-acqusition-system_VL/frontend/web-management-react/config/env.js similarity index 100% rename from frontend/web-management-react/config/env.js rename to data-acqusition-system_VL/frontend/web-management-react/config/env.js diff --git a/frontend/web-management-react/config/getHttpsConfig.js b/data-acqusition-system_VL/frontend/web-management-react/config/getHttpsConfig.js similarity index 100% rename from frontend/web-management-react/config/getHttpsConfig.js rename to data-acqusition-system_VL/frontend/web-management-react/config/getHttpsConfig.js diff --git a/frontend/web-management-react/config/jest/babelTransform.js b/data-acqusition-system_VL/frontend/web-management-react/config/jest/babelTransform.js similarity index 100% rename from frontend/web-management-react/config/jest/babelTransform.js rename to data-acqusition-system_VL/frontend/web-management-react/config/jest/babelTransform.js diff --git a/frontend/web-management-react/config/jest/cssTransform.js b/data-acqusition-system_VL/frontend/web-management-react/config/jest/cssTransform.js similarity index 100% rename from frontend/web-management-react/config/jest/cssTransform.js rename to data-acqusition-system_VL/frontend/web-management-react/config/jest/cssTransform.js diff --git a/frontend/web-management-react/config/jest/fileTransform.js b/data-acqusition-system_VL/frontend/web-management-react/config/jest/fileTransform.js similarity index 100% rename from frontend/web-management-react/config/jest/fileTransform.js rename to data-acqusition-system_VL/frontend/web-management-react/config/jest/fileTransform.js diff --git a/frontend/web-management-react/config/modules.js b/data-acqusition-system_VL/frontend/web-management-react/config/modules.js similarity index 100% rename from frontend/web-management-react/config/modules.js rename to data-acqusition-system_VL/frontend/web-management-react/config/modules.js diff --git a/frontend/web-management-react/config/paths.js b/data-acqusition-system_VL/frontend/web-management-react/config/paths.js similarity index 100% rename from frontend/web-management-react/config/paths.js rename to data-acqusition-system_VL/frontend/web-management-react/config/paths.js diff --git a/frontend/web-management-react/config/webpack.config.js b/data-acqusition-system_VL/frontend/web-management-react/config/webpack.config.js similarity index 100% rename from frontend/web-management-react/config/webpack.config.js rename to data-acqusition-system_VL/frontend/web-management-react/config/webpack.config.js diff --git a/frontend/web-management-react/config/webpack/persistentCache/createEnvironmentHash.js b/data-acqusition-system_VL/frontend/web-management-react/config/webpack/persistentCache/createEnvironmentHash.js similarity index 100% rename from frontend/web-management-react/config/webpack/persistentCache/createEnvironmentHash.js rename to data-acqusition-system_VL/frontend/web-management-react/config/webpack/persistentCache/createEnvironmentHash.js diff --git a/frontend/web-management-react/config/webpackDevServer.config.js b/data-acqusition-system_VL/frontend/web-management-react/config/webpackDevServer.config.js similarity index 100% rename from frontend/web-management-react/config/webpackDevServer.config.js rename to data-acqusition-system_VL/frontend/web-management-react/config/webpackDevServer.config.js diff --git a/frontend/web-management-react/package-lock.json b/data-acqusition-system_VL/frontend/web-management-react/package-lock.json similarity index 100% rename from frontend/web-management-react/package-lock.json rename to data-acqusition-system_VL/frontend/web-management-react/package-lock.json diff --git a/frontend/web-management-react/package.json b/data-acqusition-system_VL/frontend/web-management-react/package.json similarity index 100% rename from frontend/web-management-react/package.json rename to data-acqusition-system_VL/frontend/web-management-react/package.json diff --git a/frontend/web-management-react/public/favicon.ico b/data-acqusition-system_VL/frontend/web-management-react/public/favicon.ico similarity index 100% rename from frontend/web-management-react/public/favicon.ico rename to data-acqusition-system_VL/frontend/web-management-react/public/favicon.ico diff --git a/frontend/web-management-react/public/index.html b/data-acqusition-system_VL/frontend/web-management-react/public/index.html similarity index 100% rename from frontend/web-management-react/public/index.html rename to data-acqusition-system_VL/frontend/web-management-react/public/index.html diff --git a/frontend/web-management-react/public/logo192.png b/data-acqusition-system_VL/frontend/web-management-react/public/logo192.png similarity index 100% rename from frontend/web-management-react/public/logo192.png rename to data-acqusition-system_VL/frontend/web-management-react/public/logo192.png diff --git a/frontend/web-management-react/public/logo512.png b/data-acqusition-system_VL/frontend/web-management-react/public/logo512.png similarity index 100% rename from frontend/web-management-react/public/logo512.png rename to data-acqusition-system_VL/frontend/web-management-react/public/logo512.png diff --git a/frontend/web-management-react/public/manifest.json b/data-acqusition-system_VL/frontend/web-management-react/public/manifest.json similarity index 100% rename from frontend/web-management-react/public/manifest.json rename to data-acqusition-system_VL/frontend/web-management-react/public/manifest.json diff --git a/frontend/web-management-react/public/robots.txt b/data-acqusition-system_VL/frontend/web-management-react/public/robots.txt similarity index 100% rename from frontend/web-management-react/public/robots.txt rename to data-acqusition-system_VL/frontend/web-management-react/public/robots.txt diff --git a/frontend/web-management-react/scripts/build.js b/data-acqusition-system_VL/frontend/web-management-react/scripts/build.js similarity index 100% rename from frontend/web-management-react/scripts/build.js rename to data-acqusition-system_VL/frontend/web-management-react/scripts/build.js diff --git a/frontend/web-management-react/scripts/start.js b/data-acqusition-system_VL/frontend/web-management-react/scripts/start.js similarity index 100% rename from frontend/web-management-react/scripts/start.js rename to data-acqusition-system_VL/frontend/web-management-react/scripts/start.js diff --git a/frontend/web-management-react/scripts/test.js b/data-acqusition-system_VL/frontend/web-management-react/scripts/test.js similarity index 100% rename from frontend/web-management-react/scripts/test.js rename to data-acqusition-system_VL/frontend/web-management-react/scripts/test.js diff --git a/frontend/web-management-react/src/App.css b/data-acqusition-system_VL/frontend/web-management-react/src/App.css similarity index 100% rename from frontend/web-management-react/src/App.css rename to data-acqusition-system_VL/frontend/web-management-react/src/App.css diff --git a/frontend/web-management-react/src/App.js b/data-acqusition-system_VL/frontend/web-management-react/src/App.js similarity index 100% rename from frontend/web-management-react/src/App.js rename to data-acqusition-system_VL/frontend/web-management-react/src/App.js diff --git a/frontend/web-management-react/src/App.test.js b/data-acqusition-system_VL/frontend/web-management-react/src/App.test.js similarity index 100% rename from frontend/web-management-react/src/App.test.js rename to data-acqusition-system_VL/frontend/web-management-react/src/App.test.js diff --git a/frontend/web-management-react/src/index.css b/data-acqusition-system_VL/frontend/web-management-react/src/index.css similarity index 100% rename from frontend/web-management-react/src/index.css rename to data-acqusition-system_VL/frontend/web-management-react/src/index.css diff --git a/frontend/web-management-react/src/index.js b/data-acqusition-system_VL/frontend/web-management-react/src/index.js similarity index 100% rename from frontend/web-management-react/src/index.js rename to data-acqusition-system_VL/frontend/web-management-react/src/index.js diff --git a/frontend/web-management-react/src/logo.svg b/data-acqusition-system_VL/frontend/web-management-react/src/logo.svg similarity index 100% rename from frontend/web-management-react/src/logo.svg rename to data-acqusition-system_VL/frontend/web-management-react/src/logo.svg diff --git a/frontend/web-management-react/src/reportWebVitals.js b/data-acqusition-system_VL/frontend/web-management-react/src/reportWebVitals.js similarity index 100% rename from frontend/web-management-react/src/reportWebVitals.js rename to data-acqusition-system_VL/frontend/web-management-react/src/reportWebVitals.js diff --git a/frontend/web-management-react/src/router/data.js b/data-acqusition-system_VL/frontend/web-management-react/src/router/data.js similarity index 100% rename from frontend/web-management-react/src/router/data.js rename to data-acqusition-system_VL/frontend/web-management-react/src/router/data.js diff --git a/frontend/web-management-react/src/router/index.jsx b/data-acqusition-system_VL/frontend/web-management-react/src/router/index.jsx similarity index 100% rename from frontend/web-management-react/src/router/index.jsx rename to data-acqusition-system_VL/frontend/web-management-react/src/router/index.jsx diff --git a/frontend/web-management-react/src/service/index.js b/data-acqusition-system_VL/frontend/web-management-react/src/service/index.js similarity index 100% rename from frontend/web-management-react/src/service/index.js rename to data-acqusition-system_VL/frontend/web-management-react/src/service/index.js diff --git a/frontend/web-management-react/src/service/test.js b/data-acqusition-system_VL/frontend/web-management-react/src/service/test.js similarity index 100% rename from frontend/web-management-react/src/service/test.js rename to data-acqusition-system_VL/frontend/web-management-react/src/service/test.js diff --git a/frontend/web-management-react/src/setupProxy.js b/data-acqusition-system_VL/frontend/web-management-react/src/setupProxy.js similarity index 100% rename from frontend/web-management-react/src/setupProxy.js rename to data-acqusition-system_VL/frontend/web-management-react/src/setupProxy.js diff --git a/frontend/web-management-react/src/setupTests.js b/data-acqusition-system_VL/frontend/web-management-react/src/setupTests.js similarity index 100% rename from frontend/web-management-react/src/setupTests.js rename to data-acqusition-system_VL/frontend/web-management-react/src/setupTests.js diff --git a/frontend/web-management-react/src/utils/index.js b/data-acqusition-system_VL/frontend/web-management-react/src/utils/index.js similarity index 100% rename from frontend/web-management-react/src/utils/index.js rename to data-acqusition-system_VL/frontend/web-management-react/src/utils/index.js diff --git a/frontend/web-management-react/src/views/test/index.jsx b/data-acqusition-system_VL/frontend/web-management-react/src/views/test/index.jsx similarity index 100% rename from frontend/web-management-react/src/views/test/index.jsx rename to data-acqusition-system_VL/frontend/web-management-react/src/views/test/index.jsx diff --git a/frontend/web-management-react/src/views/test/index.scss b/data-acqusition-system_VL/frontend/web-management-react/src/views/test/index.scss similarity index 100% rename from frontend/web-management-react/src/views/test/index.scss rename to data-acqusition-system_VL/frontend/web-management-react/src/views/test/index.scss diff --git a/data-acqusition-system_VL/frontend/web-management-react/src/views/test1/index.css b/data-acqusition-system_VL/frontend/web-management-react/src/views/test1/index.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/frontend/web-management-react/src/views/test1/index.jsx b/data-acqusition-system_VL/frontend/web-management-react/src/views/test1/index.jsx similarity index 100% rename from frontend/web-management-react/src/views/test1/index.jsx rename to data-acqusition-system_VL/frontend/web-management-react/src/views/test1/index.jsx diff --git a/frontend/web-management-vue2/.eslintrc.js b/data-acqusition-system_VL/frontend/web-management-vue2/.eslintrc.js similarity index 100% rename from frontend/web-management-vue2/.eslintrc.js rename to data-acqusition-system_VL/frontend/web-management-vue2/.eslintrc.js diff --git a/frontend/web-management-vue2/.gitignore b/data-acqusition-system_VL/frontend/web-management-vue2/.gitignore similarity index 100% rename from frontend/web-management-vue2/.gitignore rename to data-acqusition-system_VL/frontend/web-management-vue2/.gitignore diff --git a/frontend/web-management-vue2/README.md b/data-acqusition-system_VL/frontend/web-management-vue2/README.md similarity index 100% rename from frontend/web-management-vue2/README.md rename to data-acqusition-system_VL/frontend/web-management-vue2/README.md diff --git a/frontend/web-management-vue2/babel.config.js b/data-acqusition-system_VL/frontend/web-management-vue2/babel.config.js similarity index 100% rename from frontend/web-management-vue2/babel.config.js rename to data-acqusition-system_VL/frontend/web-management-vue2/babel.config.js diff --git a/frontend/web-management-vue2/package-lock.json b/data-acqusition-system_VL/frontend/web-management-vue2/package-lock.json similarity index 100% rename from frontend/web-management-vue2/package-lock.json rename to data-acqusition-system_VL/frontend/web-management-vue2/package-lock.json diff --git a/frontend/web-management-vue2/package.json b/data-acqusition-system_VL/frontend/web-management-vue2/package.json similarity index 100% rename from frontend/web-management-vue2/package.json rename to data-acqusition-system_VL/frontend/web-management-vue2/package.json diff --git a/frontend/web-management-vue2/pnpm-lock.yaml b/data-acqusition-system_VL/frontend/web-management-vue2/pnpm-lock.yaml similarity index 100% rename from frontend/web-management-vue2/pnpm-lock.yaml rename to data-acqusition-system_VL/frontend/web-management-vue2/pnpm-lock.yaml diff --git a/frontend/web-management-vue2/public/favicon.ico b/data-acqusition-system_VL/frontend/web-management-vue2/public/favicon.ico similarity index 100% rename from frontend/web-management-vue2/public/favicon.ico rename to data-acqusition-system_VL/frontend/web-management-vue2/public/favicon.ico diff --git a/frontend/web-management-vue2/public/index.html b/data-acqusition-system_VL/frontend/web-management-vue2/public/index.html similarity index 100% rename from frontend/web-management-vue2/public/index.html rename to data-acqusition-system_VL/frontend/web-management-vue2/public/index.html diff --git a/frontend/web-management-vue2/src/App.vue b/data-acqusition-system_VL/frontend/web-management-vue2/src/App.vue similarity index 100% rename from frontend/web-management-vue2/src/App.vue rename to data-acqusition-system_VL/frontend/web-management-vue2/src/App.vue diff --git a/frontend/web-management-vue2/src/assets/logo.png b/data-acqusition-system_VL/frontend/web-management-vue2/src/assets/logo.png similarity index 100% rename from frontend/web-management-vue2/src/assets/logo.png rename to data-acqusition-system_VL/frontend/web-management-vue2/src/assets/logo.png diff --git a/frontend/web-management-vue2/src/components/HelloWorld.vue b/data-acqusition-system_VL/frontend/web-management-vue2/src/components/HelloWorld.vue similarity index 100% rename from frontend/web-management-vue2/src/components/HelloWorld.vue rename to data-acqusition-system_VL/frontend/web-management-vue2/src/components/HelloWorld.vue diff --git a/frontend/web-management-vue2/src/main.js b/data-acqusition-system_VL/frontend/web-management-vue2/src/main.js similarity index 100% rename from frontend/web-management-vue2/src/main.js rename to data-acqusition-system_VL/frontend/web-management-vue2/src/main.js diff --git a/frontend/web-management-vue2/src/router/index.js b/data-acqusition-system_VL/frontend/web-management-vue2/src/router/index.js similarity index 100% rename from frontend/web-management-vue2/src/router/index.js rename to data-acqusition-system_VL/frontend/web-management-vue2/src/router/index.js diff --git a/frontend/web-management-vue2/src/service/index.js b/data-acqusition-system_VL/frontend/web-management-vue2/src/service/index.js similarity index 100% rename from frontend/web-management-vue2/src/service/index.js rename to data-acqusition-system_VL/frontend/web-management-vue2/src/service/index.js diff --git a/frontend/web-management-vue2/src/views/main/index.vue b/data-acqusition-system_VL/frontend/web-management-vue2/src/views/main/index.vue similarity index 100% rename from frontend/web-management-vue2/src/views/main/index.vue rename to data-acqusition-system_VL/frontend/web-management-vue2/src/views/main/index.vue diff --git a/frontend/web-management-vue2/src/views/test/index.vue b/data-acqusition-system_VL/frontend/web-management-vue2/src/views/test/index.vue similarity index 100% rename from frontend/web-management-vue2/src/views/test/index.vue rename to data-acqusition-system_VL/frontend/web-management-vue2/src/views/test/index.vue diff --git a/frontend/web-management-vue2/vue.config.js b/data-acqusition-system_VL/frontend/web-management-vue2/vue.config.js similarity index 100% rename from frontend/web-management-vue2/vue.config.js rename to data-acqusition-system_VL/frontend/web-management-vue2/vue.config.js diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/. oxlintrc.json b/data-acqusition-system_VL/frontend/web-management-vue3/. oxlintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..d5648b966b8aac1b0a3b0952c96b4e816c088b4c --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/. oxlintrc.json @@ -0,0 +1,10 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["eslint", "typescript", "unicorn", "oxc", "vue"], + "env": { + "browser": true + }, + "categories": { + "correctness": "error" + } +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/.editorconfig b/data-acqusition-system_VL/frontend/web-management-vue3/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..3b510aa687ba5d3dbaec1b9c6989327f84261a21 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/.editorconfig @@ -0,0 +1,8 @@ +[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}] +charset = utf-8 +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +max_line_length = 100 diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/.gitattributes b/data-acqusition-system_VL/frontend/web-management-vue3/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..6313b56c57848efce05faa7aa7e901ccfc2886ea --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/.gitignore b/data-acqusition-system_VL/frontend/web-management-vue3/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a3f7a5198f61d98256615940610af798e85aba0b --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/.gitignore @@ -0,0 +1,36 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo + +.eslintcache + +# Cypress +/cypress/videos/ +/cypress/screenshots/ + +# Vitest +__screenshots__/ diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/.prettierrc.json b/data-acqusition-system_VL/frontend/web-management-vue3/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..29a2402ef050746efe041b9e3393bf33796407c3 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "semi": false, + "singleQuote": true, + "printWidth": 100 +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/README.md b/data-acqusition-system_VL/frontend/web-management-vue3/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2f103fb2c187603d9b2f45dbbdc736435110592d --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/README.md @@ -0,0 +1,45 @@ +vue3前端框架 +node 版本建议 20.19.0 || >=22.12.0 + +# web-management-vue3 + +This template should help get you started developing with Vue 3 in Vite. + +## 推荐 IDE 设置 + +[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## 推荐浏览器设置 + +- Chromium-based browsers (Chrome, Edge, Brave, etc.): + - [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd) + - [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters) +- Firefox: + - [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/) + - [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/) + +## 在 TypeScript 中对 .vue 导入的类型支持 +默认情况下,TypeScript 无法处理 .vue 导入的类型信息,因此我们用 vue-tsc 替换 tsc CLI 进行类型检查。在编辑器中,我们需要 Volar 来使 TypeScript 语言服务识别 .vue 文件的类型。 + + +## 自定义配置 + +See [Vite Configuration Reference](https://vite.dev/config/). + +## 项目启动 + +```sh +npm install +``` + +### 为开发环境进行编译和热重载 + +```sh +npm run dev +``` + +### 打包 + +```sh +npm run build +``` diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/env.d.ts b/data-acqusition-system_VL/frontend/web-management-vue3/env.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..11f02fe2a0061d6e6e1f271b21da95423b448b32 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/eslint.config.ts b/data-acqusition-system_VL/frontend/web-management-vue3/eslint.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..e079f4e1defbf1d0c993a02b117c8de1dbf92f97 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/eslint.config.ts @@ -0,0 +1,32 @@ +import { globalIgnores } from 'eslint/config' +import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript' +import pluginVue from 'eslint-plugin-vue' +import pluginVitest from '@vitest/eslint-plugin' +import skipFormatting from '@vue/eslint-config-prettier/skip-formatting' +import pluginOxlint from 'eslint-plugin-oxlint' + +// To allow more languages other than `ts` in `.vue` files, uncomment the following lines: +// import { configureVueProject } from '@vue/eslint-config-typescript' +// configureVueProject({ scriptLangs: ['ts', 'tsx'] }) +// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup + +export default defineConfigWithVueTs( + { + name: 'app/files-to-lint', + files: ['**/*.{vue,ts,mts,tsx}'], + }, + + globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), + + ...pluginVue.configs['flat/essential'], + vueTsConfigs.recommended, + + { + ...pluginVitest.configs.recommended, + files: ['src/**/__tests__/*'], + }, + + skipFormatting, + + ...pluginOxlint.configs['flat/recommended'], +) diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/index.html b/data-acqusition-system_VL/frontend/web-management-vue3/index.html new file mode 100644 index 0000000000000000000000000000000000000000..9e5fc8f06c69dd7697ad566f198ae6577fdc15b2 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite App + + +
+ + + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/package-lock.json b/data-acqusition-system_VL/frontend/web-management-vue3/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..86d964e8017a199d88ddae15bdd6f51a488de0e8 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/package-lock.json @@ -0,0 +1,6769 @@ +{ + "name": "web-management-vue3", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "web-management-vue3", + "version": "0.0.0", + "dependencies": { + "element-plus": "^2.13.0", + "pinia": "^3.0.4", + "vue": "^3.5.26", + "vue-router": "^4.6.4" + }, + "devDependencies": { + "@tsconfig/node24": "^24.0.3", + "@types/jsdom": "^27.0.0", + "@types/node": "^24.10.4", + "@vitejs/plugin-vue": "^6.0.3", + "@vitejs/plugin-vue-jsx": "^5.1.3", + "@vitest/eslint-plugin": "^1.6.4", + "@vue/eslint-config-prettier": "^10.2.0", + "@vue/eslint-config-typescript": "^14.6.0", + "@vue/test-utils": "^2.4.6", + "@vue/tsconfig": "^0.8.1", + "eslint": "^9.39.2", + "eslint-plugin-oxlint": "~1.35.0", + "eslint-plugin-vue": "~10.6.2", + "jiti": "^2.6.1", + "jsdom": "^27.3.0", + "npm-run-all2": "^8.0.4", + "oxlint": "~1.35.0", + "prettier": "3.7.4", + "typescript": "~5.9.3", + "vite": "npm:rolldown-vite@latest", + "vite-plugin-vue-devtools": "^8.0.5", + "vitest": "^4.0.16", + "vue-tsc": "^3.2.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.30", + "resolved": "https://registry.npmmirror.com/@acemir/cssom/-/cssom-0.9.30.tgz", + "integrity": "sha512-9CnlMCI0LmCIq0olalQqdWrJHPzm0/tw3gzOA9zJSgvFX7Xau3D24mAGa4BtwxwY69nsuJW6kQqqCzf/mEcQgg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", + "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.2.4" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.7.6", + "resolved": "https://registry.npmmirror.com/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz", + "integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.4" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmmirror.com/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@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.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.28.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", + "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-decorators": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", + "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.22", + "resolved": "https://registry.npmmirror.com/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.22.tgz", + "integrity": "sha512-qBcx6zYlhleiFfdtzkRgwNC7VVoAwfK76Vmsw5t+PbvtdknO9StgRk7ROvq9so1iqbdW4uLIDAsXRsTfUrIoOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz", + "integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.7.1", + "resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmmirror.com/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmmirror.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmmirror.com/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmmirror.com/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/@exodus/bytes/-/bytes-1.7.0.tgz", + "integrity": "sha512-5i+BtvujK/vM07YCGDyz4C4AyDzLmhxHMtM5HpUyPRtJPBdFPsj290ffXW+UXY21/G7GtXeHD2nRmq0T1ShyQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@exodus/crypto": "^1.0.0-rc.4" + }, + "peerDependenciesMeta": { + "@exodus/crypto": { + "optional": true + } + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmmirror.com/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmmirror.com/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz", + "integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@oxc-project/runtime": { + "version": "0.101.0", + "resolved": "https://registry.npmmirror.com/@oxc-project/runtime/-/runtime-0.101.0.tgz", + "integrity": "sha512-t3qpfVZIqSiLQ5Kqt/MC4Ge/WCOGrrcagAdzTcDaggupjiGxUx4nJF2v6wUCXWSzWHn5Ns7XLv13fCJEwCOERQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.101.0", + "resolved": "https://registry.npmmirror.com/@oxc-project/types/-/types-0.101.0.tgz", + "integrity": "sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@oxlint/darwin-arm64": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/darwin-arm64/-/darwin-arm64-1.35.0.tgz", + "integrity": "sha512-ieiYVHkNZPo77Hgrxav595wGS4rRNKuDNrljf+4xhwpJsddrxMpM64IQUf2IvR3MhK4FxdGzhhB6OVmGVHY5/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/darwin-x64": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/darwin-x64/-/darwin-x64-1.35.0.tgz", + "integrity": "sha512-1jNHu3j66X5jKySvgtE+jGtjx4ye+xioAucVTi2IuROZO6keK2YG74pnD+9FT+DpWZAtWRZGoW0r0x6aN9sEEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/linux-arm64-gnu": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-1.35.0.tgz", + "integrity": "sha512-T1lc0UaYbTxZyqVpLfC7eipbauNG8pBpkaZEW4JGz8Y68rxTH7d9s+CF0zxUxNr5RCtcmT669RLVjQT7VrKVLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-arm64-musl": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/linux-arm64-musl/-/linux-arm64-musl-1.35.0.tgz", + "integrity": "sha512-7Wv5Pke9kwWKFycUziSHsmi3EM0389TLzraB0KE/MArrKxx30ycwfJ5PYoMj9ERoW+Ybs0txdaOF/xJy/XyYkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-gnu": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/linux-x64-gnu/-/linux-x64-gnu-1.35.0.tgz", + "integrity": "sha512-HDMPOzyVVy+rQl3H7UOq8oGHt7m1yaiWCanlhAu4jciK8dvXeO9OG/OQd74lD/h05IcJh93pCLEJ3wWOG8hTiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-musl": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/linux-x64-musl/-/linux-x64-musl-1.35.0.tgz", + "integrity": "sha512-kAPBBsUOM3HQQ6n3nnZauvFR9EoXqCSoj4O3OSXXarzsRTiItNrHabVUwxeswZEc+xMzQNR0FHEWg/d4QAAWLw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/win32-arm64": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/win32-arm64/-/win32-arm64-1.35.0.tgz", + "integrity": "sha512-qrpBkkOASS0WT8ra9xmBRXOEliN6D/MV9JhI/68lFHrtLhfFuRwg4AjzjxrCWrQCnQ0WkvAVpJzu73F4ICLYZw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint/win32-x64": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/@oxlint/win32-x64/-/win32-x64-1.35.0.tgz", + "integrity": "sha512-yPFcj6umrhusnG/kMS5wh96vblsqZ0kArQJS+7kEOSJDrH+DsFWaDCsSRF8U6gmSmZJ26KVMU3C3TMpqDN4M1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmmirror.com/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.53.tgz", + "integrity": "sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.53.tgz", + "integrity": "sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.53.tgz", + "integrity": "sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.53.tgz", + "integrity": "sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.53.tgz", + "integrity": "sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.53.tgz", + "integrity": "sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.53.tgz", + "integrity": "sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.53.tgz", + "integrity": "sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.53.tgz", + "integrity": "sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.53.tgz", + "integrity": "sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.53.tgz", + "integrity": "sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.53.tgz", + "integrity": "sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.53.tgz", + "integrity": "sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", + "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node24": { + "version": "24.0.3", + "resolved": "https://registry.npmmirror.com/@tsconfig/node24/-/node24-24.0.3.tgz", + "integrity": "sha512-vcERKtKQKHgzt/vfS3Gjasd8SUI2a0WZXpgJURdJsMySpS5+ctgbPfuLj2z/W+w4lAfTWxoN4upKfu2WzIRYnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmmirror.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmmirror.com/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsdom": { + "version": "27.0.0", + "resolved": "https://registry.npmmirror.com/@types/jsdom/-/jsdom-27.0.0.tgz", + "integrity": "sha512-NZyFl/PViwKzdEkQg96gtnB8wm+1ljhdDay9ahn4hgb+SfVtPCbm3TlmDUFXTA+MGN3CijicnMhG18SI5H3rFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "24.10.4", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.10.4.tgz", + "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.1.tgz", + "integrity": "sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.50.1", + "@typescript-eslint/type-utils": "8.50.1", + "@typescript-eslint/utils": "8.50.1", + "@typescript-eslint/visitor-keys": "8.50.1", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.50.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-8.50.1.tgz", + "integrity": "sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.50.1", + "@typescript-eslint/types": "8.50.1", + "@typescript-eslint/typescript-estree": "8.50.1", + "@typescript-eslint/visitor-keys": "8.50.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/project-service/-/project-service-8.50.1.tgz", + "integrity": "sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.50.1", + "@typescript-eslint/types": "^8.50.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-8.50.1.tgz", + "integrity": "sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.1", + "@typescript-eslint/visitor-keys": "8.50.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.1.tgz", + "integrity": "sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-8.50.1.tgz", + "integrity": "sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.1", + "@typescript-eslint/typescript-estree": "8.50.1", + "@typescript-eslint/utils": "8.50.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-8.50.1.tgz", + "integrity": "sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.1.tgz", + "integrity": "sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.1", + "@typescript-eslint/tsconfig-utils": "8.50.1", + "@typescript-eslint/types": "8.50.1", + "@typescript-eslint/visitor-keys": "8.50.1", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-8.50.1.tgz", + "integrity": "sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.50.1", + "@typescript-eslint/types": "8.50.1", + "@typescript-eslint/typescript-estree": "8.50.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.1.tgz", + "integrity": "sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz", + "integrity": "sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.53" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitejs/plugin-vue-jsx": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-5.1.3.tgz", + "integrity": "sha512-I6Zr8cYVr5WHMW5gNOP09DNqW9rgO8RX73Wa6Czgq/0ndpTfJM4vfDChfOT1+3KtdrNqilNBtNlFwVeB02ZzGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.5", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5", + "@rolldown/pluginutils": "^1.0.0-beta.56", + "@vue/babel-plugin-jsx": "^2.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", + "vue": "^3.0.0" + } + }, + "node_modules/@vitejs/plugin-vue-jsx/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.57.tgz", + "integrity": "sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/eslint-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmmirror.com/@vitest/eslint-plugin/-/eslint-plugin-1.6.4.tgz", + "integrity": "sha512-+qw32ux8HMVNrJnQOYgdjrMYmCn9vsiKnJUv5MoOg40e18WOvhWurzHdbRB3vXLfUrP7+jYyQbd6TuRhL23AkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "^8.46.1", + "@typescript-eslint/utils": "^8.46.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": ">=8.57.0", + "typescript": ">=5.0.0", + "vitest": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/expect/-/expect-4.0.16.tgz", + "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.0.16.tgz", + "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.16", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", + "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/runner/-/runner-4.0.16.tgz", + "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.16", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/snapshot/-/snapshot-4.0.16.tgz", + "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.16", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/spy/-/spy-4.0.16.tgz", + "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/@vitest/utils/-/utils-4.0.16.tgz", + "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.16", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.27", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.27.tgz", + "integrity": "sha512-DjmjBWZ4tJKxfNC1F6HyYERNHPYS7L7OPFyCrestykNdUZMFYzI9WTyvwPcaNaHlrEUwESHYsfEw3isInncZxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.27" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.27", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.27.tgz", + "integrity": "sha512-ynlcBReMgOZj2i6po+qVswtDUeeBRCTgDurjMGShbm8WYZgJ0PA4RmtebBJ0BCYol1qPv3GQF6jK7C9qoVc7lg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.27", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.27.tgz", + "integrity": "sha512-eWaYCcl/uAPInSK2Lze6IqVWaBu/itVqR5InXcHXFyles4zO++Mglt3oxdgj75BDcv1Knr9Y93nowS8U3wqhxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.27", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-2.0.1.tgz", + "integrity": "sha512-uZ66EaFbnnZSYqYEyplWvn46GhZ1KuYSThdT68p+am7MgBNbQ3hphTL9L+xSIsWkdktwhPYLwPgVWqo96jDdRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-2.0.1.tgz", + "integrity": "sha512-a8CaLQjD/s4PVdhrLD/zT574ZNPnZBOY+IhdtKWRB4HRZ0I2tXBi5ne7d9eCfaYwp5gU5+4KIyFTV1W1YL9xZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@vue/babel-helper-vue-transform-on": "2.0.1", + "@vue/babel-plugin-resolve-type": "2.0.1", + "@vue/shared": "^3.5.22" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-2.0.1.tgz", + "integrity": "sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/parser": "^7.28.4", + "@vue/compiler-sfc": "^3.5.22" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.26.tgz", + "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.26", + "entities": "^7.0.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", + "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.26", + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", + "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.26", + "@vue/compiler-dom": "3.5.26", + "@vue/compiler-ssr": "3.5.26", + "@vue/shared": "3.5.26", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", + "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.26", + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.9.tgz", + "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.9" + } + }, + "node_modules/@vue/devtools-core": { + "version": "8.0.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-core/-/devtools-core-8.0.5.tgz", + "integrity": "sha512-dpCw8nl0GDBuiL9SaY0mtDxoGIEmU38w+TQiYEPOLhW03VDC0lfNMYXS/qhl4I0YlysGp04NLY4UNn6xgD0VIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^8.0.5", + "@vue/devtools-shared": "^8.0.5", + "mitt": "^3.0.1", + "nanoid": "^5.1.5", + "pathe": "^2.0.3", + "vite-hot-client": "^2.1.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-core/node_modules/@vue/devtools-kit": { + "version": "8.0.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-8.0.5.tgz", + "integrity": "sha512-q2VV6x1U3KJMTQPUlRMyWEKVbcHuxhqJdSr6Jtjz5uAThAIrfJ6WVZdGZm5cuO63ZnSUz0RCsVwiUUb0mDV0Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^8.0.5", + "birpc": "^2.6.1", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^2.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-core/node_modules/@vue/devtools-shared": { + "version": "8.0.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-8.0.5.tgz", + "integrity": "sha512-bRLn6/spxpmgLk+iwOrR29KrYnJjG9DGpHGkDFG82UM21ZpJ39ztUT9OXX3g+usW7/b2z+h46I9ZiYyB07XMXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/devtools-core/node_modules/nanoid": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.1.6.tgz", + "integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@vue/devtools-core/node_modules/perfect-debounce": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-2.0.0.tgz", + "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", + "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.9", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.9", + "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", + "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/eslint-config-prettier": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/@vue/eslint-config-prettier/-/eslint-config-prettier-10.2.0.tgz", + "integrity": "sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.2" + }, + "peerDependencies": { + "eslint": ">= 8.21.0", + "prettier": ">= 3.0.0" + } + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "14.6.0", + "resolved": "https://registry.npmmirror.com/@vue/eslint-config-typescript/-/eslint-config-typescript-14.6.0.tgz", + "integrity": "sha512-UpiRY/7go4Yps4mYCjkvlIbVWmn9YvPGQDxTAlcKLphyaD77LjIu3plH4Y9zNT0GB4f3K5tMmhhtRhPOgrQ/bQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.35.1", + "fast-glob": "^3.3.3", + "typescript-eslint": "^8.35.1", + "vue-eslint-parser": "^10.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0", + "eslint-plugin-vue": "^9.28.0 || ^10.0.0", + "typescript": ">=4.8.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.2.1.tgz", + "integrity": "sha512-g6oSenpnGMtpxHGAwKuu7HJJkNZpemK/zg3vZzZbJ6cnnXq1ssxuNrXSsAHYM3NvH8p4IkTw+NLmuxyeYz4r8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.27", + "@vue/compiler-dom": "^3.5.0", + "@vue/shared": "^3.5.0", + "alien-signals": "^3.0.0", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1", + "picomatch": "^4.0.2" + } + }, + "node_modules/@vue/language-core/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/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/@vue/reactivity": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.26.tgz", + "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.26.tgz", + "integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.26", + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz", + "integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.26", + "@vue/runtime-core": "3.5.26", + "@vue/shared": "3.5.26", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.26.tgz", + "integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.26", + "@vue/shared": "3.5.26" + }, + "peerDependencies": { + "vue": "3.5.26" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.26", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.26.tgz", + "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", + "license": "MIT" + }, + "node_modules/@vue/test-utils": { + "version": "2.4.6", + "resolved": "https://registry.npmmirror.com/@vue/test-utils/-/test-utils-2.4.6.tgz", + "integrity": "sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-beautify": "^1.14.9", + "vue-component-type-helpers": "^2.0.0" + } + }, + "node_modules/@vue/tsconfig": { + "version": "0.8.1", + "resolved": "https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.8.1.tgz", + "integrity": "sha512-aK7feIWPXFSUhsCP9PFqPyFOcz4ENkb8hZ2pneL6m2UjCkccvaOhC/5KCKluuBufvp2KzkbdA2W2pk20vLzu3g==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": "5.x", + "vue": "^3.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/@vueuse/core": { + "version": "10.11.1", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-10.11.1.tgz", + "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.11.1", + "@vueuse/shared": "10.11.1", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/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/@vueuse/metadata": { + "version": "10.11.1", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.11.1.tgz", + "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.11.1", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-10.11.1.tgz", + "integrity": "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==", + "license": "MIT", + "dependencies": { + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/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/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/alien-signals": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-3.1.2.tgz", + "integrity": "sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansis": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/ansis/-/ansis-4.2.0.tgz", + "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.11", + "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", + "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/birpc": { + "version": "2.9.0", + "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.9.0.tgz", + "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/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/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001761", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmmirror.com/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-4.0.5.tgz", + "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", + "license": "MIT", + "dependencies": { + "is-what": "^5.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssstyle": { + "version": "5.3.5", + "resolved": "https://registry.npmmirror.com/cssstyle/-/cssstyle-5.3.5.tgz", + "integrity": "sha512-GlsEptulso7Jg0VaOZ8BXQi3AkYM5BOJKEO/rjMidSCq70FkIC5y0eawrCXeYzxgt3OCf4Ls+eoxN+/05vN0Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/data-urls/-/data-urls-6.0.0.tgz", + "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-5.4.0.tgz", + "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" + }, + "node_modules/element-plus": { + "version": "2.13.0", + "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.13.0.tgz", + "integrity": "sha512-qjxS+SBChvqCl6lU6ShiliLMN6WqFHiXQENYbAY3GKNflG+FS3jqn8JmQq0CBZq4koFqsi95NT1M6SL4whZfrA==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.2", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.17.20", + "@types/lodash-es": "^4.17.12", + "@vueuse/core": "^10.11.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.19", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.3", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.3.0" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.0.tgz", + "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmmirror.com/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-oxlint": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-oxlint/-/eslint-plugin-oxlint-1.35.0.tgz", + "integrity": "sha512-XTwAUJE41nxk8PS1Ed+IwIQy/PF2AYbm9Nn1jUKLm3yYcIQCpm2sbyXkK9Fna5V2ioSulBDy3C7ge3UCs4Y0Lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.3.1" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.4", + "resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vue": { + "version": "10.6.2", + "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-10.6.2.tgz", + "integrity": "sha512-nA5yUs/B1KmKzvC42fyD0+l9Yd+LtEpVhWRbXuDj0e+ZURcTtyRbMDWUeJmTAh2wC6jC83raS63anNM2YT3NPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^7.1.0", + "semver": "^7.6.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "@stylistic/eslint-plugin": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "vue-eslint-parser": "^10.0.0" + }, + "peerDependenciesMeta": { + "@stylistic/eslint-plugin": { + "optional": true + }, + "@typescript-eslint/parser": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vue/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmmirror.com/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/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/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-what": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/is-what/-/is-what-5.5.0.tgz", + "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-beautify": { + "version": "1.15.4", + "resolved": "https://registry.npmmirror.com/js-beautify/-/js-beautify-1.15.4.tgz", + "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.4", + "glob": "^10.4.2", + "js-cookie": "^3.0.5", + "nopt": "^7.2.1" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmmirror.com/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/jsdom/node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/jsdom/node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.22", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.22.tgz", + "integrity": "sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==", + "license": "MIT" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "license": "MIT", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmmirror.com/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/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmmirror.com/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/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.npmmirror.com/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/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmmirror.com/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", + "license": "BSD-3-Clause" + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-all2": { + "version": "8.0.4", + "resolved": "https://registry.npmmirror.com/npm-run-all2/-/npm-run-all2-8.0.4.tgz", + "integrity": "sha512-wdbB5My48XKp2ZfJUlhnLVihzeuA1hgBnqB2J9ahV77wLS+/YAJAlN8I+X3DIFIPZ3m5L7nplmlbhNiFDmXRDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "cross-spawn": "^7.0.6", + "memorystream": "^0.3.1", + "picomatch": "^4.0.2", + "pidtree": "^0.6.0", + "read-package-json-fast": "^4.0.0", + "shell-quote": "^1.7.3", + "which": "^5.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "npm-run-all2": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": "^20.5.0 || >=22.0.0", + "npm": ">= 10" + } + }, + "node_modules/npm-run-all2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm-run-all2/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm-run-all2/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/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/npm-run-all2/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmmirror.com/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/oxlint": { + "version": "1.35.0", + "resolved": "https://registry.npmmirror.com/oxlint/-/oxlint-1.35.0.tgz", + "integrity": "sha512-QDX1aUgaiqznkGfTM2qHwva2wtKqhVoqPSVXrnPz+yLUhlNadikD3QRuRtppHl7WGuy3wG6nKAuR8lash3aWSg==", + "dev": true, + "license": "MIT", + "bin": { + "oxc_language_server": "bin/oxc_language_server", + "oxlint": "bin/oxlint" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/darwin-arm64": "1.35.0", + "@oxlint/darwin-x64": "1.35.0", + "@oxlint/linux-arm64-gnu": "1.35.0", + "@oxlint/linux-arm64-musl": "1.35.0", + "@oxlint/linux-x64-gnu": "1.35.0", + "@oxlint/linux-x64-musl": "1.35.0", + "@oxlint/win32-arm64": "1.35.0", + "@oxlint/win32-x64": "1.35.0" + }, + "peerDependencies": { + "oxlint-tsgolint": ">=0.10.0" + }, + "peerDependenciesMeta": { + "oxlint-tsgolint": { + "optional": true + } + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pinia": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-3.0.4.tgz", + "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.7.7" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.5.0", + "vue": "^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.7.4", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, + "license": "ISC" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/read-package-json-fast": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", + "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmmirror.com/rolldown/-/rolldown-1.0.0-beta.53.tgz", + "integrity": "sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.101.0", + "@rolldown/pluginutils": "1.0.0-beta.53" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-beta.53", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.53", + "@rolldown/binding-darwin-x64": "1.0.0-beta.53", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.53", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.53", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.53", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.53", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.53", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.53", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.53", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.53", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.53", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.53" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/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/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmmirror.com/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmmirror.com/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superjson": { + "version": "2.2.6", + "resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.6.tgz", + "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", + "license": "MIT", + "dependencies": { + "copy-anything": "^4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmmirror.com/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmmirror.com/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmmirror.com/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/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/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/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/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/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.0.19", + "resolved": "https://registry.npmmirror.com/tldts/-/tldts-7.0.19.tgz", + "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.19" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.19", + "resolved": "https://registry.npmmirror.com/tldts-core/-/tldts-core-7.0.19.tgz", + "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/ts-api-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-2.3.0.tgz", + "integrity": "sha512-6eg3Y9SF7SsAvGzRHQvvc1skDAhwI4YQ32ui1scxD1Ccr0G5qIIbUBT3pFTKX8kmWIQClHobtUdNuaBgwdfdWg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.50.1", + "resolved": "https://registry.npmmirror.com/typescript-eslint/-/typescript-eslint-8.50.1.tgz", + "integrity": "sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.50.1", + "@typescript-eslint/parser": "8.50.1", + "@typescript-eslint/typescript-estree": "8.50.1", + "@typescript-eslint/utils": "8.50.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unplugin-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.3.1.tgz", + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "dev": true, + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-utils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/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/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "name": "rolldown-vite", + "version": "7.3.0", + "resolved": "https://registry.npmmirror.com/rolldown-vite/-/rolldown-vite-7.3.0.tgz", + "integrity": "sha512-5hI5NCJwKBGtzWtdKB3c2fOEpI77Iaa0z4mSzZPU1cJ/OqrGbFafm90edVCd7T9Snz+Sh09TMAv4EQqyVLzuEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/runtime": "0.101.0", + "fdir": "^6.5.0", + "lightningcss": "^1.30.2", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rolldown": "1.0.0-beta.53", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "esbuild": "^0.27.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "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/vite-dev-rpc": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", + "integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", + "dev": true, + "license": "MIT", + "dependencies": { + "birpc": "^2.4.0", + "vite-hot-client": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" + } + }, + "node_modules/vite-hot-client": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/vite-hot-client/-/vite-hot-client-2.1.0.tgz", + "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite-plugin-inspect": { + "version": "11.3.3", + "resolved": "https://registry.npmmirror.com/vite-plugin-inspect/-/vite-plugin-inspect-11.3.3.tgz", + "integrity": "sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansis": "^4.1.0", + "debug": "^4.4.1", + "error-stack-parser-es": "^1.0.5", + "ohash": "^2.0.11", + "open": "^10.2.0", + "perfect-debounce": "^2.0.0", + "sirv": "^3.0.1", + "unplugin-utils": "^0.3.0", + "vite-dev-rpc": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-inspect/node_modules/perfect-debounce": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-2.0.0.tgz", + "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-plugin-vue-devtools": { + "version": "8.0.5", + "resolved": "https://registry.npmmirror.com/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.0.5.tgz", + "integrity": "sha512-p619BlKFOqQXJ6uDWS1vUPQzuJOD6xJTfftj57JXBGoBD/yeQCowR7pnWcr/FEX4/HVkFbreI6w2uuGBmQOh6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-core": "^8.0.5", + "@vue/devtools-kit": "^8.0.5", + "@vue/devtools-shared": "^8.0.5", + "sirv": "^3.0.2", + "vite-plugin-inspect": "^11.3.3", + "vite-plugin-vue-inspector": "^5.3.2" + }, + "engines": { + "node": ">=v14.21.3" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0-0" + } + }, + "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-kit": { + "version": "8.0.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-8.0.5.tgz", + "integrity": "sha512-q2VV6x1U3KJMTQPUlRMyWEKVbcHuxhqJdSr6Jtjz5uAThAIrfJ6WVZdGZm5cuO63ZnSUz0RCsVwiUUb0mDV0Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^8.0.5", + "birpc": "^2.6.1", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^2.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-shared": { + "version": "8.0.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-8.0.5.tgz", + "integrity": "sha512-bRLn6/spxpmgLk+iwOrR29KrYnJjG9DGpHGkDFG82UM21ZpJ39ztUT9OXX3g+usW7/b2z+h46I9ZiYyB07XMXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/vite-plugin-vue-devtools/node_modules/perfect-debounce": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-2.0.0.tgz", + "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-plugin-vue-inspector": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.3.2.tgz", + "integrity": "sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/plugin-proposal-decorators": "^7.23.0", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.22.15", + "@vue/babel-plugin-jsx": "^1.1.5", + "@vue/compiler-dom": "^3.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.4" + }, + "peerDependencies": { + "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite-plugin-vue-inspector/node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz", + "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-plugin-vue-inspector/node_modules/@vue/babel-plugin-jsx": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz", + "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@vue/babel-helper-vue-transform-on": "1.5.0", + "@vue/babel-plugin-resolve-type": "1.5.0", + "@vue/shared": "^3.5.18" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/vite-plugin-vue-inspector/node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz", + "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/parser": "^7.28.0", + "@vue/compiler-sfc": "^3.5.18" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/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/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/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/vitest": { + "version": "4.0.16", + "resolved": "https://registry.npmmirror.com/vitest/-/vitest-4.0.16.tgz", + "integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.16", + "@vitest/mocker": "4.0.16", + "@vitest/pretty-format": "4.0.16", + "@vitest/runner": "4.0.16", + "@vitest/snapshot": "4.0.16", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.16", + "@vitest/browser-preview": "4.0.16", + "@vitest/browser-webdriverio": "4.0.16", + "@vitest/ui": "4.0.16", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/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/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/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.26", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.26.tgz", + "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.26", + "@vue/compiler-sfc": "3.5.26", + "@vue/runtime-dom": "3.5.26", + "@vue/server-renderer": "3.5.26", + "@vue/shared": "3.5.26" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-component-type-helpers": { + "version": "2.2.12", + "resolved": "https://registry.npmmirror.com/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz", + "integrity": "sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue-eslint-parser": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz", + "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.6.0", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vue-router": { + "version": "4.6.4", + "resolved": "https://registry.npmmirror.com/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-router/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/vue-tsc": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-3.2.1.tgz", + "integrity": "sha512-I23Rk8dkQfmcSbxDO0dmg9ioMLjKA1pjlU3Lz6Jfk2pMGu3Uryu9810XkcZH24IzPbhzPCnkKo2rEMRX0skSrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "2.4.27", + "@vue/language-core": "3.2.1" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-8.0.0.tgz", + "integrity": "sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/package.json b/data-acqusition-system_VL/frontend/web-management-vue3/package.json new file mode 100644 index 0000000000000000000000000000000000000000..17b78c38d979aaf3424764fe36534edeb39b8e58 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/package.json @@ -0,0 +1,52 @@ +{ + "name": "web-management-vue3", + "version": "0.0.0", + "private": true, + "type": "module", + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "scripts": { + "dev": "vite", + "build": "run-p type-check \"build-only {@}\" --", + "preview": "vite preview", + "test:unit": "vitest", + "build-only": "vite build", + "type-check": "vue-tsc --build", + "lint": "run-s lint:*", + "lint:oxlint": "oxlint . --fix", + "lint:eslint": "eslint . --fix --cache", + "format": "prettier --write --experimental-cli src/" + }, + "dependencies": { + "element-plus": "^2.13.0", + "pinia": "^3.0.4", + "vue": "^3.5.26", + "vue-router": "^4.6.4" + }, + "devDependencies": { + "@tsconfig/node24": "^24.0.3", + "@types/jsdom": "^27.0.0", + "@types/node": "^24.10.4", + "@vitejs/plugin-vue": "^6.0.3", + "@vitejs/plugin-vue-jsx": "^5.1.3", + "@vitest/eslint-plugin": "^1.6.4", + "@vue/eslint-config-prettier": "^10.2.0", + "@vue/eslint-config-typescript": "^14.6.0", + "@vue/test-utils": "^2.4.6", + "@vue/tsconfig": "^0.8.1", + "eslint": "^9.39.2", + "eslint-plugin-oxlint": "~1.35.0", + "eslint-plugin-vue": "~10.6.2", + "jiti": "^2.6.1", + "jsdom": "^27.3.0", + "npm-run-all2": "^8.0.4", + "oxlint": "~1.35.0", + "prettier": "3.7.4", + "typescript": "~5.9.3", + "vite": "npm:rolldown-vite@latest", + "vite-plugin-vue-devtools": "^8.0.5", + "vitest": "^4.0.16", + "vue-tsc": "^3.2.1" + } +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/public/favicon.ico b/data-acqusition-system_VL/frontend/web-management-vue3/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 Binary files /dev/null and b/data-acqusition-system_VL/frontend/web-management-vue3/public/favicon.ico differ diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/App.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/App.vue new file mode 100644 index 0000000000000000000000000000000000000000..7905b05167cb53db655f3938ea2adb68ca72e9fb --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/App.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/base.css b/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/base.css new file mode 100644 index 0000000000000000000000000000000000000000..8816868a41b651f318dee87c6784ebcd6e29eca1 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/base.css @@ -0,0 +1,86 @@ +/* color palette from */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); +} + +/* semantic color variables for this project */ +:root { + --color-background: var(--vt-c-white); + --color-background-soft: var(--vt-c-white-soft); + --color-background-mute: var(--vt-c-white-mute); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-heading: var(--vt-c-text-light-1); + --color-text: var(--vt-c-text-light-1); + + --section-gap: 160px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-background: var(--vt-c-black); + --color-background-soft: var(--vt-c-black-soft); + --color-background-mute: var(--vt-c-black-mute); + + --color-border: var(--vt-c-divider-dark-2); + --color-border-hover: var(--vt-c-divider-dark-1); + + --color-heading: var(--vt-c-text-dark-1); + --color-text: var(--vt-c-text-dark-2); + } +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + font-weight: normal; +} + +body { + min-height: 100vh; + color: var(--color-text); + background: var(--color-background); + transition: + color 0.5s, + background-color 0.5s; + line-height: 1.6; + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Oxygen, + Ubuntu, + Cantarell, + 'Fira Sans', + 'Droid Sans', + 'Helvetica Neue', + sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/logo.svg b/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..7565660356e5b3723c9c33d508b830c9cfbea29f --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/main.css b/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/main.css new file mode 100644 index 0000000000000000000000000000000000000000..36fb845b5232b8594b0d0f0e61a8cff0b73a4128 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/assets/main.css @@ -0,0 +1,35 @@ +@import './base.css'; + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + font-weight: normal; +} + +a, +.green { + text-decoration: none; + color: hsla(160, 100%, 37%, 1); + transition: 0.4s; + padding: 3px; +} + +@media (hover: hover) { + a:hover { + background-color: hsla(160, 100%, 37%, 0.2); + } +} + +@media (min-width: 1024px) { + body { + display: flex; + place-items: center; + } + + #app { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0 2rem; + } +} diff --git a/frontend/web-management-vue3/src/components/HelloWorld.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/HelloWorld.vue similarity index 100% rename from frontend/web-management-vue3/src/components/HelloWorld.vue rename to data-acqusition-system_VL/frontend/web-management-vue3/src/components/HelloWorld.vue diff --git a/frontend/web-management-vue3/src/components/TheWelcome.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/TheWelcome.vue similarity index 100% rename from frontend/web-management-vue3/src/components/TheWelcome.vue rename to data-acqusition-system_VL/frontend/web-management-vue3/src/components/TheWelcome.vue diff --git a/frontend/web-management-vue3/src/components/WelcomeItem.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/WelcomeItem.vue similarity index 100% rename from frontend/web-management-vue3/src/components/WelcomeItem.vue rename to data-acqusition-system_VL/frontend/web-management-vue3/src/components/WelcomeItem.vue diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/components/__tests__/HelloWorld.spec.ts b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/__tests__/HelloWorld.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..2533202008f7270910420c60a420efaf9b505c90 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/__tests__/HelloWorld.spec.ts @@ -0,0 +1,11 @@ +import { describe, it, expect } from 'vitest' + +import { mount } from '@vue/test-utils' +import HelloWorld from '../HelloWorld.vue' + +describe('HelloWorld', () => { + it('renders properly', () => { + const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } }) + expect(wrapper.text()).toContain('Hello Vitest') + }) +}) diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconCommunity.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconCommunity.vue new file mode 100644 index 0000000000000000000000000000000000000000..2dc8b055253af30fb797037e2fe260505f0cf711 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconCommunity.vue @@ -0,0 +1,7 @@ + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconDocumentation.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconDocumentation.vue new file mode 100644 index 0000000000000000000000000000000000000000..6d4791cfbcf2782b3e5ffbabd042d4c47b2fbbed --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconDocumentation.vue @@ -0,0 +1,7 @@ + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconEcosystem.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconEcosystem.vue new file mode 100644 index 0000000000000000000000000000000000000000..c3a4f078c0bd340a33c61ea9ecd8a755d03571ed --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconEcosystem.vue @@ -0,0 +1,7 @@ + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconSupport.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconSupport.vue new file mode 100644 index 0000000000000000000000000000000000000000..7452834d3ef961ce24c3a072ddba2620b6158bae --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconSupport.vue @@ -0,0 +1,7 @@ + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconTooling.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconTooling.vue new file mode 100644 index 0000000000000000000000000000000000000000..660598d7c76644ffe126a1a1feb1606650bfb937 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/components/icons/IconTooling.vue @@ -0,0 +1,19 @@ + + diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/main.ts b/data-acqusition-system_VL/frontend/web-management-vue3/src/main.ts new file mode 100644 index 0000000000000000000000000000000000000000..5dcad83c30800a564e96bad81c93d6be2ffaceaa --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/main.ts @@ -0,0 +1,14 @@ +import './assets/main.css' + +import { createApp } from 'vue' +import { createPinia } from 'pinia' + +import App from './App.vue' +import router from './router' + +const app = createApp(App) + +app.use(createPinia()) +app.use(router) + +app.mount('#app') diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/router/index.ts b/data-acqusition-system_VL/frontend/web-management-vue3/src/router/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..3e49915cae707b92441e745b76f9a7958cd8f2ac --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/router/index.ts @@ -0,0 +1,23 @@ +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/HomeView.vue' + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + name: 'home', + component: HomeView, + }, + { + path: '/about', + name: 'about', + // route level code-splitting + // this generates a separate chunk (About.[hash].js) for this route + // which is lazy-loaded when the route is visited. + component: () => import('../views/AboutView.vue'), + }, + ], +}) + +export default router diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/src/stores/counter.ts b/data-acqusition-system_VL/frontend/web-management-vue3/src/stores/counter.ts new file mode 100644 index 0000000000000000000000000000000000000000..b6757ba5723c5b89b35d011b9558d025bbcde402 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/src/stores/counter.ts @@ -0,0 +1,12 @@ +import { ref, computed } from 'vue' +import { defineStore } from 'pinia' + +export const useCounterStore = defineStore('counter', () => { + const count = ref(0) + const doubleCount = computed(() => count.value * 2) + function increment() { + count.value++ + } + + return { count, doubleCount, increment } +}) diff --git a/frontend/web-management-vue3/src/views/AboutView.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/views/AboutView.vue similarity index 100% rename from frontend/web-management-vue3/src/views/AboutView.vue rename to data-acqusition-system_VL/frontend/web-management-vue3/src/views/AboutView.vue diff --git a/frontend/web-management-vue3/src/views/HomeView.vue b/data-acqusition-system_VL/frontend/web-management-vue3/src/views/HomeView.vue similarity index 100% rename from frontend/web-management-vue3/src/views/HomeView.vue rename to data-acqusition-system_VL/frontend/web-management-vue3/src/views/HomeView.vue diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.app.json b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.app.json new file mode 100644 index 0000000000000000000000000000000000000000..913b8f279fca6f23c1b6532660583d2ec4ccebab --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.json b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..100cf6a8f2b8b43c3fba052e5241951ecdd7a384 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.json @@ -0,0 +1,14 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.vitest.json" + } + ] +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.node.json b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.node.json new file mode 100644 index 0000000000000000000000000000000000000000..822562d1ef6ea304e4a6d14872bf5211e9319314 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.node.json @@ -0,0 +1,19 @@ +{ + "extends": "@tsconfig/node24/tsconfig.json", + "include": [ + "vite.config.*", + "vitest.config.*", + "cypress.config.*", + "nightwatch.conf.*", + "playwright.config.*", + "eslint.config.*" + ], + "compilerOptions": { + "noEmit": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + + "module": "ESNext", + "moduleResolution": "Bundler", + "types": ["node"] + } +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.vitest.json b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.vitest.json new file mode 100644 index 0000000000000000000000000000000000000000..7d1d8cef325f81d4cea6abfdef5351fcc8fc8cd0 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/tsconfig.vitest.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.app.json", + "include": ["src/**/__tests__/*", "env.d.ts"], + "exclude": [], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo", + + "lib": [], + "types": ["node", "jsdom"] + } +} diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/vite.config.ts b/data-acqusition-system_VL/frontend/web-management-vue3/vite.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..d49d7084249240e5f8d8fabe488a3919d9a2c08d --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/vite.config.ts @@ -0,0 +1,20 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import vueJsx from '@vitejs/plugin-vue-jsx' +import vueDevTools from 'vite-plugin-vue-devtools' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + vueJsx(), + vueDevTools(), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + }, + }, +}) diff --git a/data-acqusition-system_VL/frontend/web-management-vue3/vitest.config.ts b/data-acqusition-system_VL/frontend/web-management-vue3/vitest.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..c32871718f0722417a09b494da853e8f4cf1b8d2 --- /dev/null +++ b/data-acqusition-system_VL/frontend/web-management-vue3/vitest.config.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url' +import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' +import viteConfig from './vite.config' + +export default mergeConfig( + viteConfig, + defineConfig({ + test: { + environment: 'jsdom', + exclude: [...configDefaults.exclude, 'e2e/**'], + root: fileURLToPath(new URL('./', import.meta.url)), + }, + }), +) diff --git a/frontend/web-management-vue3/package-lock.json b/frontend/web-management-vue3/package-lock.json index 86d964e8017a199d88ddae15bdd6f51a488de0e8..b95d5bcd7e8e1c99c647e5ec66aecb7759d525d5 100644 --- a/frontend/web-management-vue3/package-lock.json +++ b/frontend/web-management-vue3/package-lock.json @@ -8,10 +8,12 @@ "name": "web-management-vue3", "version": "0.0.0", "dependencies": { + "axios": "^1.13.2", "element-plus": "^2.13.0", "pinia": "^3.0.4", "vue": "^3.5.26", - "vue-router": "^4.6.4" + "vue-router": "^4.6.4", + "xlsx": "^0.18.5" }, "devDependencies": { "@tsconfig/node24": "^24.0.3", @@ -32,6 +34,7 @@ "npm-run-all2": "^8.0.4", "oxlint": "~1.35.0", "prettier": "3.7.4", + "sass": "^1.97.2", "typescript": "~5.9.3", "vite": "npm:rolldown-vite@latest", "vite-plugin-vue-devtools": "^8.0.5", @@ -1277,6 +1280,330 @@ "win32" ] }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -2609,6 +2936,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", @@ -2705,6 +3041,23 @@ "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", "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.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2821,6 +3174,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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/callsites": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", @@ -2852,6 +3218,19 @@ ], "license": "CC-BY-4.0" }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmmirror.com/chai/-/chai-6.2.2.tgz", @@ -2879,6 +3258,31 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", @@ -2899,6 +3303,18 @@ "dev": true, "license": "MIT" }, + "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/commander": { "version": "10.0.1", "resolved": "https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz", @@ -2949,6 +3365,18 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -3107,6 +3535,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz", @@ -3117,6 +3554,20 @@ "node": ">=8" } }, + "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/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -3233,6 +3684,24 @@ "url": "https://github.com/sponsors/antfu" } }, + "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-module-lexer": { "version": "1.7.0", "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz", @@ -3240,6 +3709,33 @@ "dev": true, "license": "MIT" }, + "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/escalade": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", @@ -3717,6 +4213,26 @@ "dev": true, "license": "ISC" }, + "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/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz", @@ -3734,6 +4250,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "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/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", @@ -3749,6 +4290,15 @@ "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/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3759,6 +4309,43 @@ "node": ">=6.9.0" } }, + "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/glob": { "version": "10.5.0", "resolved": "https://registry.npmmirror.com/glob/-/glob-10.5.0.tgz", @@ -3806,6 +4393,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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-flag": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", @@ -3816,6 +4415,45 @@ "node": ">=8" } }, + "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/hookable": { "version": "5.5.3", "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", @@ -3873,6 +4511,13 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", @@ -4602,6 +5247,15 @@ "@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/mdn-data": { "version": "2.12.2", "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.12.2.tgz", @@ -4648,6 +5302,27 @@ "node": ">=8.6" } }, + "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.5", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", @@ -4729,6 +5404,14 @@ "dev": true, "license": "MIT" }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz", @@ -5233,6 +5916,12 @@ "dev": true, "license": "ISC" }, + "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/punycode": { "version": "2.3.1", "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", @@ -5278,6 +5967,20 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", @@ -5384,6 +6087,27 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/sass": { + "version": "1.97.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.2.tgz", + "integrity": "sha512-y5LWb0IlbO4e97Zr7c3mlpabcbBtS+ieiZ9iwDooShpFKWXf62zz5pEPdwrLYm+Bxn1fnbwFGzHuCLSA9tBmrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/saxes/-/saxes-6.0.0.tgz", @@ -5496,6 +6220,18 @@ "node": ">=0.10.0" } }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "license": "Apache-2.0", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmmirror.com/stackback/-/stackback-0.0.2.tgz", @@ -6585,6 +7321,24 @@ "node": ">=8" } }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", @@ -6728,6 +7482,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz", diff --git a/frontend/web-management-vue3/package.json b/frontend/web-management-vue3/package.json index 17b78c38d979aaf3424764fe36534edeb39b8e58..b6274b79a81f79baaa60a5f548b96a3bd54bbb1e 100644 --- a/frontend/web-management-vue3/package.json +++ b/frontend/web-management-vue3/package.json @@ -19,10 +19,12 @@ "format": "prettier --write --experimental-cli src/" }, "dependencies": { + "axios": "^1.13.2", "element-plus": "^2.13.0", "pinia": "^3.0.4", "vue": "^3.5.26", - "vue-router": "^4.6.4" + "vue-router": "^4.6.4", + "xlsx": "^0.18.5" }, "devDependencies": { "@tsconfig/node24": "^24.0.3", @@ -43,6 +45,7 @@ "npm-run-all2": "^8.0.4", "oxlint": "~1.35.0", "prettier": "3.7.4", + "sass": "^1.97.2", "typescript": "~5.9.3", "vite": "npm:rolldown-vite@latest", "vite-plugin-vue-devtools": "^8.0.5", diff --git a/frontend/web-management-vue3/src/App.vue b/frontend/web-management-vue3/src/App.vue index 7905b05167cb53db655f3938ea2adb68ca72e9fb..b9de61b1f824155448a6a11388f3fb90a86df00d 100644 --- a/frontend/web-management-vue3/src/App.vue +++ b/frontend/web-management-vue3/src/App.vue @@ -1,85 +1,14 @@ diff --git a/frontend/web-management-vue3/src/api/Task.ts b/frontend/web-management-vue3/src/api/Task.ts new file mode 100644 index 0000000000000000000000000000000000000000..30d079072916a2ccf25fa82f776f3d390d06f097 --- /dev/null +++ b/frontend/web-management-vue3/src/api/Task.ts @@ -0,0 +1,109 @@ +// 保持原有Task接口不变(和后端返回的字段对应) +import request from '@/utils/request' +import { ElMessage } from 'element-plus' +export interface Task { + id: number + taskName: string + // taskVersion: string + // taskDesc: string + // sensitiveCheck: boolean + // dataSource: string + publishTime: string + updateTime: string + // selectedTable: string + // collectedColumns: string[] + // checkRuleNames: string[] + status:string + taskDescription:string +} + +export interface TaskQueryParams { + timeType?: string; // publishTime/updateTime + startDate?: string; // 开始日期 + endDate?: string; // 结束日期 + taskName?: string; // 任务名称 +} + +// 3.1 获取任务列表(GET请求) +export const getTaskList = (params?: TaskQueryParams): Promise => { + console.log('getTaskList接收到的参数:', params); + // 传参给后端:GET请求通过params传递查询参数 + return request.get('/task/list', { params }) +} + +// 3.2 新增任务(POST请求,传任务数据) +export const addoreditTask = (task: Omit): Promise => { + // 路径改为 /task/addOrUpdateTask(去掉/api,因为baseURL已包含) + return request.post('/task/addOrUpdateTask', task) + .then(() => true) + .catch((error) => { + throw error // 抛出错误让上层处理 + }) +} + +// 3.3 任务编辑 +export const getTaskDetail = (id: number): Promise => { + return request.get(`/task/addOrEdit/${id}`) + .then(res => { + // 现在 res 就是直接的任务详情数据(content),无需再取 res.content + console.log("编辑返回数据:", res); + + // 校验数据是否有效(至少包含核心字段,避免空数据) + if (res && res.taskName) { // 只要有任务名称,就认为数据有效 + return res; // 直接返回 res(即原content) + } else { + ElMessage.warning('获取任务数据失败:返回数据无效'); + return null; + } + }) + .catch(err => { + console.error('编辑获取数据接口报错:', err); + ElMessage.error('编辑获取数据接口报错,请重试'); + return null; + }) +} + + +//任务详情 +export interface TaskTableInfo { + tableId: number; // 仅需表ID + tableName: string; // 仅需表名 +} +// 详情专属接口:仅获取tableId和tableName +export const getTaskTableInfo = (id: number): Promise => { + return request.get(`/task/detail/${id}`); +}; + + + +// 3.4 编辑任务(PUT请求,传id和更新数据) +export const editTask = (id: number, task: Partial): Promise => { + // 替换为你的真实编辑接口路径,例如 /api/task/edit/1 + return request.put(`/api/task/edit/${id}`, task).then(() => { + ElMessage.success('任务编辑成功') + return true + }) +} + +// 3.5 删除任务(DELETE请求,传ids数组) +export const deleteTask = (ids: number[]): Promise => { + // 先校验参数:避免传空数组给后端 + if (!ids || ids.length === 0) { + ElMessage.warning('请选择要删除的任务ID') + return Promise.reject(new Error('任务ID数组为空')) + } + console.log("待删除任务id:",ids); + + // 关键修复:请求体直接传 { ids },而非 { data: { ids } } + return request.post('/task/del/batch', ids ) + .then(() => { + ElMessage.success('任务删除成功') + return true + }) + .catch((err) => { + // 捕获错误并提示用户 + console.error('删除任务失败:', err) + ElMessage.error('删除任务失败,请稍后重试') + return false // 失败返回false,方便调用方判断 + }) +} diff --git a/frontend/web-management-vue3/src/api/dataCollect.ts b/frontend/web-management-vue3/src/api/dataCollect.ts new file mode 100644 index 0000000000000000000000000000000000000000..4facf37631bff10586499889317a1096f29e55cc --- /dev/null +++ b/frontend/web-management-vue3/src/api/dataCollect.ts @@ -0,0 +1,56 @@ +import request from '@/utils/request' + +// --- 类型定义 --- + +export interface TaskItem { + id: number + taskName: string + taskDescription: string + updateTime: string + publishTime: string + status: string +} + +export interface TaskTableInfo { + tableId: number | string + tableName: string +} + +export interface TableColumn { + columnName: string + columnComment: string + columnType: string + columnLength: number + isPrimaryKey: boolean + isnullable: boolean + value?: any +} + +// 提交数据的 DTO +export interface DataCollectDTO { + taskId: number + filedName: string[] // 注意:后端字段拼写为 filedName + tableDataList: Record[] +} + +// --- 接口方法 --- + +// 1. 获取任务列表 +export function getTaskList(params?: { taskName?: string; timeType?: string; startDate?: string; endDate?: string }) { + return request.get('/task/list', { params }) +} + +// 2. 获取任务关联的表信息 +export function getTaskTableInfo(id: number) { + return request.get(`/task/detail/${id}`) +} + +// 3. 查询表结构 +export function getTableColumns(params: { tableName: string; nowTableId: number | string; taskId: number }) { + return request.get('/table/visual/columns', { params }) +} + +// 4. 提交采集数据 (更新为最新接口地址) +export function submitData(data: DataCollectDTO) { + return request.post('/collect/info/submit', data) +} \ No newline at end of file diff --git a/frontend/web-management-vue3/src/api/quality.ts b/frontend/web-management-vue3/src/api/quality.ts new file mode 100644 index 0000000000000000000000000000000000000000..8933fd4cfb48756212e7365547e22ac27e5fe52c --- /dev/null +++ b/frontend/web-management-vue3/src/api/quality.ts @@ -0,0 +1,62 @@ +// src/api/qualityResult.ts +import request from '@/utils/request' // 替换为你项目的request路径 + +// ========== 原有类型(保持不变) ========== +export interface QualityResult { + ruleId: number; + ruleName: string; + ruleDesc: string; + ruleLevel: string; + taskId: number; + taskName: string; + createTime: string; + updateTime: string; + paramList: null | any[]; +} + +export interface QualityResultResponse { + msg: string; + data: QualityResult[]; + code: number; +} + +export interface ListResultsParams { + taskName?: string; + timeType: string; + startTime?: string; + endTime?: string; +} + +// ========== 新增:质检详情相关类型 + 接口 ========== +// 单个质检数据项类型(和你组件里的CheckItem一致) +export interface CheckItem { + data: Record; // 动态字段数据 + highlightMap: Record; // 错误字段映射 +} + +// 质检详情接口返回类型(和你组件里的ExecuteCheckResponse一致) +export interface ExecuteCheckResponse { + code: string | number; // 兼容后端返回数字/字符串200 + msg: string; + content: CheckItem[]; +} + +// 质检详情请求参数类型 +export interface GetCheckDataParams { + taskId: number; // 任务ID(数字类型) +} + +// 1. 原有接口(保持不变) +export const getQualityResultList = (): Promise => { + return request.get('/api/quality/listAllResults') +} + +export const getFilteredQualityResultList = (params: ListResultsParams): Promise => { + return request.get('/api/quality/listResults', { params }) +} + +// 2. 新增:获取质检详情数据接口(封装你原来的/quality/executeCheck请求) +export const getCheckDataDetail = (params: GetCheckDataParams): Promise => { + // 注意:这里路径去掉/api,和你组件里修改后的一致 + return request.get('/api/quality/executeCheck', { params }) +} \ No newline at end of file diff --git a/frontend/web-management-vue3/src/api/sensitiveWord.ts b/frontend/web-management-vue3/src/api/sensitiveWord.ts new file mode 100644 index 0000000000000000000000000000000000000000..586c70d24b64bf3eee22ca8647a42154212b6784 --- /dev/null +++ b/frontend/web-management-vue3/src/api/sensitiveWord.ts @@ -0,0 +1,26 @@ +// @/api/sensitiveWord.ts +import request from '@/utils/request' // 用你之前封装的axios实例 + +// 定义敏感词类型(和后端返回结构一致) +export interface SensitiveWord { + id: number; + wordContent: string; + isEnabled: number; +} + +// 1. 获取敏感词列表(后端接口:GET /sensitiveWord/list) +export const getSensitiveWordList = () => { + return request.get('sensitiveWord/list') +} + +// // 2. 保存敏感词列表(后端接口:POST /sensitiveWord/save,传整个列表) +// export const saveSensitiveWordList = (data: SensitiveWord[]) => { +// return request.post('/sensitiveWord/save', data) +// } +export const saveSensitiveWordChange = (data: { + add: SensitiveWord[] + update: SensitiveWord[] + delete: number[] +}) => { + return request.post('/sensitiveWord/batch', data) // 后端新接口地址 +} \ No newline at end of file diff --git a/frontend/web-management-vue3/src/assets/main.css b/frontend/web-management-vue3/src/assets/main.css index 36fb845b5232b8594b0d0f0e61a8cff0b73a4128..cd97abd991f574fbfb4155342c2469ade3d77bc7 100644 --- a/frontend/web-management-vue3/src/assets/main.css +++ b/frontend/web-management-vue3/src/assets/main.css @@ -1,9 +1,9 @@ @import './base.css'; #app { - max-width: 1280px; + /* max-width: 1280px; */ margin: 0 auto; - padding: 2rem; + padding: 1rem; font-weight: normal; } diff --git a/frontend/web-management-vue3/src/main.ts b/frontend/web-management-vue3/src/main.ts index 5dcad83c30800a564e96bad81c93d6be2ffaceaa..f45dbbbb2cbc4cf21b3db94a1849df22de534c36 100644 --- a/frontend/web-management-vue3/src/main.ts +++ b/frontend/web-management-vue3/src/main.ts @@ -6,9 +6,13 @@ import { createPinia } from 'pinia' import App from './App.vue' import router from './router' +import ElementPlus from 'element-plus' +// 引入 Element Plus 样式(关键!没有这个布局样式不生效) +import 'element-plus/dist/index.css' + const app = createApp(App) app.use(createPinia()) app.use(router) - +app.use(ElementPlus) app.mount('#app') diff --git a/frontend/web-management-vue3/src/router/index.ts b/frontend/web-management-vue3/src/router/index.ts index 3e49915cae707b92441e745b76f9a7958cd8f2ac..8890e1f57709c0d0e0b3f42d9440262bed57fe7c 100644 --- a/frontend/web-management-vue3/src/router/index.ts +++ b/frontend/web-management-vue3/src/router/index.ts @@ -1,23 +1,121 @@ -import { createRouter, createWebHistory } from 'vue-router' -import HomeView from '../views/HomeView.vue' +import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' +// 导入布局组件 +import LayoutContainer from '@/views/Layout/index.vue' +import TaskAdd from '@/views/Task/TaskAdd.vue' +// 懒加载 + 增加加载失败兜底(避免异步加载导致的渲染错位) +const TaskFormulation = () => import(/* webpackChunkName: "task" */ '@/views/Task/index.vue') +const DataCollection = () => import(/* webpackChunkName: "data" */ '@/views/Data/index.vue') +const QualityInspectionResult = () => import(/* webpackChunkName: "quality" */ '@/views/Quality/index.vue') +const QualityCheckDetail = () => import(/* webpackChunkName: "quality-detail" */ '@/views/Quality/QualityCheckDetail.vue') +// 显式标注 routes 类型 +const routes: RouteRecordRaw[] = [ + // 根路由:严格重定向 + 明确布局 + { + path: '/', + redirect: { name: 'TaskFormulation' }, // 用name跳转(避免path拼写错误) + component: LayoutContainer, + children: [ + // 任务制定:增加alias + 明确meta标识 + { + path: 'task-formulation', + name: 'TaskFormulation', + alias: ['/task'], // 可选:增加别名,避免路径输入错误 + component: TaskFormulation, + meta: { + title: '任务制定', + key: 'task-formulation', // 唯一key,用于侧边栏匹配 + keepAlive: false // 关闭缓存,避免组件复用导致的错位 + } + }, + // 新增任务:增加父路由关联 + { + path: 'task-formulation/add', + name: 'TaskAdd', + component: TaskAdd, + meta: { + title: '新增任务', + key: 'task-add', + keepAlive: false + } + }, + // 采集任务:唯一key + { + path: 'data-collection', + name: 'DataCollection', + component: DataCollection, + meta: { + title: '采集任务', + key: 'data-collection', + keepAlive: false + } + }, + // 质检结果库:唯一key + { + path: 'quality-inspection-result', + name: 'QualityInspectionResult', + component: QualityInspectionResult, + meta: { + title: '质检结果库', + key: 'quality-inspection-result', + keepAlive: false + } + }, + // 质检详情页:严格参数匹配 + 禁止缓存 + { + path: 'quality-inspection-result/detail/:id(\\d+)', // 限制id只能是数字,避免非法参数 + name: 'QualityCheckDetail', + component: QualityCheckDetail, + meta: { + title: '质检详情页', + key: 'quality-check-detail', + keepAlive: false + }, + props: true, + // 可选:路由独享守卫,确保参数合法 + beforeEnter: (to) => { + const id = Number(to.params.id); + if (isNaN(id) || id <= 0) { + return { name: 'QualityInspectionResult' }; // 参数非法跳回列表 + } + } + } + ] + }, + +] + +// 初始化路由:修复BASE_URL + 增加滚动行为 const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), - routes: [ - { - path: '/', - name: 'home', - component: HomeView, - }, - { - path: '/about', - name: 'about', - // route level code-splitting - // this generates a separate chunk (About.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import('../views/AboutView.vue'), - }, - ], + history: createWebHistory(import.meta.env.BASE_URL || '/'), // 兜底BASE_URL + routes, + // 修复刷新/跳转时的滚动位置,避免历史记录异常 + scrollBehavior: (to, from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } else { + return { top: 0 }; + } + } +}) + +// 路由守卫:增加日志 + 严格匹配meta.title +router.beforeEach((to, from, next) => { + // 调试日志:定位路由跳转异常 + console.log('路由跳转:', { from: from.fullPath, to: to.fullPath, name: to.name }); + + // 严格设置标题 + if (to.meta.title) { + document.title = `${to.meta.title} - 数据采集系统`; + } + + // 禁止从详情页刷新后跳转到错误模块 + if (from.name === 'QualityCheckDetail' && to.name === 'NotFound') { + next({ name: 'QualityInspectionResult' }); + return; + } + + next(); }) -export default router +export default router \ No newline at end of file diff --git a/frontend/web-management-vue3/src/utils/request.ts b/frontend/web-management-vue3/src/utils/request.ts new file mode 100644 index 0000000000000000000000000000000000000000..d5571c3b9baa49b8cf1939439872d5f7b261bfb0 --- /dev/null +++ b/frontend/web-management-vue3/src/utils/request.ts @@ -0,0 +1,69 @@ +// src/utils/request.ts +import axios from 'axios' +import type { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios' +import { ElMessage } from 'element-plus' + +// 创建axios实例 +const request = axios.create({ + baseURL: 'http://10.107.180.156:8080/', + timeout: 10000, + headers: { + 'Content-Type': 'application/json;charset=utf-8', + // 如果请求遇到 ngrok 的浏览器警告页面导致 JSON 解析失败,请取消下面这行的注释 + 'ngrok-skip-browser-warning': 'true' + } +}) + +// 请求拦截器 +request.interceptors.request.use( + (config: AxiosRequestConfig) => { + const token = localStorage.getItem('token') + if (token && config.headers) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + (error: AxiosError) => { + ElMessage.error('请求发送失败,请检查网络') + return Promise.reject(error) + } +) + +// 响应拦截器 +request.interceptors.response.use( + (response: AxiosResponse) => { + const res = response.data + // 1. 如果后端直接返回数组(如你提供的 /task/list 数据),直接返回 + if (Array.isArray(res)) { + return res + } + // 2. 如果是对象结构(Result封装) + if (res && typeof res === 'object') { + // 兼容可能有 code/msg 的情况 + if (res.code && res.code !== 200 && res.code !== "200") { + ElMessage.error(res.msg || '请求失败') + return Promise.reject(res) + } + // 优先返回 data 或 content,否则返回整个对象 + return res.data !== undefined ? res.data : (res.content !== undefined ? res.content : res) + } + return res + }, + (error: AxiosError) => { + const status = error.response?.status + if (status === 401) ElMessage.error('登录已过期') + else if (status === 403) ElMessage.error('无权访问') + else if (status === 500) ElMessage.error('服务器错误') + else ElMessage.error(error.message || '网络请求错误') + return Promise.reject(error) + } +) + +export type RequestConfig = AxiosRequestConfig +export type ResponseData = { + code: number + data: T + msg: string +} + +export default request \ No newline at end of file diff --git a/frontend/web-management-vue3/src/views/Data/index.vue b/frontend/web-management-vue3/src/views/Data/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..78a0b3aac63e33127bddedae8d26d241a012f47c --- /dev/null +++ b/frontend/web-management-vue3/src/views/Data/index.vue @@ -0,0 +1,933 @@ + + + + + \ No newline at end of file diff --git a/frontend/web-management-vue3/src/views/Layout/index.vue b/frontend/web-management-vue3/src/views/Layout/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..30e636e2b0e4f35a5a530ec1ba4f31a72ee09268 --- /dev/null +++ b/frontend/web-management-vue3/src/views/Layout/index.vue @@ -0,0 +1,145 @@ + + + + + \ No newline at end of file diff --git a/frontend/web-management-vue3/src/views/Quality/QualityCheckDetail.vue b/frontend/web-management-vue3/src/views/Quality/QualityCheckDetail.vue new file mode 100644 index 0000000000000000000000000000000000000000..473094c7b98d59403fe3dd6f19acde8c0533c64a --- /dev/null +++ b/frontend/web-management-vue3/src/views/Quality/QualityCheckDetail.vue @@ -0,0 +1,355 @@ + + + + + \ No newline at end of file diff --git a/frontend/web-management-vue3/src/views/Quality/index.vue b/frontend/web-management-vue3/src/views/Quality/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..0fe69b3851fc18961aee3c665e56912f69233a01 --- /dev/null +++ b/frontend/web-management-vue3/src/views/Quality/index.vue @@ -0,0 +1,244 @@ + + + + + \ No newline at end of file diff --git a/frontend/web-management-vue3/src/views/Task/TaskAdd.vue b/frontend/web-management-vue3/src/views/Task/TaskAdd.vue new file mode 100644 index 0000000000000000000000000000000000000000..99a4d9fac2c58ebe1e5354e64a67e80d9aaa6b4b --- /dev/null +++ b/frontend/web-management-vue3/src/views/Task/TaskAdd.vue @@ -0,0 +1,1411 @@ + + + + + \ No newline at end of file diff --git a/frontend/web-management-vue3/src/views/Task/index.vue b/frontend/web-management-vue3/src/views/Task/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..79fe02caa0ac479998902dc799bd2efe2611aba4 --- /dev/null +++ b/frontend/web-management-vue3/src/views/Task/index.vue @@ -0,0 +1,450 @@ + + + + + \ No newline at end of file diff --git a/frontend/web-management-vue3/vite.config.ts b/frontend/web-management-vue3/vite.config.ts index d49d7084249240e5f8d8fabe488a3919d9a2c08d..9b0aa1419800c0509161d3f2f68484d93c700681 100644 --- a/frontend/web-management-vue3/vite.config.ts +++ b/frontend/web-management-vue3/vite.config.ts @@ -17,4 +17,27 @@ export default defineConfig({ '@': fileURLToPath(new URL('./src', import.meta.url)) }, }, -}) + // ========== 新增:代理配置(核心修复) ========== + server: { + proxy: { + // 匹配所有 /api 开头的请求,转发到后端服务器 + '/api': { + // !!!关键:替换为你的后端服务器实际地址(比如 http://localhost:8080、http://192.168.1.10:8080) + target: 'http://10.107.180.156:8080/', + changeOrigin: true, // 必须开启,解决跨域问题 + // 自定义路径重写:适配后端接口前缀不一致的情况 + rewrite: (path) => { + // 场景1:/api/quality/xxx → 后端实际是 /quality/xxx(无/api)→ 去掉/api前缀 + if (path.startsWith('/api/quality')) { + return path.replace(/^\/api/, ''); + } + // 场景2:其他 /api/xxx → 后端实际是 /api/xxx(带/api)→ 保留前缀 + else { + return path; + } + } + } + } + } + // ========== 代理配置结束 ========== +}) \ No newline at end of file