diff --git a/code/ERP动态配置多租户多公司多语言需求分析.md b/code/ERP动态配置多租户多公司多语言需求分析.md deleted file mode 100644 index dc9d48d3..00000000 --- a/code/ERP动态配置多租户多公司多语言需求分析.md +++ /dev/null @@ -1,1395 +0,0 @@ -# ERP 动态配置、多租户、多公司与多语言需求分析 - -> 文档版本:V1.1 -> 编制日期:2026-09-30 -> 修订日期:2026-09-30 -> 适用范围:FMS/ERP 新系统规划、产品设计、数据库设计、接口设计和开发验收 -> 文档状态:需求基线草案(多语言与配置版本方案已修订) -> -> **V1.1 修订范围**:第 10 章(引入变更集、无状态/有状态配置、类型注册表)、第 11 章(三层存储模型、角色能力边界、双重循环回退链、可覆盖白名单)、以及 3.5 / 9.4 / 13.2 / 19.4 / 22 / 23 章的配套修订。其余章节保持 V1.0 原文。 - -## 1. 文档说明 - -本文档用于明确 ERP 系统在以下方面的总体需求和设计边界: - -- 一个租户一个数据库的物理隔离模式; -- 一个租户包含多个公司、子公司和组织; -- 动态字段、动态表单、动态流程和动态权限; -- 简体中文、繁体中文、英文等多语言能力; -- 公司级业务、集团级共享资料和集团汇总报表; -- 与现有 FMS SQL 驱动、模块配置和工作流设计保持一致。 - -本文档是系统级需求分析,不替代各业务模块的详细需求、接口协议、数据库字段设计和页面原型。后续销售、采购、库存、财务等模块应以本文档的边界和基础模型为前提继续细化。 - -## 2. 建设目标 - -### 2.1 总体目标 - -建设一个面向企业集团和内部业务团队的 ERP/FMS 系统,通过稳定的业务内核和可版本化的配置能力,支持不同租户在不复制代码的情况下适配不同的组织结构、字段、流程、权限和语言。 - -系统不是通用低代码平台,不要求所有页面、业务规则和复杂业务组件都由用户拖拽生成。系统采用以下原则: - -> 固定核心业务能力,配置变化部分,代码承载复杂业务逻辑,插件承载专业差异。 - -### 2.2 具体目标 - -1. 每个租户拥有独立数据库,方便备份、迁移、恢复和维护。 -2. 一个租户可以包含多个公司、子公司、分公司和组织机构。 -3. 公司之间可以共享基础资料,也可以保持独立的业务和财务数据。 -4. 支持字段、表单、查询、编号、流程、权限、打印模板等动态配置。 -5. 支持用户界面、配置项、基础资料和业务快照的多语言处理。 -6. 核心业务数据可通过 SQL 高效查询、统计、导出和扩展。 -7. 所有配置均支持草稿、校验、发布、生效、停用和回滚。 -8. 支持单租户备份、恢复、复制到测试环境和迁移到其他数据库。 -9. 支持公司级报表、集团汇总报表和后续合并分析能力。 - -## 3. 设计原则 - -### 3.1 租户隔离原则 - -一个租户对应一个业务数据库。租户业务表不再依赖 `tenant_id` 实现日常数据隔离,数据库边界本身就是租户隔离边界。 - -租户注册信息与数据库连接信息由租户注册表维护。首期可以使用配置文件,后续在租户数量、部署实例或平台运维需求增加时再切换为可选平台库;租户自己的用户、组织、配置和业务数据始终放在租户数据库。 - -### 3.2 公司隔离原则 - -租户数据库内部允许多个公司共存,但所有公司级业务和财务数据必须带有 `company_id`。公司是业务、库存、结算、账簿和报表的主要归属边界。 - -### 3.3 配置与代码边界 - -以下内容优先配置化: - -- 字段定义、字段标签和字段分组; -- 列表和表单布局; -- 查询条件、排序、显示格式和导出字段; -- 编号规则、字典和枚举; -- 审批节点、审批人和审批条件; -- 角色、字段权限和数据范围; -- 打印模板、通知模板和简单校验。 - -以下内容必须由代码保证: - -- 库存扣减、锁定、释放和成本计算; -- 财务过账、反过账和账簿一致性; -- 单据状态的关键流转约束; -- 并发控制、幂等处理和跨模块数据一致性; -- 复杂税务、结算、汇率和合并抵销逻辑。 - -### 3.4 数据模型原则 - -- 核心业务数据使用关系表,不使用全量 EAV 模型。 -- 高频查询和关键业务字段使用正式列。 -- 变化频繁的扩展字段可使用 JSON 或扩展值表。 -- 需要筛选、排序、统计的扩展字段应具备可索引方案。 -- 历史单据保存名称、规格、地址、税率、价格等业务快照。 -- 配置、元数据和业务数据分离存储。 - -### 3.5 现有 FMS 规范兼容 - -系统实现应延续现有 FMS 规范: - -- 使用 SQL 驱动的查询和数据处理方式; -- 系统配置、元数据和权限表使用 `s_` 前缀; -- 业务表沿用现有 `b_` 或业务域前缀; -- 字段采用小写 `snake_case`; -- JSON 仅承载布局、查询和用户偏好等适合 JSON 的结构; -- 多语言采用三层存储:系统默认层与租户覆盖层使用租户库关系表,硬编码兜底层使用代码资源文件,历史单据使用业务快照(详见 11.1); -- 权限过滤必须落实到后端查询或写入逻辑; -- 不使用触发器代替业务层规则。 - -## 4. 业务概念模型 - -```text -平台 -└── 租户 Tenant:一个客户集团或客户账号,对应一个数据库 - ├── 公司 Company:集团总部、子公司、分公司、法人实体 - │ ├── 组织 Organization:部门、岗位、成本中心 - │ ├── 仓库 Warehouse - │ └── 账簿 Ledger - ├── 集团共享基础资料 - └── 公司专属基础资料 -``` - -### 4.1 租户 - -租户是平台级概念,代表一个独立客户或集团客户。租户具备: - -- 独立数据库; -- 独立的配置和业务数据; -- 独立的备份和恢复周期; -- 独立的模块授权和版本状态; -- 独立的默认语言、时区和区域设置。 - -### 4.2 公司 - -公司是租户内部的法人实体、经营主体或业务主体。公司至少需要维护: - -- 公司编码和名称; -- 上级公司; -- 公司类型; -- 法人、税号和注册地址; -- 默认币种和默认语言; -- 时区和会计日历; -- 默认账簿和财务期间; -- 银行账户、开票主体和税务信息; -- 启停用状态。 - -### 4.3 组织 - -组织是公司的内部管理单元,包括部门、业务部、采购部、仓储部、财务部、成本中心等。组织支持树形层级,可用于审批、权限、负责人、费用归属和数据范围。 - -### 4.4 共享范围 - -基础资料应支持集团共享和公司专属两种范围: - -```text -GROUP 集团内公司均可使用 -COMPANY 仅指定公司可使用 -ORG 仅指定组织或组织范围可使用 -``` - -共享不代表可以跨公司直接交易。业务单据仍必须指定实际业务公司、结算公司和相关组织。 - -## 5. 系统总体架构 - -```text -前端应用层 -├── 平台管理 -├── 基础资料 -├── 销售管理 -├── 采购管理 -├── 库存管理 -├── 费用与结算 -├── 财务管理 -├── 报表中心 -└── 系统配置 - -通用能力层 -├── 业务对象与元数据 -├── 动态表单与列表 -├── 工作流与审批 -├── 权限与数据范围 -├── 多语言与区域化 -├── 编号与字典 -├── 附件与打印 -├── 审计日志 -└── 通知消息 - -租户运行层 -├── 租户识别 -├── 数据库路由 -├── 数据源连接池 -├── 配置版本管理 -├── 租户数据库迁移 -├── 备份恢复 -└── 租户健康检查 - -数据层 -├── 租户连接注册(文件/平台库) -├── 租户数据库 -├── 消息队列 -└── 分析库/数仓 -``` - -### 5.1 租户注册表与平台库(可选) - -系统必须能够根据租户标识找到对应数据库。租户注册信息不强制要求使用平台库,首期可以使用按租户维护的配置文件: - -```text -config/tenants/tenant-a.json -config/tenants/tenant-b.json -``` - -注册表至少维护: - -- 租户编码和状态; -- 数据库标识和部署模式; -- 当前数据库版本; -- 数据库健康状态; -- 域名或登录入口映射; -- 模块授权和启用功能; -- 迁移、备份和恢复任务状态。 - -当需要在线开通租户、多实例部署、统一运维或集中查看所有租户状态时,可将同一套注册信息迁移到平台库。平台库只负责控制平面,不保存租户业务明细。 - -### 5.2 租户数据库 - -每个租户数据库保存本租户的完整业务数据,包括: - -- 用户成员和组织架构; -- 公司、账簿、仓库和基础资料; -- 系统模块、字段、流程、权限和语言配置; -- 销售、采购、库存、费用和财务数据; -- 租户级审计日志和业务操作记录。 - -## 6. 功能需求总览 - -| 编号 | 功能域 | 主要内容 | 优先级 | -| ------ | ---------- | ---------------------------------------- | ------ | -| FR-001 | 平台与租户 | 租户开通、数据库登记、状态管理 | P0 | -| FR-002 | 公司与组织 | 多公司、子公司、组织树、仓库和账簿 | P0 | -| FR-003 | 用户与权限 | 用户、角色、公司范围、组织范围、字段权限 | P0 | -| FR-004 | 元数据配置 | 模块、字段、对象和关系配置 | P0 | -| FR-005 | 动态页面 | 列表、表单、详情、查询和导出配置 | P0 | -| FR-006 | 工作流 | 状态、节点、条件、审批人和动作 | P0 | -| FR-007 | 多语言 | 界面、配置、主数据和单据快照多语言 | P0 | -| FR-008 | 基础资料 | 客户、供应商、产品、分类、价格和税率 | P0 | -| FR-009 | 销售采购 | 订单、审批、收发货、结算和对账 | P1 | -| FR-010 | 库存 | 仓库、库存、批次、序列号、调拨和盘点 | P1 | -| FR-011 | 财务 | 账簿、期间、应收应付、凭证和报表 | P1 | -| FR-012 | 报表 | 公司报表、集团汇总、导出和分析 | P1 | -| FR-013 | 运维 | 迁移、备份、恢复、监控和审计 | P0 | -## 7. 平台与租户管理需求 - -### 7.1 租户开通 - -租户开通可以由部署工具、运维人员或平台管理员完成: - -1. 创建租户基本资料; -2. 创建或绑定租户数据库; -3. 执行数据库初始化脚本; -4. 写入基础语言、时区和默认参数; -5. 创建首个租户管理员; -6. 分配默认模块和权限; -7. 写入租户注册文件或平台库; -8. 记录初始化结果和数据库版本。 - -租户注册表应抽象为统一的 `TenantRegistry` 接口。首期使用文件实现,后续可以替换为平台库实现,不改变业务模块代码。 - -### 7.2 租户数据库模式 - -系统应支持以下数据库部署模式: - -- `shared_instance`:同一数据库实例中的独立数据库; -- `dedicated_instance`:独立数据库实例; -- `external_database`:外部托管或私有化数据库。 - -默认采用独立数据库,是否独立实例由租户规模、性能和部署要求决定。 - -### 7.3 租户状态 - -租户状态至少包括: - -```text -CREATING 初始化中 -ACTIVE 正常使用 -READ_ONLY 只读维护 -SUSPENDED 暂停访问 -MIGRATING 数据迁移中 -ARCHIVED 已归档 -``` - -不同状态下,登录、查询、保存、审批、导出和后台任务应有明确限制。 - -## 8. 公司、组织和账簿需求 - -### 8.1 公司管理 - -系统支持在一个租户数据库内维护多个公司,并支持公司树: - -```text -集团总部 -├── 上海子公司 -├── 苏州子公司 -└── 香港子公司 -``` - -公司管理功能包括: - -- 新增、编辑、停用公司; -- 设置上级公司和公司类型; -- 设置默认语言、时区和币种; -- 设置会计日历和财务期间; -- 维护税务、银行和开票资料; -- 配置公司级编号规则、审批规则和权限; -- 查看公司数据量、业务状态和启用模块。 - -### 8.2 组织管理 - -组织树使用父子关系维护,支持: - -- 部门、岗位、成本中心等组织类型; -- 组织移动和层级调整; -- 负责人和分管人员; -- 组织有效期; -- 用户多组织任职; -- 审批节点按组织、岗位或负责人取值。 - -### 8.3 仓库和账簿 - -仓库必须归属公司,可进一步归属组织。账簿必须归属公司,并明确: - -- 本位币; -- 会计年度; -- 会计期间; -- 科目体系; -- 是否允许过账; -- 结账状态。 - -## 9. 用户、角色和权限需求 - -### 9.1 权限层次 - -系统权限至少分为: - -```text -平台权限 -租户权限 -公司权限 -组织权限 -仓库权限 -模块权限 -按钮权限 -字段权限 -数据权限 -业务动作权限 -``` - -### 9.2 用户业务上下文 - -用户登录后形成统一的业务上下文: - -```text -tenant_id 当前租户标识 -company_id 当前公司 -organization_id 当前组织 -ledger_id 当前账簿 -language 当前语言 -timezone 当前时区 -currency 当前显示或业务币种 -user_id 当前用户 -``` - -用户可以切换的范围由权限决定。普通用户可能只能切换组织,集团财务可以切换公司和账簿。 - -### 9.3 数据权限 - -数据权限支持: - -- 仅本人创建的数据; -- 所属组织数据; -- 所属组织及下级组织数据; -- 指定公司数据; -- 指定仓库数据; -- 指定客户、供应商或业务负责人数据; -- 自定义条件数据。 - -数据权限必须在后端 SQL 或数据访问层执行,前端隐藏不能代替后端权限过滤。 - -### 9.4 超级管理员与租户用户 - -> V1.1 新增。本章是第 10 章配置版本与第 11 章多语言的能力边界前提。 - -系统区分两类角色,其能力差异是全局性的,不只作用于多语言: - -| 角色 | 持有方 | 是否交付客户 | 主要能力 | -| ---------- | -------------- | ------------------ | ------------------------------------------------------------ | -| 超级管理员 | 运维或开发团队 | **否**,不交付租户 | 新增/删除语言、配置语言默认值、修改任意配置与文案、对租户白名单做例外放行、平台级运维操作 | -| 租户用户 | 客户方 | 是 | 在授权范围内修改文案取值与配置,**不能新增语言、不能语言级配置、不能修改锁定文本** | - -租户用户对文案的修改结果**对整个租户生效**,不是每个登录账号各改各的。租户内所有用户看到同一份文案;个人语言偏好只决定"使用哪一门语言",不决定"某个词如何翻译"。 - -这条约束的实操价值在于:用户报障时会复述屏幕上的文案,若同一租户内不同人看到不同叫法,运维无法据此定位问题。 - -## 10. 动态配置需求 - -### 10.1 配置对象 - -系统至少支持以下配置对象: - -- 业务模块; -- 数据对象; -- 字段定义; -- 主子表关系; -- 列表布局; -- 表单布局; -- 查询方案; -- 编号规则; -- 字典和枚举; -- 工作流; -- 权限和数据范围; -- 打印模板; -- 通知模板; -- 公式和简单规则。 - -### 10.2 动态字段 - -支持以下字段类型: - -- 文本、多行文本; -- 整数、数值、金额; -- 日期、时间、日期时间; -- 单选、多选、下拉树; -- 用户、部门、公司、仓库、客户等关联字段; -- 附件、图片; -- 公式字段; -- 子表和明细字段。 - -字段配置包括: - -- 编码、名称和数据类型; -- 是否启用; -- 是否必填; -- 默认值; -- 可见、只读和禁用条件; -- 查询、排序和导出能力; -- 权限级别; -- 公司作用域; -- 多语言标签; -- 校验和格式化规则。 - -### 10.3 动态表单和列表 - -表单支持: - -- 分组、选项卡和折叠面板; -- 字段栅格和列宽; -- 条件显示、条件只读和条件必填; -- 主表与子表; -- 自定义组件; -- 用户个性化布局; -- 根据公司、角色或单据状态使用不同布局。 - -列表支持: - -- 动态列; -- 固定列和排序; -- 多条件查询; -- 条件组和逻辑组合; -- 汇总、分组和统计; -- 导出字段控制; -- 用户保存查询方案。 - -### 10.4 配置生命周期与元模型 - -配置发布必须经过: - -```text -草稿 → 校验 → 测试 → 发布 → 生效 → 停用/回滚 -``` - -发布前校验包括: - -- 字段和编码重复检查; -- 关联对象存在性检查; -- 流程节点可达性检查; -- 必填字段可填写检查; -- 公式字段引用检查; -- 权限是否造成无人审批检查; -- 删除或停用字段对历史数据的影响检查。 - -配置版本必须保留发布人、发布时间、变更说明和前一版本引用。 - -> V1.1 修订:上述生命周期是**完整链路**,适用于结构型与行为型配置。展示型、内容型(含翻译)按 10.7 的类型注册表跳过"测试"环节,直接发布。 - -**统一元模型。** 10.1 列举的全部配置对象共用一套版本机制,不为每类各造一套: - -```text -配置对象 config_object —— 一个可版本化的单元(字段定义、列表布局、工作流、打印模板……) - ├── 工作副本 —— 唯一一份,可反复编辑 - ├── 版本快照 —— 发布时整体冻结,发布后不可变 - └── 指针 —— 当前版本 + 上一版本 - -变更集 change_set —— 打包多个配置对象的工作单元,见 10.5 -``` - -参考表结构(沿用 `s_` 前缀与 `snake_case` 命名): - -```text -s_config_object (tenant_id, object_type, object_code) -s_config_version (object_id, version_no, status, content_json) -s_config_release (object_id, current_version_id, previous_version_id, released_by, released_at) -s_change_set (tenant_id, set_code, status, released_by, released_at) -s_change_set_item (change_set_id, object_id, before_version_id, after_version_id) -``` - -**整包快照,不做行级 diff。** 单个配置对象通常为几百行 JSON,整体冻结最简单、最不易出错,回滚即移动指针。版本比对通过两个版本的 JSON 并排展示实现,**不实现三方合并**。 - -**配置作用域:租户级默认 + 公司级稀疏覆盖。**(V1.1 补充) - -本节新增的公司级覆盖机制只作用于「表现与行为」类配置对象;结构性定义仍由租户统一,详见下方「配置对象的作用域划分」。三层结构与第 11 章多语言的「覆盖层 → 默认层 → 兜底层」一致,表述与之对齐: - -```text -多语言:租户覆盖层 → 系统默认层 → 硬编码兜底层 -配置: 公司级覆盖 → 租户级默认 → 系统内置 -``` - -原 `s_config_object` / `s_config_version` / `s_config_release` 定义保持不变;公司级覆盖通过新增两张表实现,不改变对象的租户级定义: - -```text -s_config_override (object_id, company_id, current_version_id, previous_version_id) -s_config_override_version (object_id, company_id, version_no, content_json, status, released_by, released_at) -``` - -解析规则: - -```text -最终生效配置 = - 公司级覆盖(company_id) 存在 → 取公司级已发布版本 - 否则 → 取租户级已发布版本 -``` - -**覆盖粒度为「对象级整包覆盖」,不做字段级合并。** 理由:字段级合并会产生"字段 A 来自公司版、字段 B 来自租户版"的组合,租户升级后可能出现公司版与租户版字段结构不一致的诡异状态,且无法预测。整包覆盖语义清晰、可预期。 - -**稀疏覆盖,不做全量复制。** 公司级覆盖必须是稀疏的: - -- 公司创建时,覆盖表为空,零初始化; -- 租户级默认值变更后,自动传播到所有未做覆盖的公司; -- 公司删除覆盖,即回退到租户级默认。 - -**为什么不做「创建公司时复制全量租户配置」。** 该做法下,租户后续优化无法传播到已有公司,N 个公司产生 N 份副本,改一次通用规则要改 N 次,与多语言全量复制的缺陷完全相同。 - -**配套要求:租户版与公司版差异比对。** 系统提供「查看租户版与本公司版差异」的比对功能(两个 JSON 并排展示即可),使公司管理员能判断是否需要同步租户级更新。 - -**配置对象的作用域划分。** - -| 配置对象 | 租户级 | 公司级覆盖 | 说明 | -| --- | --- | --- | --- | -| 业务模块、数据对象、主子表关系 | 定义 | ❌ | 结构型,租户统一 | -| 字段定义(编码、名称、数据类型) | 定义 | ❌ | 结构性定义租户统一 | -| 字段使用属性(必填、显隐、只读、默认值、标签) | 默认 | ✅ | 10.2 已有「公司作用域」 | -| 列表布局、表单布局、查询方案 | 默认 | ✅ | 10.3 已支持按公司 | -| 编号规则 | 默认 | ✅ | 8.1 明确要求 | -| 工作流、审批规则 | 默认 | ✅ | 8.1 明确要求 | -| 权限和数据范围 | 默认 | ✅ | 9.1 已有公司权限层 | -| 打印模板、通知模板 | 默认 | ✅ | 抬头、税号、logo 常为公司专属 | -| 字典和枚举 | 默认 | ✅ 有限 | 允许公司增改项文案,不允许改编码 | -| 公式和简单规则 | 默认 | ❌ | 逻辑一致性优先 | - -> 原则:**结构性定义租户统一,表现与行为规则允许公司覆盖。** -> -> 作用域止于公司:组织级、仓库级不设配置作用域(仅权限可下沉到组织/仓库)。配置继续下沉会导致配置量爆炸且无法维护。 - -**作用域边界规则。** - -1. **删除公司级覆盖 = 回退到租户级默认**,不等同于停用或删除该配置。 -2. **孤儿覆盖校验**:租户级对象被停用或删除后,其下的公司级覆盖应被标记为孤儿覆盖,纳入发布前校验清单与运维巡检,不得静默失效。 -3. **公司停用或归档时,其覆盖随之失效**,不进入解析链。 -4. **权限、编号规则、打印模板复用同一套覆盖机制**,不得各造一套。 - -**共享内核(建议)。**「租户级默认 + 公司级稀疏覆盖 + 优先级解析」是本文档中反复出现的结构,至少四处复用同一模式——多语言(11.4 公司级 overlay)、配置(本次新增)、权限(9.1 公司权限层)、编号规则(8.1 公司级编号规则)。建议抽象为共享内核统一实现,避免四处各造一套导致行为不一致。 - -### 10.5 变更集 - -> V1.1 新增。V1.1 补充:支持租户级与公司级混合作用域。 - -ERP 中最常见的操作是"加字段 → 改表单 → 改列表列 → 改打印模板"的组合修改。若只能单对象独立发布,会产生"字段已加但表单未放置"的中间态不一致。因此配置以**变更集**为发布单元: - -- 变更集包含 N 个配置对象的草稿变更; -- 提交时执行**跨对象一致性校验**; -- **原子发布**:全部成功或全部不生效,不得出现半发布状态(呼应 19.4); -- **回滚以变更集为最小单位**。 - -**跨对象校验**是相比单对象发布的最大增量价值:可校验"表单引用的字段是否存在""列表列引用的字段是否已停用""打印模板引用的字段是否仍可见"这类约束,而这些在分开发布时无法校验。 - -**变更集项的作用域。**(V1.1 补充)`s_change_set_item` 增加 `scope` 与 `company_id`: - -```text -s_change_set_item (change_set_id, object_id, before_version_id, after_version_id, scope, company_id) -``` - -- `scope` 取 `TENANT` 或 `COMPANY`; -- `scope = COMPANY` 时 `company_id` 必填,指向公司级覆盖(见 10.4); -- `scope = TENANT` 时 `company_id` 为空。 - -**允许同一变更集混合租户级与公司级项。** 典型场景:「加字段(租户级)+ 改 A 公司表单(公司级)」必须能一起发,否则又会退回"字段已加但公司表单未更新"的中间态。 - -**原子发布与原子回滚仍以变更集为单位,跨作用域一并回退**,不因作用域不同而拆分。 - -**跨对象校验需具备作用域意识**:例如校验"表单引用的字段在该公司是否可见/启用",而非仅校验租户级。校验清单增加「孤儿覆盖检查」(见 10.4 作用域边界规则)。 - -**占用锁**:配置对象进入某个变更集后,其他变更集不得再将其加入,系统应提示"该对象已在 XXX 变更集中"。占用锁的键扩展为 `(object, scope, company_id)` 组合,避免同一公司级对象被两个变更集同时占用。采用占用锁而非三方合并。 - -### 10.6 无状态配置与有状态配置 - -> V1.1 新增。本节决定配置变更对在途业务单据的影响方式。 - -配置按是否持有运行时状态分为两类: - -| 类型 | 典型例子 | 生效规则 | -| -------------- | ---------------------------------------------------- | ------------------------------------------------------------ | -| **无状态配置** | 必填、显隐、只读、校验规则、显示格式、打印模板、翻译、编号规则的格式定义(前缀、日期格式、位数、补位规则) | **实时求值,永远以最新为准**。发布后立刻对所有单据生效 | -| **有状态配置** | 工作流、审批节点、审批规则 | **实例创建时绑定 `config_version`**,按绑定版本执行完毕,不受后续发布影响 | - -**为什么有状态配置必须绑定版本。** 审批流原为 A→B→C 三级,改为 A→C 两级后回滚:若按"最新为准",已走完 C 的单据在回滚后缺失 B 级审批,已发生的业务动作无法处理;仍卡在 C 的单据则无法确定 B 级算通过还是未通过。审批流改版时,在途单据必然被此类问题撞上。 - -**编号规则不属于有状态配置。** 编号规则需拆为两部分理解: - -- 编号格式的规则部分(前缀、日期格式、位数、补位方式等)是**无状态配置**,修改后实时求值、立即生效,与必填、显隐等同类,无需版本绑定; -- **计数器本身不是配置,而是运行时数据**。它需要解决的是并发安全问题(数据库序列、独立计数表或乐观锁),与配置版本机制无关,不进入 `s_config_version` 版本体系。 - -因此,需要版本绑定的配置仅包括工作流与审批流实例。不应为编号计数器生成版本快照。 - -**影响面**:版本绑定仅作用于"改版那一刻正在审批中的少数单据",新单据照常走最新版本。 - -**配套硬约束:** - -1. **字段只能停用,不能物理删除**。10.4 校验清单中"删除或停用字段对历史数据的影响检查"升级为硬约束。 -2. **保存与提交的校验强度不同**。新规则将某字段设为必填后,审批中的历史单据该字段可能为空,若保存时强制校验,该单据将既无法编辑也无法提交,形成死单。规则:**保存时降级为警告,提交/审核时强制校验**,使老单据可补填后继续流转。 -3. **运行时与发布分离**。运行时永远读取已发布版本,草稿修改不影响线上。单据与流程实例记录其绑定的 `config_version`;打印模板同理,历史单据打印使用开单时的模板版本。 - -### 10.7 类型注册表与校验器 - -> V1.1 新增。 - -使用**声明式类型注册表**替代散落的 if-else 判断。新增一类配置对象时,只需增加一条注册记录与一个校验器,不改引擎。 - -| 类型 | 例子 | 变更频率 / 风险 | 是否审批 | 生命周期 | -| ------ | ---------------------------- | --------------- | ------------ | ---------------------- | -| 展示型 | 列表布局、查询方案、打印模板 | 高 / 低 | 否 | 跳过测试环节,直接发布 | -| 内容型 | 翻译、字典、枚举文案 | 高 / 低 | 否(轻量档) | 轻量发布,见 11.10 | -| 结构型 | 字段定义、对象关系 | 低 / 高 | 是 | 校验 + 审批 | -| 行为型 | 工作流、审批规则、编号规则 | 中 / 高 | 是 | 校验 + 审批 | - -### 10.8 回滚语义 - -> V1.1 新增。 - -回滚 = 指针拨回上一版本,**物理上不删除任何数据**。 - -- 无状态配置:回滚后立即按旧版本求值。 -- 有状态配置:新实例按旧版本执行,在途实例按绑定版本执行完毕。 -- 存在在途实例时给出**强提示,但不硬性禁止**。管理员在回滚时具备判断力,强行拦截导致卡单才是更严重的事故。 - -### 10.9 设计边界 - -> V1.1 新增。以下内容明确不在本期范围内,避免后续被误加: - -- **不新建通用审批流引擎承载"配置审批"**,复用第 15 章已有的工作流能力。 -- **不自动生成配置变更的数据迁移脚本或 DDL**。结构型变更走"影响评估 + 只停用不删除"。 -- **不做行级 diff,不做冲突三方合并**。 - -## 11. 多语言与区域化需求 - -### 11.1 多语言存储策略 - -> V1.1 整节重写。原"混合存储(代码资源 + 租户库)"改为三层模型,并明确角色能力边界。 - -多语言文本分三层存储。**注意:系统默认层(第 2 层)走数据库而非代码资源文件**,原因是"超级管理员新增语言、配置语言默认值"是运行时的、不发版的动作,代码资源文件无法承载。 - -| 层级 | 内容 | 存储位置 | 可修改方 | 生效方式 | -| -------------------------- | ------------------------------ | --------------------------------------------------- | ------------------------------------ | ----------------------- | -| 第 3 层 租户覆盖层 overlay | 该租户**改过的 key**,只存差异 | 租户数据库 `s_i18n_overlay` | 租户(白名单内)、超级管理员(全部) | 保存即生效 | -| 第 2 层 系统默认层 | 系统默认翻译值,全量 | 租户数据库 `s_i18n_resource` / `s_i18n_translation` | **仅超级管理员** | 保存即生效,不发版 | -| 第 1 层 硬编码兜底层 | 系统能跑起来的最小文案集 | 代码资源文件 | 开发(随版本发布) | 仅在第 2 层不可用时生效 | - -关键约束: - -- **第 1 层不是全量翻译**,只放错误提示、语言名称本身等最小集,其唯一职责是"数据库不可用时界面仍能渲染、不白屏"。 -- **租户 overlay 只存差异**,大部分租户该表是空的——空表即零初始化、租户秒级可用。 -- **动态字段标签、流程节点名、字典文案等天生没有代码默认值的内容直接归入第 2 层**,不属于 overlay 概念。overlay 仅指"第 2 层已有默认值、租户要覆盖"的部分。 -- 平台库不负责保存租户业务翻译。 - -按内容性质归类: - -| 内容类型 | 归属层级 | 示例 | -| -------------- | ---------------------------------- | ------------------------------------------ | -| 系统默认文案 | 第 2 层 | 菜单、按钮、系统提示、固定错误码 | -| 租户改写文案 | 第 3 层 | 菜单显示名、按钮文案、业务校验提示 | -| 租户动态配置 | 第 2 层 | 动态字段标题、表单分组、流程名称、字典翻译 | -| 租户业务主数据 | 主表 + 翻译表 | 产品、分类、客户类型、供应商类型 | -| 可编辑模板 | 第 2 层 / 租户数据库 | 打印模板、邮件模板、通知模板 | -| 用户语言偏好 | 租户数据库用户配置,可辅以本地缓存 | 当前语言、日期格式、数字格式 | -| 历史单据内容 | 业务单据快照字段 | 产品名称、客户名称、税率、单位名称 | - -### 11.2 角色能力边界 - -> V1.1 新增,承接 9.4。 - -本文档中的"租户"实质上是**受限的普通用户**,不是可以自由定制的独立租户。多语言能力边界如下: - -| 能力 | 超级管理员 | 租户用户 | -| ------------------------- | -------------------- | ---------------------- | -| 新增语言 | ✅ 运行时配置,不发版 | ❌ | -| 删除/停用语言 | ✅ | ❌ | -| 配置语言默认值(第 2 层) | ✅ | ❌ | -| 修改具体文案取值 | ✅ 全部 | ✅ 白名单内 | -| 修改结果的生效范围 | 全局 | **整个租户**,非账号级 | - -租户用户**不能新增语言、不能删除语言、不能配置语言包的默认值**,只能修改已有语言中某些文案的取值。修改结果对整个租户生效,租户内所有用户看到同一份文案;个人语言偏好只决定"使用哪一门语言",不决定"某个词如何翻译"。 - -### 11.3 支持范围 - -系统设计上支持: - -- 简体中文 `zh-CN`; -- 繁体中文 `zh-TW`; -- 英文 `en-US`; -- 日文 `ja-JP`; -- 后续扩展其他语言。 - -首期实际启用语言由项目范围确定,但数据模型和接口不得写死单一语言。新增语言由超级管理员在运行时配置,不需要发版。 - -### 11.4 读取与回退规则 - -> V1.1 修订:删除原 11.2 与 11.5 两处互相冲突的回退链,合并为唯一一条,并改为双重循环模型。 - -原 V1.0 的 11.2 与 11.5 对回退链描述不一致(一处写"系统代码资源"、一处写"系统基础语言"),且把"语言"和"来源"两个正交维度压成了一维。统一模型如下: - -```text -语言候选 L = [用户语言, 当前公司默认语言, 租户默认语言, 系统基础语言] (去重) -来源优先 S = [租户 overlay, 公司级 overlay, 系统默认层, 硬编码兜底层, 原始 key 末段] - -遍历顺序:先遍历语言,后遍历来源 - for l in L: - for s in S: - 命中即返回 -``` - -**为什么要先语言后来源。** 若先遍历来源,会出现同一页面上半部分日文、下半部分中文(overlay 只有中文则出中文、默认层有日文则出日文)。ERP 中语言混屏会被当作缺陷上报,比缺翻译更严重。先遍历语言可保证整屏语言一致,全部未命中才整体降级。 - -**语言候选受"系统已启用语言"约束**:候选列表 = 系统已启用语言 ∩ 用户语言偏好。系统未启用某语言时,即使用户浏览器语言匹配也不得采用,应回退到系统基础语言。 - -代码资源与数据库资源应使用统一的语言编码和资源键。系统文案使用资源键,例如 `common.save`;动态配置和业务主数据使用对象编码、字段编码或资源 ID 关联翻译表。 - -缺少翻译时不得导致页面报错,应显示回退语言,并允许超级管理员查看缺失翻译清单。 - -### 11.5 多语言内容类型与可覆盖白名单 - -> V1.1 修订:原 11.1 与 11.4 冲突(11.1 将菜单、按钮归入代码资源,隐含租户不可改;11.4 又写两者"共同覆盖")。此处统一拆分。 - -数据库与代码资源共同覆盖以下内容: - -1. 菜单、按钮、提示和系统消息; -2. 动态字段、表单分组和流程节点; -3. 字典、分类和枚举项; -4. 产品、物料、客户分类和供应商分类; -5. 打印模板标题和固定文本; -6. 通知、邮件和消息模板; -7. 单据打印时使用的历史名称快照。 - -其中**允许租户覆盖**与**锁死不给改**的划分如下: - -| 允许租户覆盖 | 不允许租户覆盖(锁死) | -| ---------------------- | ------------------------ | -| 菜单显示名 | 技术错误码、异常堆栈文案 | -| 按钮文案 | 日志关键字、审计术语 | -| 表单/字段标签、分组名 | 权限拒绝的标准文案 | -| 业务校验提示、业务消息 | 升级提示、系统状态提示 | -| 打印模板抬头 | | - -**锁死理由**:用户报障时会复述屏幕上的错误文案,若该文案可被租户改写,运维无法用它检索日志与工单,问题定位链路会断。 - -**白名单授予方式**:按**模块 + 类别**批量授予,不逐 key 配置;超级管理员可对单个 key 做例外放行。 - -### 11.6 业务主数据翻译 - -产品、分类等主数据采用主表加翻译表的方式: - -```text -product -product_translation -dictionary_item -dictionary_item_translation -``` - -不建议把所有翻译内容拼接在单个 JSON 字段中,以便后续查询、导入、导出、校验和维护。 - -### 11.7 单据快照 - -单据创建或审核时,需要根据业务要求保存以下快照: - -- 产品编码和名称; -- 规格型号; -- 客户或供应商名称; -- 公司名称、地址和税号; -- 银行信息; -- 币种和汇率; -- 税率和税额; -- 付款条件; -- 单位名称。 - -历史单据展示和打印优先使用快照,不能因主数据后续改名而改变历史事实。 - -> V1.1 补充:快照需区分两类,名称类快照的语言维度待业务方确认(见第 22 章待确认项 14)。 - -- **事实性快照**:金额、税率、数量、编码、税号、地址等与语言无关的信息,必须原样存储,不因主数据后续变更而改变。 -- **名称类快照**:产品名称、客户名称、单位名称等。原 11.7 只要求存快照,未说明存哪个语言。实际场景:去年以中文开单,今年客户要求补打英文版发票,快照中只有中文名。 - -名称类快照提供三个选项供业务方决策: - -| 选项 | 做法 | 评价 | -| ---- | ------------------------ | -------------------------------------------- | -| a | 仅存开单时的那一种语言 | 补打其他语言无法输出,财务与合规场景常不满足 | -| b | 带 `lang` 维度存多份 | 最稳妥,存储量翻倍 | -| c | 仅存主数据 ID + 当前翻译 | 违反"历史事实不可变"原则 | - -**建议折中**:按开单语言存一份,同时保留主数据 ID,允许按当前翻译补打,但单据上须标注"依据当前资料翻译"。 - -### 11.8 区域化 - -系统分别配置语言、时区、日期格式、数字格式和币种,不将这些概念混为一谈。配置优先级为: - -```text -用户设置 → 公司设置 → 租户设置 → 系统默认 -``` - -### 11.9 缓存与资源治理 - -> V1.1 新增。以下条目为原 V1.0 缺失项,缺失会导致上线后返工。 - -1. **缓存**:多语言是每次渲染都读取的高频数据,必须缓存。按 `lang` 整包加载进内存(通常几十 KB),超级管理员修改默认值或租户修改 overlay 时发送缓存失效事件。 -2. **单一数据源**:避免前端与后端各维护一份资源文件导致不同步。以 key 为中心单一维护,构建期分发,或由后端统一提供 i18n 接口。 -3. **key 命名规范**:使用语义化 key,如 `sales.order.status.pending`。**禁止使用英文原文作为 key**——以原文为 key 时,修改一次英文就要改动所有语言包。 -4. **Excel 导入导出**:超级管理员批量配置翻译、批量查找替换的刚需。缺失此能力,翻译运营最终会退化为直接改数据库。 -5. **zh-TW 独立维护**:不得依赖简体自动转繁体。打印/列印、软件/軟體、文件/檔案 等用词差异必须独立维护。 -6. **废弃 key 治理**:废弃 key 标记为 `deprecated` 后静默保留,版本升级时不得硬删除,由清理工具另行处理。 -7. **占位符与复数**:至少支持 ICU MessageFormat(如 `{count, plural, ...}`)。中文无复数变化,但英文、俄文有,后期补齐成本高。 - -### 11.10 翻译与配置版本体系的关系 - -> V1.1 新增。本节落定"翻译是否纳入配置版本体系"。 - -**结论:翻译纳入同一套版本模型(10.4 元模型、10.5 变更集),但发布门槛设为最低档(轻量档)。** - -排除理由: - -- ❌ **不走严格审批**(同结构型):修改错别字也要等审批,运营会绕过系统直接改数据库。 -- ❌ **不独立于版本体系之外**:否则没有发布/回滚、没有审计、没有批量导入导出;且翻译与配置存在联动(新增字段时,字段标签翻译需与字段定义一同发布),两套体系无法实现原子发布,与 10.5 的变更集机制直接冲突。 - -轻量档的具体形态: - -| 能力 | 翻译是否具备 | -| ----------------------------------- | ------------ | -| 版本快照、一键回滚 | ✅ | -| 变更审计(谁改的、什么时候改的) | ✅ | -| 可进入变更集、与配置原子发布 | ✅ | -| 走审批才能生效 | ❌ | -| 必须走「草稿→校验→测试→发布」全链路 | ❌ | - -**热修复通道**:翻译属于高频、低风险、改错字类的操作,必须支持"改完立刻生效"的快速通道,10.4 的完整生命周期对其过重。翻译与「展示型」配置同属轻量档。 -## 12. 核心业务需求 - -### 12.1 基础资料 - -基础资料包括: - -- 客户、供应商和其他往来单位; -- 产品、物料、服务和分类; -- 单位、仓库、库位和批次规则; -- 价格表、付款条件和结算方式; -- 税率、币种和汇率; -- 银行账户和开票信息; -- 业务员、部门和负责人。 - -每项资料需要明确: - -- 集团共享还是公司专属; -- 谁可以查看和使用; -- 是否允许停用; -- 是否允许被历史单据引用; -- 是否支持多语言; -- 是否需要版本或有效期。 - -### 12.2 销售管理 - -销售流程至少支持: - -```text -报价 → 销售订单 → 审批 → 发货/出库 → 开票 → 收款/结算 -``` - -销售单据必须记录销售公司、销售组织、客户、仓库、币种、价格和税务信息。 - -### 12.3 采购管理 - -采购流程至少支持: - -```text -采购申请 → 采购订单 → 审批 → 收货/入库 → 发票 → 付款/结算 -``` - -采购公司、采购组织、收货仓库、供应商和结算主体可以按业务规则分别指定。 - -### 12.4 库存管理 - -库存管理至少支持: - -- 入库、出库、调拨和退货; -- 库存锁定和释放; -- 盘点和库存调整; -- 批次、保质期和序列号; -- 公司间调拨; -- 委托、寄售和其他库存所有权; -- 库存成本和库存余额。 - -库存数据必须明确公司、仓库、货主、产品和计量单位。 - -### 12.5 财务和结算 - -财务能力至少包括: - -- 公司独立账簿; -- 会计年度和期间; -- 应收、应付和往来核销; -- 费用、收款、付款和预收预付; -- 汇率和币种处理; -- 单据结算状态; -- 记账和反记账; -- 公司级财务报表。 - -财务单据必须归属公司和账簿。已过账数据不得通过普通编辑直接修改。 - -### 12.6 公司间交易 - -系统预留公司间交易能力,支持: - -- 公司间销售和采购; -- 公司间调拨; -- 代收代付; -- 内部往来; -- 公司间应收应付; -- 集团内部抵销标识。 - -公司间交易应记录: - -```text -source_company_id -target_company_id -intercompany_transaction_id -``` - -## 13. 数据模型要求 - -### 13.1 租户注册信息 - -首期可以使用配置文件维护以下信息,后续也可以将其迁移到平台库: - -```text -tenant_registry -tenant_database -tenant_module_license -tenant_migration_task -tenant_backup_task -tenant_domain_mapping -``` - -平台管理员、授权和运维任务是否进入平台库,根据部署模式决定;不影响租户数据库内的用户、公司和业务数据。 - -### 13.2 租户数据库核心对象 - -```text -s_user -s_role -s_user_role -s_company -s_organization -s_warehouse -s_ledger -s_user_company -s_user_organization -s_module -s_field -s_module_schema -s_workflow -s_permission -s_i18n_resource -s_i18n_translation -s_i18n_overlay -s_audit_log -``` - -> V1.1 新增以下配置版本与多语言对象(对应 10.4、10.5、11.1): - -```text -s_config_object -s_config_version -s_config_release -s_change_set -s_change_set_item -s_i18n_release -``` - -其中 `s_i18n_overlay` 只保存租户改过的 key(11.1 第 3 层),`s_i18n_release` 保存翻译版本快照(11.10)。 - -### 13.3 业务表通用字段 - -公司级业务表原则上包括: - -```text -company_id -organization_id 可选 -created_by -created_at -updated_by -updated_at -status -``` - -库存业务根据场景增加: - -```text -warehouse_id -owner_type -owner_id -``` - -财务业务根据场景增加: - -```text -ledger_id -fiscal_year -fiscal_period -currency_code -exchange_rate -``` - -### 13.4 数据库设计边界 - -核心字段使用关系列;动态字段根据访问频率采用 JSON 或扩展值表。不得为了追求绝对动态而将所有字段转换为 `entity_id + field_name + field_value` 的全量 EAV 结构。 - -## 14. 数据库路由和运行时需求 - -### 14.1 请求路由 - -请求处理流程: - -```text -请求进入 -→ 解析域名、登录信息或令牌 -→ 识别租户 -→ 读取租户注册表(配置文件或平台库) -→ 获取租户数据库标识 -→ 选择数据源和连接池 -→ 设置公司和组织上下文 -→ 执行业务查询或写入 -→ 清理上下文 -``` - -### 14.2 数据源管理 - -系统应支持: - -- 按租户动态创建数据源; -- 连接池复用和空闲释放; -- 租户数据库健康检查; -- 连接失败重试和熔断; -- 数据库只读状态; -- 租户迁移期间禁止普通写入; -- 日志记录租户、数据库和请求编号。 - -### 14.3 注册表实现和跨租户限制 - -`TenantRegistry` 至少支持文件实现和平台库实现两种方式。文件更新应具备格式校验、版本号和原子替换能力;平台库更新应具备事务和审计能力。 - -日常业务接口禁止跨租户查询和跨租户事务。平台级统计通过事件、CDC 或分析库实现,不在业务请求中遍历全部租户数据库。 - -## 15. 工作流与审批需求 - -### 15.1 流程模型 - -工作流采用状态机模型,包括: - -- 草稿; -- 提交; -- 审批中; -- 已通过; -- 已驳回; -- 已取消; -- 已完成; -- 已关闭。 - -### 15.2 审批节点 - -审批人来源支持: - -- 指定用户; -- 指定角色; -- 部门负责人; -- 公司负责人; -- 业务负责人; -- 发起人上级; -- 按金额、公司、组织或字段条件计算。 - -### 15.3 业务动作 - -流程节点可以触发: - -- 状态变更; -- 发送通知; -- 写入审计记录; -- 生成下一张业务单据; -- 锁定或释放库存; -- 触发打印或导出; -- 调用受控的业务处理器。 - -库存、财务和结算等关键动作必须经过业务处理器,不允许只依赖通用配置执行任意写入。 - -## 16. 审计、日志和可追溯性 - -系统应记录: - -- 登录、退出和租户切换; -- 公司和组织切换; -- 配置创建、发布和回滚; -- 权限授予、撤销和变更; -- 单据创建、修改、提交、审批和作废; -- 库存和财务关键动作; -- 导出、打印、备份和恢复; -- 平台管理员跨租户操作。 - -审计记录至少包含: - -```text -operator_id -tenant_code -company_id -operation_type -object_type -object_id -request_id -before_value -after_value -created_at -``` -## 17. 备份、恢复和迁移需求 - -### 17.1 租户级备份 - -系统支持单个租户执行: - -- 全量备份; -- 增量备份; -- 指定时间点恢复; -- 备份文件校验; -- 备份保留策略; -- 备份下载或转移; -- 恢复到临时数据库。 - -### 17.2 租户迁移 - -迁移流程: - -```text -申请迁移 -→ 检查租户状态 -→ 创建迁移前备份 -→ 切换只读 -→ 导出或复制数据库 -→ 校验数据和版本 -→ 更新租户连接文件或注册表记录 -→ 健康检查 -→ 恢复正常访问 -``` - -### 17.3 数据库版本 - -每个租户数据库必须维护当前结构版本。升级任务支持: - -- 版本扫描; -- 分批升级; -- 失败重试; -- 单租户暂停升级; -- 升级前备份; -- 执行记录和耗时; -- 失败原因和人工处理标记。 - -## 18. 报表和分析需求 - -### 18.1 公司级报表 - -首期支持: - -- 销售明细和汇总; -- 采购明细和汇总; -- 库存余额和收发存; -- 应收应付; -- 费用和结算; -- 公司利润和经营分析。 - -### 18.2 集团级报表 - -支持按公司、公司树、组织、区域、币种和期间汇总。集团报表需要考虑: - -- 不同公司的本位币; -- 汇率折算; -- 公司间交易识别; -- 内部往来抵销; -- 集团科目映射; -- 合并范围和有效期。 - -### 18.3 分析数据来源 - -日常交易查询使用租户数据库。跨公司和大数据量分析可通过事件或 CDC 同步到分析库,避免报表查询影响交易库。 - -## 19. 非功能需求 - -### 19.1 性能 - -- 常用列表查询应支持分页、排序和条件下推; -- 查询和数据权限尽量在 SQL 层完成; -- 不能在应用层加载全量数据后再过滤; -- 大型报表支持异步生成; -- 导入导出支持分批处理和进度反馈; -- 租户数据源应具备连接池上限和空闲回收机制。 - -### 19.2 可维护性 - -- 配置和业务逻辑分离; -- 租户数据库支持独立升级和恢复; -- 数据库迁移脚本可重复执行或具备明确版本记录; -- 核心业务规则集中实现; -- 动态模块不复制大量相同接口和页面代码。 - -### 19.3 可扩展性 - -- 支持新增公司和子公司; -- 支持新增语言(由超级管理员运行时配置,不需要发版); -- 支持新增模块、字段和流程; -- 支持独立数据库实例和外部数据库; -- 支持后续拆分库存、财务和分析服务; -- 支持公司级数据导出和迁移。 - -### 19.4 一致性 - -- 关键业务操作必须幂等; -- 库存和财务更新必须有明确事务边界; -- 已审核、已过账和已结算单据不能普通修改; -- 失败操作必须可重试或进入人工处理队列; -- 配置发布不能产生半发布状态(由 10.5 变更集的原子发布保证)。 - -## 20. 实施阶段建议 - -### 阶段一:平台基础和租户底座 - -- 租户连接配置或注册表; -- 租户开通和数据库路由; -- 数据库初始化和版本迁移; -- 用户、角色、公司和组织; -- 多语言基础资源; -- 审计日志; -- 备份和健康检查。 - -### 阶段二:动态配置底座 - -- 模块和字段元数据; -- 动态列表和查询; -- 动态表单; -- 字典和编号规则; -- 配置版本、发布和回滚; -- 基础权限和数据范围。 - -### 阶段三:核心业务 - -- 客户、供应商和产品; -- 销售和采购; -- 仓库、库存和调拨; -- 基础结算; -- 工作流和审批。 - -### 阶段四:财务和集团能力 - -- 账簿和期间; -- 应收应付; -- 费用和付款; -- 公司间交易; -- 集团汇总报表; -- 汇率和合并分析。 - -### 阶段五:增强能力 - -- 分析库和数据同步; -- 高级打印模板; -- 规则引擎; -- 外部系统接口; -- 独立数据库实例; -- 私有化部署和租户迁移工具。 - -## 21. 验收标准 - -### 21.1 租户隔离 - -- 新建两个租户并分别初始化数据库; -- 租户 A 的业务查询不能读取租户 B 的数据; -- 平台管理员切换租户有审计记录; -- 单个租户可以独立备份和恢复; -- 单个租户数据库可以迁移而不影响其他租户。 - -### 21.2 多公司 - -- 同一租户可以创建总部、子公司和分公司; -- 用户可被授权一个或多个公司; -- 公司级单据必须带 `company_id`; -- 基础资料可设置集团共享或公司专属; -- 公司级库存、账簿和报表相互隔离; -- 集团管理员可查看授权范围内的汇总数据。 - -### 21.3 动态配置 - -- 可新增自定义字段并在列表、表单和详情中使用; -- 可配置字段显隐、只读、必填和权限; -- 可配置流程并完成提交、审批、驳回和完成; -- 配置发布后可回滚到上一版本; -- 配置变更不会破坏历史单据展示。 - -### 21.4 多语言 - -- 用户可切换界面语言; -- 动态字段、字典和流程名称可翻译; -- 产品和基础资料支持多语言名称; -- 缺少翻译时按规则回退; -- 历史单据使用名称和税率快照; -- 打印模板可按语言输出。 - -### 21.5 运行维护 - -- 可查看每个租户数据库版本; -- 可执行租户级升级和失败重试; -- 可查看迁移、备份和恢复任务状态; -- 连接异常和数据库不可用时有明确错误提示; -- 大型跨公司报表不会阻塞日常单据操作。 - -## 22. 待确认事项 - -以下内容在进入详细设计前需要由业务方确认: - -1. 首期实际支持哪些语言; -2. 公司是否需要独立财务账簿和独立税务主体; -3. 是否首期实现公司间销售、采购和内部结算; -4. 首期支持哪些库存所有权类型; -5. 是否需要批次、序列号和保质期管理; -6. 租户数据库使用同一实例还是按规模分级部署; -7. 数据库备份保留周期和恢复时间目标; -8. 集团报表是否需要汇率折算和内部抵销; -9. 是否需要外部财务、税务、OA、CRM 或电商接口; -10. 哪些动态字段需要进入正式列或统计索引; -11. 业务配置是否需要测试环境和审批发布(V1.1 已按 10.7 类型注册表给出分类门槛,仍需业务方确认接受度); -12. 私有化部署是否作为首期交付范围; -13. 租户可覆盖的系统文本白名单范围是否完整(见 11.5,需确认锁死清单); -14. 历史单据名称快照是否需要支持多语言补打(见 11.7,选项 a/b/c 需业务方拍板); -15. 有状态配置(审批流、工作流)在途单据采用"实例绑定版本"的接受度(见 10.6); -16. 翻译变更纳入配置发布流程后,运营流程是否可配合(见 11.10); -17. 硬编码兜底层(11.1 第 1 层)最小文案集的具体范围。 - -## 23. 结论 - -平台库不是业务运行的硬性前提。对于租户数量较少、每个客户独立部署或由运维维护配置文件的场景,使用租户注册文件即可;当需要在线租户管理、集中运维、多实例同步或统一平台权限时,再启用平台库。无论采用哪种注册方式,业务代码保持一套,租户业务数据库保持独立。 - -系统采用以下总体方案: - -```text -代码 = 一套,租户差异通过配置、元数据和受控插件实现 -一个租户 = 一个独立数据库 -一个租户 = 多个公司、子公司和组织 -公司 = 业务、库存和财务归属边界 -组织 = 权限、审批和经营管理边界 -基础资料 = 支持集团共享或公司独立 -配置能力 = 动态字段、表单、流程、权限和打印 -多语言 = 界面、配置、主数据和历史单据快照(三层存储:租户覆盖 / 系统默认 / 硬编码兜底) -租户 = 受限用户,可改文案取值,不可新增语言 -超级管理员 = 运维持有,不交付客户,负责语言新增与默认值配置 -配置发布 = 以变更集为单元,跨对象校验,原子发布与原子回滚 -配置变更 = 无状态实时生效,有状态绑定版本跑完 -集团分析 = 公司维度汇总,必要时同步到分析库 -核心业务 = 由代码保证,不完全交给低代码配置 -``` - -最终目标不是把 ERP 做成一个万能低代码工具,而是建设一个具有稳定业务内核、清晰数据边界、可配置扩展能力和可独立运维能力的企业业务平台。 - -| | | -| ---- | ---- | -| | | -| | | -| | | -| | | -| | | \ No newline at end of file diff --git a/code/fms/FMS新系统核心架构实施计划.md b/code/fms/FMS新系统核心架构实施计划.md new file mode 100644 index 00000000..3f5ecc7a --- /dev/null +++ b/code/fms/FMS新系统核心架构实施计划.md @@ -0,0 +1,447 @@ +# FMS 新系统核心架构实施计划 V1.0 + +> 文档版本:V1.0 +> 编制日期:2026-09-30 +> 适用范围:FMS/ERP 新系统第一阶段核心架构重构 +> 执行方式:由多个 AI 按任务卡顺序执行,人负责最终取舍和验收 + +## 1. 计划目标 + +本计划用于指导其他 AI 实现 FMS 新系统第一阶段核心架构。 + +第一阶段只解决以下问题: + +- SQL Server 数据库如何迁移和版本化; +- 租户数据库如何连接和路由; +- 用户、公司、组织、仓库和账簿如何形成统一上下文; +- 业务域如何组织自己的表、SQL、服务、接口和页面; +- SQL 如何成为查询、报表和数据处理的主要实现; +- 简单基础资料如何使用通用 CRUD; +- 核心业务如何使用专用 SQL 和业务处理器; +- 如何用一个完整业务域验证架构。 + +第一阶段不实现完整 ERP,也不建设通用低代码平台。 + +## 2. 已确定的架构约束 + +其他 AI 执行所有任务时必须遵守以下约束: + +1. SQL Server 是第一阶段唯一数据库目标。 +2. 一个租户对应一个数据库,租户库内不使用 `tenant_id` 做日常业务过滤。 +3. 业务域代码包是代码组织中心。 +4. 真实业务表和 SQL 视图是事实来源。 +5. SQL 文件是查询、报表和数据处理的主要实现。 +6. 业务代码负责业务动作、事务和复杂业务规则。 +7. 页面配置只负责表现和少量参数。 +8. 不做全量 EAV,不做运行时任意生成业务表。 +9. 通用 CRUD 只用于简单基础资料,不作为核心业务默认实现。 +10. 工作流负责流程编排,库存、财务和结算动作必须由业务处理器完成。 +11. 第一阶段不引入通用配置版本引擎、通用公式引擎和通用规则解释器。 +12. 内部开发人员可以直接维护 SQL,不增加 SQL 安全沙箱、ORM 替代层或复杂 SQL DSL。 +13. 所有新代码必须遵守统一目录、命名和 SQL 文件风格。 + +## 3. 阶段依赖 + +```text +T0 架构基线和代码规范 + ↓ +T1 SQL Migration 和数据库运行时 + ↓ +T2 租户路由和业务上下文 + ↓ +T3 系统基础数据和权限 + ↓ +T4 业务域模板和 SQL 调用约定 + ↓ +T5 客户或产品示例业务域 + ↓ +T6 工作流、审计和多语言接入 + ↓ +T7 第一阶段验收和旧设计迁移清单 +``` + +T0 到 T4 必须顺序完成。T5 完成后,T6 可以拆分给不同 AI,但最终必须统一接口和风格。 + +## 4. 任务 T0:架构基线和代码规范 + +### 4.1 目标 + +把新架构的原则转成开发人员和 AI 都能执行的规则。 + +### 4.2 工作内容 + +- 阅读并理解以下文档: + - `ERP动态配置多租户多公司多语言需求分析.md`; + - `FMS新系统核心表结构设计.md`; + - `FMS新系统核心架构设计.md`。 +- 确定 SQL Server 版本和连接方式; +- 确定数据库迁移目录和文件命名; +- 确定业务域目录结构; +- 确定表名、字段名、索引、主键和时间字段规范; +- 确定 SQL 文件参数和返回结果规范; +- 明确哪些旧设计暂时不迁移。 + +### 4.3 输出物 + +```text +开发规范补充文档 +SQL Migration 目录 +业务域目录模板 +SQL 文件示例 +架构决策记录 +``` + +### 4.4 验收标准 + +- 新增一个业务域时不需要重新发明目录结构; +- SQL 文件可以被数据库工具独立执行和验证; +- 不存在同时使用两套字段命名和 SQL 组织方式的说明; +- 其他 AI 可以只读本阶段输出物开始后续工作。 + +## 5. 任务 T1:SQL Migration 和数据库运行时 + +### 5.1 目标 + +让每个租户数据库可以可靠地初始化、升级和记录结构版本。 + +### 5.2 工作内容 + +- 创建迁移记录表; +- 实现迁移文件扫描和顺序执行; +- 实现重复执行判断; +- 记录迁移名称、版本、checksum、执行时间和结果; +- 支持初始化新租户数据库; +- 支持租户数据库版本查询; +- 补充失败迁移的人工处理方式。 + +### 5.3 Migration 规则 + +```text +V001__create_core_tables.sql +V002__create_company_tables.sql +V003__create_audit_tables.sql +``` + +Migration 可以包含建表、改表、索引、视图、约束和必要的数据回填。 + +Migration 不负责页面布局和用户偏好,也不作为通用配置表使用。 + +### 5.4 验收标准 + +- 空数据库可以从零初始化; +- 已执行的迁移不会重复执行; +- 迁移失败时可以明确定位文件和错误; +- 两个租户数据库可以独立升级; +- 应用启动时可以读取数据库结构版本。 + +## 6. 任务 T2:租户路由和业务上下文 + +### 6.1 目标 + +建立统一的数据库连接、租户识别和请求上下文,不让业务域自行处理这些基础问题。 + +### 6.2 工作内容 + +- 定义 `TenantRegistry` 接口; +- 首期使用配置文件实现租户注册; +- 实现租户数据库连接创建和复用; +- 实现请求级数据库连接选择; +- 实现请求级业务上下文; +- 请求结束后清理上下文; +- 记录当前租户、用户、公司和请求编号。 + +### 6.3 上下文结构 + +```text +tenant_code +user_id +company_id +organization_id +warehouse_id +ledger_id +language +timezone +currency +request_id +``` + +### 6.4 验收标准 + +- 同一个请求内所有业务 SQL 使用同一个租户数据库; +- 业务域不需要自己读取租户配置文件; +- 用户可以切换授权公司并重新建立上下文; +- 上下文不会泄漏到下一个请求; +- 日志可以定位租户、用户、公司和请求。 + +## 7. 任务 T3:系统基础数据和权限 + +### 7.1 目标 + +建立所有业务域依赖的用户、角色、公司、组织、仓库和账簿。 + +### 7.2 第一批表 + +```text +s_user +s_role +s_user_role +s_role_permission +s_role_data_scope +s_company +s_organization +s_warehouse +s_ledger +s_user_company +s_user_organization +s_user_warehouse +s_user_ledger +``` + +### 7.3 权限范围 + +首期只实现: + +- 用户可用公司; +- 用户可用组织; +- 用户可用仓库; +- 模块访问权限; +- 业务动作权限; +- 全部、指定公司、本组织、本组织及下级、本人和指定仓库等简单数据范围。 + +不实现角色继承、拒绝权限和通用权限表达式。 + +### 7.4 验收标准 + +- 一个用户可以属于多个公司; +- 一个用户可以在不同公司拥有不同角色; +- 公司、组织、仓库和账簿不会混用编码; +- 权限查询可以使用 SQL 完成; +- 所有业务查询可以取得当前公司上下文。 + +## 8. 任务 T4:业务域模板和 SQL 调用约定 + +### 8.1 目标 + +建立所有业务域共同遵守的实现模板,解决“一个文件一个风格”的问题。 + +### 8.2 业务域模板 + +```text +domains// +├── migration/ +├── sql/ +├── repository/ +├── service/ +├── api/ +├── page/ +└── i18n/ +``` + +### 8.3 SQL 文件命名 + +```text +_list.sql +_detail.sql +_save.sql +_.sql +_report.sql +``` + +### 8.4 访问约定 + +- 查询由 repository 调用 SQL; +- 保存由 repository 调用保存 SQL或 service 组织多条 SQL; +- 业务动作由 service 作为唯一入口; +- 页面只调用 API; +- 业务域不直接修改另一个业务域的内部表; +- 复杂业务必须有明确事务边界; +- 简单资料才允许使用通用 CRUD。 + +### 8.5 验收标准 + +- 创建新业务域只需复制模板并替换业务名称; +- list、detail、save、action 的代码结构统一; +- SQL 不散落在页面、控制器和配置数据库中; +- 通用 CRUD 的适用范围有明确示例。 + +## 9. 任务 T5:客户或产品示例业务域 + +### 9.1 目标 + +用一条完整业务链路验证新架构,而不是先建设一个空的通用引擎。 + +### 9.2 推荐对象 + +优先选择客户或产品,不要一开始选择库存或财务。 + +### 9.3 工作内容 + +```text +SQL Migration +→ b_customer 或 b_product +→ 查询 SQL +→ 保存 SQL +→ 业务域 service +→ API +→ 页面 +→ 公司范围 +→ 审计 +→ 多语言名称 +``` + +### 9.4 验收标准 + +- 可以在 SQL Server 中直接执行列表和详情查询; +- 页面不需要通用模块解释器才能运行; +- 保存过程经过明确的 repository/service; +- 公司范围可以生效; +- 关键变更有审计记录; +- 新增字段可以通过 Migration 完成; +- 业务域目录、SQL 命名和代码风格符合 T4。 + +## 10. 任务 T6:工作流、审计和多语言接入 + +### 10.1 工作流 + +保留 `wf_*` 工作流子系统,但绑定业务动作,不绑定任意页面配置: + +```text +sales_order.submit +sales_order.approve +purchase_order.submit +expense.approve +``` + +工作流实例固定流程版本,真正的库存、财务和结算动作由业务域 service 执行。 + +### 10.2 审计 + +审计至少记录: + +```text +user_id +company_id +domain_code +business_id +operation +before_value +after_value +request_id +occurred_at +``` + +### 10.3 多语言 + +第一阶段只实现: + +```text +s_i18n_type +s_i18n +``` + +业务主数据按业务域使用翻译表。暂不实现多层 overlay、翻译变更集和运行时语言管理。 + +### 10.4 验收标准 + +- 工作流可以调用一个业务域动作; +- 流程实例记录固定的流程版本; +- 业务动作和审批动作有审计记录; +- 系统文案和主数据翻译可以按语言读取; +- 翻译读取不影响业务 SQL 查询。 + +## 11. 任务 T7:第一阶段验收和旧设计迁移清单 + +### 11.1 验收重点 + +第一阶段不是验收页面数量,而是验收架构是否成立: + +- SQL 是事实来源; +- 业务域可以独立拥有表、SQL、服务和页面; +- 不依赖通用模块解释器才能运行; +- 简单对象可以使用通用 CRUD; +- 核心动作使用专用 service 和 SQL; +- 多公司上下文贯通查询、保存、权限和审计; +- 数据库结构变更通过 Migration 管理; +- 代码目录和 SQL 风格统一。 + +### 11.2 旧设计迁移分类 + +```text +保留:真实业务表、成熟 SQL、工作流运行表 +迁移:散落 SQL、通用保存调用、模块页面配置 +降级:s_module、s_field、s_module_schema 只做登记和表现 +后置:全局配置版本、通用规则引擎、多层配置覆盖 +删除:以元数据解释器为中心的核心业务运行时 +``` + +## 12. 给其他 AI 的执行规则 + +每个 AI 接任务时必须先阅读: + +1. `FMS新系统核心架构设计.md`; +2. `FMS新系统核心架构实施计划.md`; +3. 与当前任务直接相关的旧设计文档。 + +每个 AI 的任务输出必须包含: + +```text +完成内容 +修改文件 +数据库变更 +验证方式 +未完成事项 +风险或需要人工决策的地方 +``` + +执行限制: + +- 不得自行增加通用配置引擎; +- 不得把业务逻辑放进页面 JSON; +- 不得为一个业务对象创建第二套 SQL 调用方式; +- 不得修改无关业务域; +- 不得为了“以后可能需要”提前抽象; +- 不得删除旧表或旧接口,除非任务明确要求迁移; +- 不得把 SQL 改写成 ORM 查询作为默认方案; +- 不得只提交页面而没有 SQL、服务和验收说明。 + +## 13. 第一张任务卡 + +可以把下面内容直接交给第一个 AI: + +```text +你负责 FMS 新系统核心架构实施计划的 T0 任务:架构基线和代码规范。 + +请先阅读: +1. FMS新系统核心架构设计.md +2. FMS新系统核心架构实施计划.md +3. FMS新系统核心表结构设计.md +4. 开发规范.md + +你的目标是确定 SQL Server、Migration、业务域目录、SQL 文件命名、数据库命名和业务动作入口规范。 + +要求: +- 不实现业务模块; +- 不新增通用低代码引擎; +- 不修改无关文件; +- 不把 SQL 改写成 ORM 查询; +- 输出一份开发规范补充文档; +- 提供一个客户或产品业务域的空目录模板; +- 提供至少三个 SQL 文件示例; +- 最后报告修改文件、验证方式和未决问题。 +``` + +## 14. 计划结论 + +第一阶段的正确顺序不是先做一个“万能模块引擎”,而是: + +```text +统一规范 +→ 数据库迁移 +→ 租户和公司上下文 +→ 系统基础数据 +→ 业务域模板 +→ 一个完整业务域 +→ 工作流和通用能力 +``` + +先用一个真实业务域验证架构,再决定哪些能力值得抽象。所有通用能力都必须来自实际重复,而不是来自对未来场景的猜测。 diff --git a/code/fms/FMS新系统核心架构设计.md b/code/fms/FMS新系统核心架构设计.md new file mode 100644 index 00000000..6e6c1750 --- /dev/null +++ b/code/fms/FMS新系统核心架构设计.md @@ -0,0 +1,732 @@ +# FMS 新系统核心架构设计 V2.0 + +> 文档版本:V2.0 +> 编制日期:2026-09-30 +> 文档状态:核心架构设计草案 +> 适用范围:FMS/ERP 新系统第一阶段重构 + +## 1. 文档目的 + +本文档重新定义 FMS 新系统的核心架构,重点解决以下问题: + +- SQL 是系统的第一等公民; +- 代码风格和模块实现方式统一; +- 第一阶段保持简单,不建设通用低代码平台; +- 真实业务表、业务 SQL 和业务代码拥有清晰边界; +- 支持一个租户多个公司,但不提前建设复杂的平台能力。 + +本文档替代旧设计中以 `s_module`、通用 CRUD 和动态 JSON 为中心的架构思路。旧表结构中的业务数据、工作流和可复用 SQL 可以迁移,但运行时中心需要重新组织。 + +## 2. 根本改变 + +### 2.1 旧架构 + +旧设计的主链路是: + +```text +s_module +→ s_field +→ s_module_schema +→ 通用 SQL 拼接 +→ 通用保存 +→ 页面 +``` + +它的优点是页面和简单模块创建较快,缺点是业务模块逐渐依赖元数据解释器,容易变成一个低代码平台。 + +### 2.2 新架构 + +新设计的主链路是: + +```text +业务域代码包 +→ 真实 SQL 表和视图 +→ 业务查询与业务动作 +→ API / 页面 +``` + +新系统的中心不再是全局模块元数据,而是**业务域代码包**。每个业务域自己拥有表结构、迁移、SQL、业务动作和页面入口。 + +```text +客户域 +├── 数据库迁移 +├── 业务表和视图 +├── 查询 SQL +├── 保存 SQL +├── 业务动作 +├── 接口 +├── 页面 +└── 多语言资源 +``` + +### 2.3 核心原则 + +```text +业务域是组织中心 +SQL 表和视图是事实来源 +SQL 文件是查询和处理的主要实现 +业务代码负责动作和事务 +页面是业务域的使用界面 +配置只解决少量表现和参数问题 +``` + +## 3. 总体架构 + +```text +租户注册配置 + │ + ▼ +租户数据库路由 + │ + ▼ +SQL Server 租户数据库 + ├── 系统内核 + │ ├── 用户、角色和业务上下文 + │ ├── 公司、组织、仓库和账簿 + │ ├── 多语言和审计 + │ └── 文件和运行记录 + ├── 业务域 + │ ├── 客户和供应商 + │ ├── 产品和基础资料 + │ ├── 销售 + │ ├── 采购 + │ ├── 库存 + │ └── 财务 + ├── 工作流 + └── SQL 视图和报表 +``` + +运行时链路: + +```text +请求 +→ 租户路由 +→ 建立用户和公司上下文 +→ 进入业务域 +→ 执行查询或业务动作 +→ SQL 事务 +→ 审计记录 +→ 返回结果 +``` + +## 4. 核心内核 + +核心内核只提供所有业务域都需要的能力,不负责解释所有业务。 + +### 4.1 租户路由 + +第一阶段采用一个租户一个数据库: + +- 租户注册信息使用配置文件; +- 一个租户对应一个 SQL Server 数据库; +- 租户库内不重复使用 `tenant_id` 过滤业务数据; +- 数据库连接由统一的 `TenantRegistry` 获取; +- 每个租户数据库单独执行迁移并记录版本。 + +平台库、在线租户开通和集中运维不进入第一阶段。 + +### 4.2 业务上下文 + +每次请求建立统一上下文: + +```text +tenant_code +user_id +company_id +organization_id +warehouse_id +ledger_id +language +timezone +currency +request_id +``` + +上下文由运行时创建,业务域只能读取,不由页面自行拼接。SQL 和业务动作通过上下文得到当前公司、用户和账簿。 + +### 4.3 基础表 + +第一阶段的系统基础表: + +```text +s_user +s_role +s_user_role +s_company +s_organization +s_warehouse +s_ledger +s_user_company +s_user_organization +s_user_warehouse +s_user_ledger +s_i18n_type +s_i18n +s_audit_log +s_file +``` + +角色先采用简单模型,不实现角色继承和复杂拒绝规则。公司、组织、仓库和账簿是明确的独立对象,不使用一个 `org_id` 代替它们。 + +## 5. 业务域代码包 + +### 5.1 业务域定义 + +业务域是新系统的主要代码组织单位,例如: + +```text +customer +supplier +product +sales +purchase +inventory +finance +workflow +``` + +一个业务域负责自己的: + +- 业务表和表关系; +- 数据库迁移; +- 查询视图; +- 查询 SQL; +- 保存 SQL; +- 业务动作; +- 事务边界; +- API; +- 页面; +- 多语言资源; +- 审计事件。 + +业务域之间通过明确的业务表关系、SQL 查询和服务接口协作,不通过全局 JSON 规则互相解释。 + +### 5.2 业务对象 + +业务对象仍然存在,但它属于业务域,而不是全局通用元数据引擎。 + +一个业务对象至少包含: + +```text +对象编码 +主表或视图 +查询 SQL +保存方式 +业务动作 +``` + +例如销售订单: + +```text +sales_order +├── b_sales_order +├── b_sales_order_line +├── sales_order_list.sql +├── sales_order_save.sql +├── submit_sales_order() +└── approve_sales_order() +``` + +### 5.3 业务域目录 + +建议使用以下代码组织方式: + +```text +fms/ +├── core/ +│ ├── tenant/ +│ ├── context/ +│ ├── auth/ +│ ├── audit/ +│ └── i18n/ +├── domains/ +│ ├── customer/ +│ │ ├── migration/ +│ │ ├── sql/ +│ │ ├── repository/ +│ │ ├── service/ +│ │ ├── api/ +│ │ └── page/ +│ ├── product/ +│ ├── sales/ +│ ├── purchase/ +│ ├── inventory/ +│ └── finance/ +├── workflow/ +└── shared/ +``` + +每个业务域使用同一种目录结构,不允许某个模块把 SQL 放数据库字段、另一个模块把 SQL 放页面代码、第三个模块再放配置 JSON。 + +## 6. SQL 设计 + +### 6.1 SQL 的职责 + +SQL 负责: + +- 查询; +- 关联; +- 分组和统计; +- 排序和分页; +- 批量更新; +- 事务内的数据处理; +- 报表和视图。 + +业务代码负责: + +- 业务动作入口; +- 事务编排; +- 状态变化; +- 幂等处理; +- 跨模块规则; +- 库存和财务业务约束。 + +### 6.2 SQL 文件规范 + +SQL 统一放在业务域目录下: + +```text +domains/sales/sql/ +├── order_list.sql +├── order_detail.sql +├── order_save.sql +├── order_submit.sql +└── order_report.sql +``` + +SQL 命名统一使用: + +```text +对象_动作.sql +``` + +例如: + +```text +customer_list.sql +customer_save.sql +customer_disable.sql +sales_order_submit.sql +inventory_lock.sql +``` + +### 6.3 通用 CRUD 的边界 + +新架构不移除通用 CRUD,但不把通用 CRUD 作为所有业务的默认核心。它可以用于简单基础资料,核心业务必须由业务域自己的 SQL 和业务动作实现。 + +以下内容不再作为系统核心: + +- 数据库中的 `b_query_sql` 作为所有模块的默认查询入口; +- `b_save_table` 驱动所有业务模块的通用保存; +- `b_order_sql` 在运行时任意拼接排序; +- 全局 `data / virtual` 模块解释器; +- 页面 JSON 中的业务公式和业务写入规则; +- 一张通用配置表承载所有业务行为。 + +内部开发人员可以自由编写 SQL,但 SQL 由对应业务域维护,并与代码和迁移一起发布。 + +### 6.4 通用保存边界 + +通用保存仅用于简单基础资料。以下内容必须使用业务域专用服务和 SQL: + +- 库存扣减、锁定和释放; +- 采购和销售状态推进; +- 财务过账和反过账; +- 公司间交易; +- 审批提交和审批动作; +- 任何需要多个业务表一致提交的操作。 + +## 7. 数据库模型 + +### 7.1 表分层 + +```text +s_* 系统内核和控制数据 +b_* 业务主表和业务明细表 +wf_* 工作流定义和运行数据 +``` + +核心业务表使用真实列和真实关系,不使用全量 EAV。 + +### 7.2 公司字段 + +公司级业务表根据业务实际需要包含: + +```text +company_id +organization_id +warehouse_id +ledger_id +``` + +跨公司业务另外保存: + +```text +source_company_id +target_company_id +settlement_company_id +``` + +共享基础资料不复制多份,使用共享范围或公司关联表表达。 + +### 7.3 动态字段 + +第一阶段不支持普通用户通过页面配置直接创建数据库字段。新增业务字段使用: + +```text +迁移脚本增加物理列或扩展表 +→ 更新查询 SQL 和视图 +→ 更新页面字段定义 +→ 增加多语言资源 +``` + +字段分为: + +1. 核心字段:真实列,参与业务逻辑和统计; +2. 扩展字段:通过迁移增加的可选列或扩展表字段; +3. 低频扩展:JSON,仅用于非核心展示。 + +需要筛选、排序、统计或导出的字段不能只放在 JSON 中。 + +运行时字段分为两种情况: + +- **表现字段**:标签、显隐、只读、排序和布局可以运行时调整; +- **物理字段**:需要存储、查询、排序、统计或导出的字段,必须通过 SQL Migration 增加物理列或扩展表。 + +后续如果确实需要管理员在线增加物理字段,可以增加一个受控的字段变更服务,由它生成并执行 SQL Migration,同时更新视图、字段定义和页面配置。这个过程仍然是数据库结构变更,不是普通 JSON 配置。 + +### 7.4 数据库约束 + +数据库负责结构完整性: + +- 主键; +- 外键; +- 唯一索引; +- 非空约束; +- 必要 CHECK; +- 查询和关联索引。 + +不使用触发器替代库存、财务和审批业务流程。业务规则放在业务域服务和事务 SQL 中。 + +## 8. 页面和配置 + +### 8.1 页面不是元数据生成的 + +核心业务页面由业务域代码实现。页面可以复用通用列表、表单和查询组件,但页面的字段、动作和业务行为由业务域明确声明。 + +页面配置只保存: + +- 列显示顺序; +- 列宽; +- 表单分组; +- 查询默认值; +- 用户个人偏好; +- 显示格式。 + +不使用 JSON 描述完整业务页面和业务处理器。 + +### 8.2 模块表的定位 + +如果保留 `s_module`,它只用于: + +- 菜单和路由登记; +- 权限对象登记; +- 模块名称和多语言资源键; +- 业务域对象的索引。 + +它不负责: + +- 生成所有 SQL; +- 推断所有保存逻辑; +- 承载业务状态; +- 解释任意 JSON 规则。 + +### 8.3 公司差异 + +第一阶段不建设通用的租户、公司、部门、角色多层配置继承。 + +确实存在公司差异时,在具体业务表中直接使用 `company_id`,例如: + +```text +s_number_rule(company_id, domain_code, field_code) +wf_binding(company_id, domain_code, event_code) +s_print_template(company_id, template_code) +``` + +不把所有差异都抽象为一个通用覆盖引擎。 + +## 9. 权限 + +权限采用简单的角色模型: + +```text +s_role +s_user_role +s_role_permission +s_role_data_scope +s_user_company +``` + +权限对象绑定业务域和业务动作: + +```text +customer.read +customer.create +sales_order.submit +sales_order.approve +inventory.adjust +finance.post +``` + +第一阶段支持: + +- 用户可用公司; +- 用户可用组织; +- 用户可用仓库; +- 模块访问权限; +- 业务动作权限; +- 简单数据范围。 + +不实现角色继承、拒绝权限和通用权限表达式。复杂范围由对应业务域的 SQL 实现。 + +## 10. 工作流 + +工作流是业务域的流程编排器,不是业务规则中心。 + +工作流绑定业务域动作: + +```text +sales_order.submit +sales_order.approve +purchase_order.submit +expense.approve +``` + +工作流可以决定: + +- 下一节点; +- 审批人; +- 当前流程状态; +- 需要调用哪个业务动作。 + +业务域负责真正的动作: + +- 销售订单批准后是否允许出库; +- 采购收货如何增加库存; +- 财务单据如何过账; +- 审批失败如何补偿。 + +工作流实例固定流程版本,历史审批记录只追加不修改。 + +## 11. 多语言 + +第一阶段保持简单: + +```text +s_i18n_type +s_i18n +``` + +系统文案使用稳定资源键: + +```text +sales.order.name +sales.order.customer +action.submit +``` + +业务主数据使用业务域自己的翻译表: + +```text +b_product +b_product_translation +b_customer +b_customer_translation +``` + +系统资源可以放在代码资源文件或租户库中,但必须统一一种来源。第一阶段不实现三层 overlay、翻译变更集和运行时语言管理。 + +历史单据保存产品名称、客户名称、税率、地址、币种和金额等快照。 + +## 12. 配置和版本 + +第一阶段不建设覆盖所有对象的通用配置版本引擎。 + +配置分为三类: + +| 类型 | 实现方式 | +| --- | --- | +| 数据库结构 | SQL Migration | +| 业务逻辑 | 代码和业务 SQL | +| 页面表现 | 页面代码和少量布局配置 | +| 工作流 | 独立流程版本表 | +| 业务参数 | 明确的参数表 | + +只有工作流、编号规则、打印模板等确实需要历史追溯的内容,才单独设计版本。 + +### 12.1 SQL Migration + +SQL Migration 是按顺序执行、可追踪的数据库结构变更脚本。例如: + +```text +migration/ +├── V001__create_company.sql +├── V002__create_customer.sql +└── V003__add_customer_tax_no.sql +``` + +迁移工具在每个租户数据库中记录已执行的版本。发布新代码时,先执行缺少的迁移,再启动依赖新结构的代码。 + +Migration 可以包含: + +- 建表、改表和删表; +- 增加或停用字段; +- 创建视图、索引和约束; +- 初始化字典和系统数据; +- 必要的数据回填。 + +Migration 不等于运行时页面配置。页面配置可以立即保存,数据库结构变化则必须经过迁移记录。 + +数据库迁移记录: + +```text +schema_version +migration_name +checksum +executed_at +``` + +## 13. 代码风格和目录规范 + +新系统的代码按业务域组织,不按页面组织,也不按一组通用配置表组织。 + +```text +domains/ + sales/ + migration/ + sql/ + repository/ + service/ + api/ + page/ + i18n/ +``` + +统一要求: + +- 一个业务动作只有一个主要入口; +- SQL 统一放业务域的 `sql` 目录; +- 页面只调用业务域 API,不直接写业务 SQL; +- 业务域不通过另一个域的内部表直接修改数据; +- 数据库表、SQL、服务、接口和页面使用同一业务名称; +- 新增抽象必须来自至少两个真实业务域的重复需求。 + +数据库命名在新系统中一次确定: + +- 表名使用小写 `snake_case`; +- 系统表使用 `s_`; +- 业务表使用 `b_` 或明确业务域前缀; +- 工作流表使用 `wf_`; +- 字段命名统一使用一套规则,不再混用 `b_`、`mx_` 和裸字段名。 + +## 14. 第一阶段建设范围 + +第一阶段只建设架构内核和一条完整业务链路。 + +### 14.1 必须完成 + +1. SQL Server 迁移工具和数据库版本表; +2. 租户数据库连接和路由; +3. 用户、角色、公司、组织、仓库和账簿; +4. 统一业务上下文; +5. 业务域目录和 SQL 调用约定; +6. 基础权限和公司范围; +7. 审计日志; +8. 基础多语言; +9. 一个业务域的表、SQL、服务、接口和页面完整闭环。 + +### 14.2 建议示例 + +建议先做客户或产品域: + +```text +SQL Migration +→ 真实业务表 +→ 查询 SQL +→ 保存 SQL +→ 业务域服务 +→ API +→ 页面 +→ 公司权限 +→ 审计 +``` + +这个示例必须验证“业务域代码包是中心”,不只是验证通用页面是否能显示。 + +### 14.3 第一阶段不做 + +- 以全局 `s_module` 驱动的通用 CRUD 作为核心业务默认实现; +- 全局 `s_field` 驱动的运行时字段创建; +- 通用页面设计器; +- 通用公式和规则解释器; +- 全对象配置版本和变更集; +- 多层公司配置覆盖; +- 复杂多语言发布体系; +- 集团分析库和跨租户业务查询。 + +## 15. 第一阶段验收标准 + +### 15.1 架构中心 + +- 一个业务域拥有自己的迁移、SQL、服务和页面; +- 业务域可以不依赖通用模块解释器运行; +- 页面配置不能替代业务代码; +- 工作流只能调用明确登记的业务动作。 + +### 15.2 SQL 驱动 + +- 业务查询可以直接在 SQL Server 中验证; +- 复杂查询使用业务域 SQL 文件或视图; +- 业务表和关联关系是真实 SQL 结构; +- 新增可统计字段需要物理列或索引扩展; +- 不为了页面功能复制业务表。 + +### 15.3 简单和一致 + +- 同类业务域使用相同目录和调用流程; +- 不存在同一类配置的多种格式; +- 不存在同一业务动作的多个通用入口; +- 数据库迁移和代码可以一起发布; +- 第一阶段不依赖通用低代码运行时。 + +## 16. 旧设计迁移原则 + +旧设计不是全部废弃,而是按职责迁移: + +| 旧内容 | 新系统处理方式 | +| --- | --- | +| 真实业务表 | 保留并按业务域归属整理 | +| 业务 SQL | 移入对应业务域 `sql` 目录 | +| `wf_*` 工作流表 | 保留,改为绑定业务动作 | +| `s_module` | 降为菜单、权限和对象索引 | +| `s_field` | 降为字段说明,不负责运行时造字段 | +| `s_module_schema` | 页面局部配置,不作为核心运行时 | +| 通用保存接口 | 仅保留简单基础资料使用 | +| JSON 公式和动态规则 | 迁移到业务代码或 SQL | +| `b_query_sql` 等全局 SQL 字段 | 逐步迁移到业务域 SQL 文件 | + +## 17. 最终架构关系 + +```text +业务域代码包是组织中心 +SQL 表和视图是事实来源 +SQL 文件是查询和处理的主要实现 +业务代码负责动作和事务 +页面负责交互 +工作流负责流程编排 +少量配置负责表现和参数 +``` + +新系统不是旧系统增加一层配置,也不是把旧模块表重新命名。它的核心变化是: + +> **从元数据驱动的通用模块,改成业务域驱动的 SQL 应用。** diff --git a/code/g3soft-libs/.changeset/config.json b/code/g3soft-libs/.changeset/config.json new file mode 100644 index 00000000..0dd1adda --- /dev/null +++ b/code/g3soft-libs/.changeset/config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": ["@g3soft/docs"] +} diff --git a/code/g3soft-libs/.gitignore b/code/g3soft-libs/.gitignore new file mode 100644 index 00000000..ffa91e73 --- /dev/null +++ b/code/g3soft-libs/.gitignore @@ -0,0 +1,17 @@ +node_modules +dist +coverage + +# Nuxt / Docus 产物与缓存 +.nuxt +.output +.data +.nitro +.cache + +# 构建前挪走的 Nuxt 缓存(见 README「构建环境说明」) +.trash + +*.log +*.tsbuildinfo +.DS_Store diff --git a/code/g3soft-libs/README.md b/code/g3soft-libs/README.md new file mode 100644 index 00000000..9f91b3f9 --- /dev/null +++ b/code/g3soft-libs/README.md @@ -0,0 +1,89 @@ +# g3soft-frontend + +G3Soft 前端技术基础设施:**自研 Vue 3 组件库** + **Docus 文档站**,pnpm monorepo 管理。 + +## 目录结构 + +``` +g3soft-frontend/ +├── pnpm-workspace.yaml # workspace 声明 + catalog 统一版本 + 构建脚本白名单 +├── packages/ +│ ├── ui/ # 组件库(发布到 npm 私库) +│ │ ├── src/button/ # 一组件一目录 +│ │ └── vite.config.ts # 产出 ESM + 类型声明 +│ └── tokens/ # 设计变量,组件库与文档站共用 +├── docs/ # 文档站(private,不发布) +│ ├── nuxt.config.ts # Docus Layer + alias 直连 packages 源码 +│ ├── content/ # Markdown 内容(路由与导航自动生成) +│ ├── examples/ # 可运行示例,按组件分目录 +│ ├── data/api/ # gen:api 生成的 API 数据(不要手改) +│ └── app/components/content # Demo.vue / ApiTable.vue(可在 md 中直接使用) +└── scripts/gen-api.mjs # 从组件源码生成 API 表格数据 +``` + +## 环境要求 + +- Node.js >= 20.19 +- pnpm 11(`better-sqlite3` 是 Docus 全文搜索依赖的原生模块,已在 `allowBuilds` 中放行) + +## 安装 + +```bash +pnpm install +``` + +## 开发 + +```bash +pnpm dev +``` + +启动文档站(默认 http://localhost:3000)。组件源码通过 alias 直连,改 `packages/ui` 会即时热更。 + +## 构建 + +```bash +pnpm gen:api # 从组件源码重新生成 API 数据(改了 props/events/slots 后必跑) +pnpm build # 构建 packages/*(组件库产出 dist) +pnpm build:docs # 构建文档站静态文件 +``` + +文档站静态产物在 `docs/.output/public`,可直接部署到任意静态托管。 + +### 部署到子路径 + +文档站支持挂载到子路径,构建时通过环境变量指定: + +```bash +DOCS_BASE_URL=/docs/ pnpm build:docs +``` + +## 发布组件包 + +组件库走 changesets 管理版本: + +```bash +pnpm changeset # 记录本次改动 +pnpm version # 生成版本号与 CHANGELOG +pnpm release # 构建并发布到私库 +``` + +`packages/ui` 的 `prepublishOnly` 会执行 `publint` 校验包结构(`exports`、`files` 是否自洽)。 + +## 两条链路为什么互不干扰 + +| | 文档站 | 组件包 | +|---|---|---| +| 是否发布 | 否(`private: true`) | 是(npm 私库) | +| 版本管理 | 无 | changesets(已 `ignore: ["@g3soft/docs"]`) | +| 构建命令 | `pnpm build:docs` | `pnpm build` | +| 产物 | `docs/.output/public`(静态) | `packages/ui/dist`(ESM + d.ts) | +| 依赖边界 | Docus / Nuxt / Tailwind 只在 `docs` 包 | 只有 `vue`(peer) 与 `@g3soft/tokens` | + +关键点:Nuxt 相关的依赖**只出现在 `docs/package.json`**,组件库的依赖树里没有任何文档站的东西;changesets 的 `ignore` 保证打 tag 发版时不会带上文档站。 + +## 约定 + +- 组件样式**不写 `scoped`**,用 `g3-` 前缀 + BEM,颜色尺寸一律引用 `--g3-*` 变量。 +- API 表格由源码生成,**禁止手写**;改了组件记得跑 `pnpm gen:api`。 +- 示例放 `docs/examples/<组件名>/<示例名>.vue`,在 md 中用 `::demo{name="<组件名>/<示例名>"}` 引用。 diff --git a/code/g3soft-libs/docs/app/components/content/ApiTable.vue b/code/g3soft-libs/docs/app/components/content/ApiTable.vue new file mode 100644 index 00000000..850c17a6 --- /dev/null +++ b/code/g3soft-libs/docs/app/components/content/ApiTable.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/code/g3soft-libs/docs/app/components/content/Demo.vue b/code/g3soft-libs/docs/app/components/content/Demo.vue new file mode 100644 index 00000000..0ecc70ce --- /dev/null +++ b/code/g3soft-libs/docs/app/components/content/Demo.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/code/g3soft-libs/docs/content/guide/getting-started.md b/code/g3soft-libs/docs/content/guide/getting-started.md new file mode 100644 index 00000000..9c32eeab --- /dev/null +++ b/code/g3soft-libs/docs/content/guide/getting-started.md @@ -0,0 +1,68 @@ +--- +title: 快速开始 +description: 安装组件库并在项目中用起来 +--- + +# 快速开始 + +## 安装 + +```bash +pnpm add @g3soft/ui @g3soft/tokens +``` + +`vue` 由宿主项目提供(`peerDependencies`),请确保已安装 Vue 3。 + +## 引入设计变量 + +在应用入口引入一次,组件样式全部依赖这套变量: + +```ts +// main.ts +import '@g3soft/tokens' +``` + +## 使用组件 + +按需引入: + +```vue + + + +``` + +或全量注册: + +```ts +import { G3UI } from '@g3soft/ui' +import { createApp } from 'vue' + +createApp(App).use(G3UI).mount('#app') +``` + +## 换肤 + +组件的颜色与尺寸一律引用 `--g3-*` 变量,定制只需覆盖同名变量,不必改组件代码: + +```css +:root { + --g3-color-primary: #1677ff; + --g3-radius: 6px; +} +``` + +暗色主题由 `html[data-g3-theme='dark']` 触发: + +```ts +document.documentElement.dataset.g3Theme = 'dark' +``` + +## 下一步 + +- 浏览[组件参考](/reference/ui/button) +- 了解[设计变量](/explain/why-tokens)的设计取舍 diff --git a/code/g3soft-libs/docs/content/index.md b/code/g3soft-libs/docs/content/index.md new file mode 100644 index 00000000..9657fcfa --- /dev/null +++ b/code/g3soft-libs/docs/content/index.md @@ -0,0 +1,89 @@ +--- +seo: + title: G3Soft 前端技术文档 + description: G3Soft 自研 Vue 3 组件库、设计变量与前端工程规范。 +--- + +:::u-page-hero +#title +自研组件,一套规范 + +#description +G3Soft 前端技术文档站:组件库 API、设计变量、工程规范与设计决策,全部集中在这里。 + +#links +:::u-button +--- +color: primary +size: xl +to: /guide/getting-started +trailing-icon: i-lucide-arrow-right +--- +快速开始 +::: + +:::u-button +--- +color: neutral +variant: outline +size: xl +icon: i-lucide-book-open +to: /reference/ui/button +--- +浏览组件 +::: +::: + +:::u-page-section +#title +四个内容域 + +#features +:::u-page-feature +--- +icon: i-lucide-rocket +to: /guide/getting-started +--- +#title +指南 + +#description +从安装到上手,以及版本升级与迁移说明。 +::: + +:::u-page-feature +--- +icon: i-lucide-component +to: /reference/ui/button +--- +#title +参考 + +#description +组件库 API 自动生成,另有 Hooks 与后端接口文档。 +::: + +:::u-page-feature +--- +icon: i-lucide-ruler +to: /standard/code-style +--- +#title +规范 + +#description +代码风格、命名约定、Git 与发布流程等团队工程规范。 +::: + +:::u-page-feature +--- +icon: i-lucide-lightbulb +to: /explain/why-tokens +--- +#title +解释 + +#description +设计决策背后的取舍与常见问题解答。 +::: +::: diff --git a/code/g3soft-libs/docs/content/reference/ui/button.md b/code/g3soft-libs/docs/content/reference/ui/button.md new file mode 100644 index 00000000..5bb5dcc8 --- /dev/null +++ b/code/g3soft-libs/docs/content/reference/ui/button.md @@ -0,0 +1,42 @@ +--- +title: Button 按钮 +description: 常用的操作按钮,支持多种视觉类型与状态 +--- + +# Button 按钮 + +常用的操作按钮,支持 7 种视觉类型、3 种尺寸与加载、禁用等状态。 + +## 基础用法 + +::demo{name="button/basic"} +:: + +## 视觉类型 + +语义化类型用于表达操作的风险等级。 + +::demo{name="button/type"} +:: + +## 尺寸 + +::demo{name="button/size"} +:: + +## 状态 + +::demo{name="button/state"} +:: + +## 图标与撑满 + +::demo{name="button/icon"} +:: + +::demo{name="button/block"} +:: + +## API + + diff --git a/code/g3soft-libs/docs/data/api/button.json b/code/g3soft-libs/docs/data/api/button.json new file mode 100644 index 00000000..90f64b2a --- /dev/null +++ b/code/g3soft-libs/docs/data/api/button.json @@ -0,0 +1,66 @@ +{ + "displayName": "Button", + "description": "常用的操作按钮。 支持 7 种视觉类型、3 种尺寸,以及加载、禁用、撑满、纯图标等状态。", + "props": [ + { + "name": "type", + "description": "视觉类型", + "type": "ButtonType", + "defaultValue": "default" + }, + { + "name": "size", + "description": "尺寸", + "type": "ButtonSize", + "defaultValue": "medium" + }, + { + "name": "htmlType", + "description": "原生 button 的 type 属性", + "type": "union", + "defaultValue": "button" + }, + { + "name": "disabled", + "description": "是否禁用", + "type": "boolean", + "defaultValue": "false" + }, + { + "name": "loading", + "description": "是否加载中:同时禁止点击并展示加载图标", + "type": "boolean", + "defaultValue": "false" + }, + { + "name": "block", + "description": "是否撑满父容器宽度", + "type": "boolean", + "defaultValue": "false" + }, + { + "name": "iconOnly", + "description": "是否仅图标:渲染为正方形按钮", + "type": "boolean", + "defaultValue": "false" + } + ], + "events": [ + { + "name": "click", + "description": "", + "type": "", + "defaultValue": "" + } + ], + "slots": [ + { + "name": "icon", + "description": "" + }, + { + "name": "default", + "description": "" + } + ] +} diff --git a/code/g3soft-libs/docs/examples/button/basic.vue b/code/g3soft-libs/docs/examples/button/basic.vue new file mode 100644 index 00000000..25f4e0b4 --- /dev/null +++ b/code/g3soft-libs/docs/examples/button/basic.vue @@ -0,0 +1,8 @@ + + + diff --git a/code/g3soft-libs/docs/examples/button/block.vue b/code/g3soft-libs/docs/examples/button/block.vue new file mode 100644 index 00000000..1c936a41 --- /dev/null +++ b/code/g3soft-libs/docs/examples/button/block.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/code/g3soft-libs/docs/examples/button/icon.vue b/code/g3soft-libs/docs/examples/button/icon.vue new file mode 100644 index 00000000..bdd036a9 --- /dev/null +++ b/code/g3soft-libs/docs/examples/button/icon.vue @@ -0,0 +1,11 @@ + + + diff --git a/code/g3soft-libs/docs/examples/button/size.vue b/code/g3soft-libs/docs/examples/button/size.vue new file mode 100644 index 00000000..ab356e50 --- /dev/null +++ b/code/g3soft-libs/docs/examples/button/size.vue @@ -0,0 +1,9 @@ + + + diff --git a/code/g3soft-libs/docs/examples/button/state.vue b/code/g3soft-libs/docs/examples/button/state.vue new file mode 100644 index 00000000..7f670dbe --- /dev/null +++ b/code/g3soft-libs/docs/examples/button/state.vue @@ -0,0 +1,20 @@ + + + diff --git a/code/g3soft-libs/docs/examples/button/type.vue b/code/g3soft-libs/docs/examples/button/type.vue new file mode 100644 index 00000000..c707395b --- /dev/null +++ b/code/g3soft-libs/docs/examples/button/type.vue @@ -0,0 +1,11 @@ + + + diff --git a/code/g3soft-libs/docs/nuxt.config.ts b/code/g3soft-libs/docs/nuxt.config.ts new file mode 100644 index 00000000..6d80204e --- /dev/null +++ b/code/g3soft-libs/docs/nuxt.config.ts @@ -0,0 +1,37 @@ +import { fileURLToPath } from 'node:url' + +/** + * 文档站(Docus)。 + * + * 几个刻意的选择: + * - extends: ['docus'] —— Docus 是 Nuxt Layer,全部能力(导航、搜索、主题)由它提供 + * - alias 直连 packages 源码 —— 组件库尚未构建也能开发,改组件即时热更 + * + * 部署到子路径时用环境变量 NUXT_APP_BASE_URL=/docs/,不在配置里写死。 + */ +export default defineNuxtConfig({ + extends: ['docus'], + + // sitemap.xml、llms.txt、OG image 都依赖站点 URL,缺了会导致预渲染 500 + site: { + url: process.env.DOCS_SITE_URL || 'https://ui.g3soft.dev', + name: 'G3Soft UI', + }, + + vite: { + resolve: { + alias: { + '@g3soft/ui': fileURLToPath(new URL('../packages/ui/src/index.ts', import.meta.url)), + '@g3soft/tokens': fileURLToPath( + new URL('../packages/tokens/src/index.css', import.meta.url), + ), + }, + }, + server: { + fs: { + // 组件库源码在 docs 目录之外,需要放开读取范围 + allow: [fileURLToPath(new URL('..', import.meta.url))], + }, + }, + }, +}) diff --git a/code/g3soft-libs/docs/package.json b/code/g3soft-libs/docs/package.json new file mode 100644 index 00000000..64332f13 --- /dev/null +++ b/code/g3soft-libs/docs/package.json @@ -0,0 +1,20 @@ +{ + "name": "@g3soft/docs", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "nuxt dev", + "build": "nuxt build", + "generate": "nuxt generate", + "preview": "nuxt preview" + }, + "dependencies": { + "@g3soft/tokens": "workspace:*", + "@g3soft/ui": "workspace:*", + "better-sqlite3": "^12.11.1", + "docus": "^5.14.0", + "nuxt": "4.4.8", + "vue": "catalog:" + } +} diff --git a/code/g3soft-libs/package.json b/code/g3soft-libs/package.json new file mode 100644 index 00000000..eb748948 --- /dev/null +++ b/code/g3soft-libs/package.json @@ -0,0 +1,25 @@ +{ + "name": "g3soft-libs", + "version": "0.0.0", + "private": true, + "type": "module", + "packageManager": "pnpm@11.5.0", + "engines": { + "node": ">=20.19.0" + }, + "scripts": { + "dev": "pnpm --filter @g3soft/docs dev", + "build:docs": "pnpm --filter @g3soft/docs generate", + "preview:docs": "pnpm --filter @g3soft/docs preview", + "build": "pnpm -r --filter \"./packages/**\" build", + "gen:api": "node scripts/gen-api.mjs", + "changeset": "changeset", + "version": "changeset version", + "release": "pnpm build && changeset publish" + }, + "devDependencies": { + "@changesets/cli": "^2.29.0", + "typescript": "catalog:", + "vue-docgen-api": "^4.79.0" + } +} diff --git a/code/g3soft-libs/packages/tokens/package.json b/code/g3soft-libs/packages/tokens/package.json new file mode 100644 index 00000000..676e198e --- /dev/null +++ b/code/g3soft-libs/packages/tokens/package.json @@ -0,0 +1,22 @@ +{ + "name": "@g3soft/tokens", + "version": "0.0.1", + "description": "G3Soft 设计变量(颜色 / 间距 / 圆角 / 字体 / 动效),组件库与文档站共用", + "license": "UNLICENSED", + "type": "module", + "files": [ + "src" + ], + "sideEffects": [ + "*.css" + ], + "exports": { + ".": "./src/index.css", + "./tokens.css": "./src/tokens.css", + "./dark.css": "./src/dark.css", + "./package.json": "./package.json" + }, + "publishConfig": { + "access": "restricted" + } +} diff --git a/code/g3soft-libs/packages/tokens/src/dark.css b/code/g3soft-libs/packages/tokens/src/dark.css new file mode 100644 index 00000000..831502be --- /dev/null +++ b/code/g3soft-libs/packages/tokens/src/dark.css @@ -0,0 +1,21 @@ +/** + * 暗色主题:只覆盖变量值,不改变量名。 + * 启用方式:document.documentElement.dataset.g3Theme = 'dark' + */ +html[data-g3-theme='dark'] { + --g3-color-primary: #4096ff; + --g3-color-primary-hover: #69b1ff; + --g3-color-primary-active: #1677ff; + + --g3-text-1: rgba(255, 255, 255, 0.88); + --g3-text-2: rgba(255, 255, 255, 0.65); + --g3-text-3: rgba(255, 255, 255, 0.45); + --g3-text-disabled: rgba(255, 255, 255, 0.3); + --g3-text-inverse: #ffffff; + + --g3-bg-container: #141414; + --g3-bg-disabled: rgba(255, 255, 255, 0.08); + --g3-border-color: #424242; + + --g3-shadow: 0 2px 8px rgba(0, 0, 0, 0.45); +} diff --git a/code/g3soft-libs/packages/tokens/src/index.css b/code/g3soft-libs/packages/tokens/src/index.css new file mode 100644 index 00000000..a0297b75 --- /dev/null +++ b/code/g3soft-libs/packages/tokens/src/index.css @@ -0,0 +1,7 @@ +/** + * 设计变量总入口。 + * 组件样式一律引用 var(--g3-*),取值只在本包内定义。 + * 换肤 / 客户定制 = 覆盖同名变量,不需要改任何组件代码。 + */ +@import './tokens.css'; +@import './dark.css'; diff --git a/code/g3soft-libs/packages/tokens/src/tokens.css b/code/g3soft-libs/packages/tokens/src/tokens.css new file mode 100644 index 00000000..82aa7513 --- /dev/null +++ b/code/g3soft-libs/packages/tokens/src/tokens.css @@ -0,0 +1,62 @@ +/** + * G3Soft 设计变量(浅色主题 / 默认值) + * + * 命名规则:--g3-{类别}-{属性}[-{状态}] + * 组件不得写死颜色与尺寸,必须引用本文件中的变量。 + */ +:root { + /* ---------- 品牌色 ---------- */ + --g3-color-primary: #1677ff; + --g3-color-primary-hover: #4096ff; + --g3-color-primary-active: #0958d9; + --g3-color-success: #52c41a; + --g3-color-warning: #faad14; + --g3-color-danger: #ff4d4f; + + /* ---------- 文本 ---------- */ + --g3-text-1: rgba(0, 0, 0, 0.88); + --g3-text-2: rgba(0, 0, 0, 0.65); + --g3-text-3: rgba(0, 0, 0, 0.45); + --g3-text-disabled: rgba(0, 0, 0, 0.25); + --g3-text-inverse: #ffffff; + + /* ---------- 容器与边框 ---------- */ + --g3-bg-container: #ffffff; + --g3-bg-disabled: rgba(0, 0, 0, 0.04); + --g3-border-color: #d9d9d9; + + /* ---------- 圆角 ---------- */ + --g3-radius-sm: 4px; + --g3-radius: 6px; + --g3-radius-lg: 8px; + + /* ---------- 间距 ---------- */ + --g3-space-1: 4px; + --g3-space-2: 8px; + --g3-space-3: 12px; + --g3-space-4: 16px; + --g3-space-5: 24px; + --g3-space-6: 32px; + + /* ---------- 控件尺寸与字号 ---------- */ + --g3-control-height-sm: 24px; + --g3-control-height: 32px; + --g3-control-height-lg: 40px; + --g3-font-size-sm: 12px; + --g3-font-size: 14px; + --g3-font-size-lg: 16px; + + /* ---------- 字体 ---------- */ + --g3-font-family: + -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', + 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif; + --g3-font-family-mono: + ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono', Menlo, Consolas, monospace; + + /* ---------- 动效 ---------- */ + --g3-duration: 0.2s; + --g3-ease: cubic-bezier(0.645, 0.045, 0.355, 1); + + /* ---------- 阴影 ---------- */ + --g3-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); +} diff --git a/code/g3soft-libs/packages/ui/README.md b/code/g3soft-libs/packages/ui/README.md new file mode 100644 index 00000000..798d93c9 --- /dev/null +++ b/code/g3soft-libs/packages/ui/README.md @@ -0,0 +1,54 @@ +# @g3soft/ui + +G3Soft 通用 UI 组件库(Vue 3 + TypeScript)。 + +## 安装 + +```bash +pnpm add @g3soft/ui @g3soft/tokens +``` + +`vue` 通过 `peerDependencies` 声明,由宿主项目提供,请确保宿主已安装 Vue 3。 + +## 使用 + +样式变量来自 `@g3soft/tokens`,在应用入口引入一次: + +```ts +import '@g3soft/tokens' +``` + +按需引入组件: + +```vue + + + +``` + +也可以全量注册: + +```ts +import { G3UI } from '@g3soft/ui' +import { createApp } from 'vue' + +createApp(App).use(G3UI).mount('#app') +``` + +## 构建 + +```bash +pnpm build +``` + +产物在 `dist/`,包含 ESM 入口与类型声明。发布前会由 `prepublishOnly` 执行 `publint` 校验包结构。 + +## 约定 + +- 样式**不写 `scoped`**,统一用 `g3-` 前缀 + BEM 命名,便于消费方覆盖。 +- 每个 CSS 变量都带兜底值,保证未引入 tokens 时组件仍可正常显示。 +- 组件不写死颜色与尺寸,一律引用 `--g3-*` 变量。 diff --git a/code/g3soft-libs/packages/ui/package.json b/code/g3soft-libs/packages/ui/package.json new file mode 100644 index 00000000..cbb6d7b1 --- /dev/null +++ b/code/g3soft-libs/packages/ui/package.json @@ -0,0 +1,40 @@ +{ + "name": "@g3soft/ui", + "version": "0.0.1", + "description": "G3Soft 通用 UI 组件库", + "license": "UNLICENSED", + "type": "module", + "files": [ + "dist", + "README.md" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./style.css": "./dist/style.css", + "./package.json": "./package.json" + }, + "scripts": { + "build": "vite build", + "prepublishOnly": "publint" + }, + "peerDependencies": { + "vue": "^3.5.0" + }, + "dependencies": { + "@g3soft/tokens": "workspace:*" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^6.0.0", + "publint": "latest", + "vite": "^8.0.0", + "vite-plugin-dts": "latest", + "vue": "catalog:", + "vue-tsc": "^3.0.0" + }, + "publishConfig": { + "access": "restricted" + } +} diff --git a/code/g3soft-libs/packages/ui/src/button/Button.vue b/code/g3soft-libs/packages/ui/src/button/Button.vue new file mode 100644 index 00000000..655452e9 --- /dev/null +++ b/code/g3soft-libs/packages/ui/src/button/Button.vue @@ -0,0 +1,213 @@ + + + + + diff --git a/code/g3soft-libs/packages/ui/src/button/index.ts b/code/g3soft-libs/packages/ui/src/button/index.ts new file mode 100644 index 00000000..9465bfb6 --- /dev/null +++ b/code/g3soft-libs/packages/ui/src/button/index.ts @@ -0,0 +1,2 @@ +export { default as G3Button } from './Button.vue' +export type { ButtonProps, ButtonSize, ButtonType } from './types' diff --git a/code/g3soft-libs/packages/ui/src/button/types.ts b/code/g3soft-libs/packages/ui/src/button/types.ts new file mode 100644 index 00000000..6929f705 --- /dev/null +++ b/code/g3soft-libs/packages/ui/src/button/types.ts @@ -0,0 +1,29 @@ +/** 按钮视觉类型 */ +export type ButtonType = + | 'default' + | 'primary' + | 'success' + | 'warning' + | 'danger' + | 'text' + | 'link' + +/** 按钮尺寸 */ +export type ButtonSize = 'small' | 'medium' | 'large' + +export interface ButtonProps { + /** 视觉类型 */ + type?: ButtonType + /** 尺寸 */ + size?: ButtonSize + /** 原生 button 的 type 属性 */ + htmlType?: 'button' | 'submit' | 'reset' + /** 是否禁用 */ + disabled?: boolean + /** 是否加载中:同时禁止点击并展示加载图标 */ + loading?: boolean + /** 是否撑满父容器宽度 */ + block?: boolean + /** 是否仅图标:渲染为正方形按钮 */ + iconOnly?: boolean +} diff --git a/code/g3soft-libs/packages/ui/src/index.ts b/code/g3soft-libs/packages/ui/src/index.ts new file mode 100644 index 00000000..75407448 --- /dev/null +++ b/code/g3soft-libs/packages/ui/src/index.ts @@ -0,0 +1,21 @@ +import type { App, Plugin } from 'vue' +import G3Button from './button/Button.vue' + +export { G3Button } +export type { ButtonProps, ButtonSize, ButtonType } from './button/types' + +/** + * 可选的全量注册插件。 + * 按需 import 是主路径;这里只是为不熟悉按需引入的团队提供便利入口。 + */ +const components = { G3Button } + +export const G3UI: Plugin = { + install(app: App) { + Object.entries(components).forEach(([name, component]) => { + app.component(name, component) + }) + }, +} + +export default G3UI diff --git a/code/g3soft-libs/packages/ui/tsconfig.json b/code/g3soft-libs/packages/ui/tsconfig.json new file mode 100644 index 00000000..c5bb749e --- /dev/null +++ b/code/g3soft-libs/packages/ui/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "jsx": "preserve", + "strict": true, + "noImplicitOverride": true, + "esModuleInterop": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["vite/client"] + }, + "include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"] +} diff --git a/code/g3soft-libs/packages/ui/vite.config.ts b/code/g3soft-libs/packages/ui/vite.config.ts new file mode 100644 index 00000000..cf4f9c94 --- /dev/null +++ b/code/g3soft-libs/packages/ui/vite.config.ts @@ -0,0 +1,40 @@ +import { fileURLToPath } from 'node:url' +import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' +import dts from 'vite-plugin-dts' + +/** + * 组件库构建:产出 ESM + 类型声明。 + * + * 关键点: + * - vue 必须外置(external),否则包里会打进一份 Vue,消费方出现双实例 + * - preserveModules 保留源码结构,消费方能按需 tree-shaking + * - vite-plugin-dts 生成 dist/index.d.ts,配合 package.json 的 exports.types + */ +export default defineConfig({ + plugins: [ + vue(), + dts({ + // 只产出声明文件,JS 交给 vite 本体 + include: ['src'], + outDir: 'dist', + rollupTypes: true, + }), + ], + build: { + lib: { + entry: fileURLToPath(new URL('./src/index.ts', import.meta.url)), + formats: ['es'], + fileName: () => 'index.js', + }, + rollupOptions: { + external: ['vue'], + output: { + preserveModules: true, + preserveModulesRoot: 'src', + entryFileNames: '[name].js', + assetFileNames: 'style.css', + }, + }, + }, +}) diff --git a/code/g3soft-libs/pnpm-lock.yaml b/code/g3soft-libs/pnpm-lock.yaml new file mode 100644 index 00000000..ca9690f1 --- /dev/null +++ b/code/g3soft-libs/pnpm-lock.yaml @@ -0,0 +1,17368 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +catalogs: + default: + typescript: + specifier: ^5.9.0 + version: 5.9.3 + vue: + specifier: ^3.5.41 + version: 3.5.43 + +importers: + + .: + devDependencies: + '@changesets/cli': + specifier: ^2.29.0 + version: 2.31.1(@types/node@26.6.4) + typescript: + specifier: 'catalog:' + version: 5.9.3 + vue-docgen-api: + specifier: ^4.79.0 + version: 4.79.2(vue@3.5.43(typescript@5.9.3)) + + docs: + dependencies: + '@g3soft/tokens': + specifier: workspace:* + version: link:../packages/tokens + '@g3soft/ui': + specifier: workspace:* + version: link:../packages/ui + better-sqlite3: + specifier: ^12.11.1 + version: 12.11.1 + docus: + specifier: ^5.14.0 + version: 5.14.0(ef3cbfd5a7d4098d77feeb53de29bbf8) + nuxt: + specifier: 4.4.8 + version: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + vue: + specifier: 'catalog:' + version: 3.5.43(typescript@5.9.3) + + packages/tokens: {} + + packages/ui: + dependencies: + '@g3soft/tokens': + specifier: workspace:* + version: link:../tokens + devDependencies: + '@vitejs/plugin-vue': + specifier: ^6.0.0 + version: 6.0.9(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + publint: + specifier: latest + version: 0.3.25 + vite: + specifier: ^8.0.0 + version: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vite-plugin-dts: + specifier: latest + version: 5.1.2(@vue/language-core@3.3.12)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + vue: + specifier: 'catalog:' + version: 3.5.43(typescript@5.9.3) + vue-tsc: + specifier: ^3.0.0 + version: 3.3.12(typescript@5.9.3) + +packages: + + '@ai-sdk/gateway@4.0.104': + resolution: {integrity: sha512-4lTyt8a4BMfVz4QGo+VO5odakmYMX5kq+xiRgdQGGY7o/jP2WSasp6LvIvYvt/lHzz1MfE+xKTOJhz7mMwjynA==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/mcp@2.0.67': + resolution: {integrity: sha512-cMEif3Lbvh+FozPpBM5UPy6QQhH8v8L/u1kcR2UXp+86EfIDXIaIeOaH+wYCk2CfloFccUn1K8LJuPXqZMZsfw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@5.0.54': + resolution: {integrity: sha512-amqDxFnw9+dpVrDACRDGmExUUNOH9C1D2bhg/DqWJnamEOieDTXBBXLHujSby/0MqHdAFksnpE8Pzfqx6ABMBw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@4.0.22': + resolution: {integrity: sha512-1Jtmn36VNMOBo9CMUQrPqsR744qtqRloEiXpWCYS8ffPlhS2CrSNmoho5lPjp3R7EnkzBsGI6p51TA7fQJQZdA==} + engines: {node: '>=22'} + + '@ai-sdk/vue@4.0.128': + resolution: {integrity: sha512-Pfs91DPU1VmJam1qo3URYIpQO3RNSe7ws5Ro+aq5jv0KqLqX98uhOZQOIKoD2wqbp/CuN3ZtFoXoFqAhExwg6Q==} + engines: {node: '>=22'} + peerDependencies: + vue: ^3.3.4 + + '@alloc/quick-lru@5.3.0': + resolution: {integrity: sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA==} + engines: {node: '>=10'} + + '@antfu/install-pkg@2.1.0': + resolution: {integrity: sha512-sdg9NxU3zR4Mnawfbc/x6GB5Wf17WYud5qOuEuxXjaKpYpMkISSJEjItGebXJ2bQ4DIcly4NYH23mtkGJjvKUw==} + + '@apidevtools/json-schema-ref-parser@14.2.1': + resolution: {integrity: sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==} + engines: {node: '>= 20'} + peerDependencies: + '@types/json-schema': ^7.0.15 + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.29.7': + resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.29.7': + resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.29.7': + resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.29.7': + resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.29.7': + resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.29.7': + resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.29.7': + resolution: {integrity: sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.29.7': + resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.29.9': + resolution: {integrity: sha512-FFwIwzU+7SCOuxxV4YtJql6T9981ZVTm+FHO5GhVsRqCTdy0WwrEZh3l42ARpXruJUDGOptdduHW6Zr7pNPLNg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@bomb.sh/tab@0.0.19': + resolution: {integrity: sha512-dTRfo9Q9B+lbLG3JCu8a/AGQSfD2XXcFcnakQzVjSOX+VvR/s9zpsH8TlqV3iHqazniRn1Ypwd1hcRlXcu/4BA==} + hasBin: true + peerDependencies: + cac: ^6.7.14 + citty: ^0.1.6 || ^0.2.0 + commander: ^13.1.0 || ^14.0.0 || ^15.0.0 + peerDependenciesMeta: + cac: + optional: true + citty: + optional: true + commander: + optional: true + + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} + + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} + + '@capsizecss/unpack@4.0.1': + resolution: {integrity: sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==} + engines: {node: '>=18'} + + '@changesets/apply-release-plan@7.1.1': + resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} + + '@changesets/assemble-release-plan@6.0.10': + resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.31.1': + resolution: {integrity: sha512-uO05WTcRBwuVOJVSW8Cmpqw6q0WDL53ajGCMyszutvOe5toOnunbpM4jZzf+qxBOz7i0AzopZ8diBuewjmF40w==} + hasBin: true + + '@changesets/config@3.1.4': + resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.4': + resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==} + + '@changesets/get-release-plan@4.0.16': + resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@clack/core@1.5.1': + resolution: {integrity: sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.8.1': + resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} + engines: {node: '>= 20.12.0'} + + '@cloudflare/kv-asset-handler@0.4.2': + resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} + engines: {node: '>=18.0.0'} + + '@colordx/core@5.8.0': + resolution: {integrity: sha512-cG0QJAO6VkaRUlIb0zOzX9gfJgs1pjoOL9gZ/PK1kfvBs0GCkADu5oQh6gPxXgQnZ3gV575h+lQRC0NlMDTclA==} + + '@comark/vue@0.7.0': + resolution: {integrity: sha512-C63ObcCAiM5DKVDhWPz27pCRsvl0IG9XZJDGjFef1h/V4kS6lEjsoyepLdl4pvAPoSn6U0oGiJTgHLj5GCw2rQ==} + peerDependencies: + beautiful-mermaid: ^1.1.3 + katex: ^0.17.0 + shiki: ^4.3.1 + vue: ^3.5.0 + peerDependenciesMeta: + beautiful-mermaid: + optional: true + katex: + optional: true + shiki: + optional: true + + '@dxup/nuxt@0.4.1': + resolution: {integrity: sha512-gtYffW6OfWNvoLW+XD3Mx/K8uUq08PMGLYJoDxc92EzZAWqR0FhcR5iaLm5r/OxyGTKz+P5f5Y7Aoir9+SjYaw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@dxup/unimport@0.1.2': + resolution: {integrity: sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/core@1.11.2': + resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.3': + resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@fingerprintjs/botd@2.0.0': + resolution: {integrity: sha512-yhuz23NKEcBDTHmGz/ULrXlGnbHenO+xZmVwuBkuqHUkqvaZ5TAA0kAgcRy4Wyo5dIBdkIf57UXX8/c9UlMLJg==} + + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@floating-ui/vue@1.1.11': + resolution: {integrity: sha512-HzHKCNVxnGS35r9fCHBc3+uCnjw9IWIlCPL683cGgM9Kgj2BiAl8x1mS7vtvP6F9S/e/q4O6MApwSHj8hNLGfw==} + + '@hono/node-server@2.1.3': + resolution: {integrity: sha512-TA//nWMqPhbfdfneACk6t5a9eqbS9lABEPyKn0/xZTah3H3U2XaVg85rJFl0/Fyit0I552YDHgXGVSf3GwqbUw==} + engines: {node: '>=20'} + peerDependencies: + hono: ^4 + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@iconify-json/lucide@1.2.140': + resolution: {integrity: sha512-/br6j8K8IFcZscs7gJ20PWaaonQeA4jcGK0Bdt+4EDra2Zbtpb36RGaGOJr5opz6zJtXaZdMCYCXa0dN/y4c0g==} + + '@iconify-json/simple-icons@1.2.99': + resolution: {integrity: sha512-kouZhqvUoNdxEe+lZksbJJZMCZv4b4Ob62O1GW3fcpz/I0mVPzM+9/Qf/DUuv5ns8l6c46D8M/ubhJjjbLp9HQ==} + + '@iconify-json/vscode-icons@1.2.85': + resolution: {integrity: sha512-fXmil7MaVEtHo2bsdeCH4O36LwPC49FEHtyaTHamL2UEGp/6Uih+B5aVlZ9k95m+wphHBszk5CD3sF18Jp6SXw==} + + '@iconify/collections@1.0.747': + resolution: {integrity: sha512-MHGKbGI3HX22deRE1Oub/G8+4DT8a6gpUglSLEtkeSIQ1/N9shX/M84LnihW2v3n8nr1idioDV0dKH9AwkxNZQ==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.7': + resolution: {integrity: sha512-JZHlwdID+dy+lTgbYC8NEC4zeugqeYsc6jewvzb4c58kHauJn+X7rNwQjxz5p2qSjqaEeQoLkCIQ9v/H4PK0/w==} + + '@iconify/vue@5.0.3': + resolution: {integrity: sha512-e9x6QZe2/HyeHUog0jzZJSZts7m/YntPYp/p4OqtZEXpHznxWnQpcX30YpuaUH43h69l3YeR1FCJ8V1t3qd7qA==} + peerDependencies: + vue: '>=3.0.0' + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.5': + resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.5': + resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.5': + resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.4': + resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.4': + resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.4': + resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.4': + resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.4': + resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.4': + resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.4': + resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.4': + resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.5': + resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.5': + resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.5': + resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.5': + resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.5': + resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.5': + resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.5': + resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.5': + resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.5': + resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.5': + resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.5': + resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.5': + resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.5': + resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@internationalized/date@3.12.4': + resolution: {integrity: sha512-M1dEn4c1U1HsSlaVR8upZtSqvXrTkHDfv18H01uCSJyjVLDxnBR38v/fMxecmlwXKR4i9HeZcmgQAPE6A+aGJQ==} + + '@internationalized/number@3.6.8': + resolution: {integrity: sha512-8UmMFia46DUt+k97zKd9fKWXcWHR+k8ae3eYzILETuT2KbIvLyOfac7zesw+sJdRAAZ7Q9pM1Mk22aXp2LD0Ig==} + + '@intlify/bundle-utils@11.2.5': + resolution: {integrity: sha512-gl7CGygRALtuT4H8n/PNC0hubg4rnctPoT04//GZNsTemvJw0Q7i6jSaq0PZHxnH0cdGqyowNXmW4FYILbahzg==} + engines: {node: '>= 22.13'} + peerDependencies: + petite-vue-i18n: '*' + vue-i18n: '*' + peerDependenciesMeta: + petite-vue-i18n: + optional: true + vue-i18n: + optional: true + + '@intlify/core-base@11.4.13': + resolution: {integrity: sha512-3qGv1/j0fl6ZSeehGaznE78A4i3hCaOeOyDh7jq7SV6ch/XGoy96xIrYuALTV3xhIqj2rktsIKcwlLZ3CbOhkA==} + engines: {node: '>= 22'} + + '@intlify/core@11.4.13': + resolution: {integrity: sha512-0coNB/hGvF+l3ihiAA7E3Su2KUCJsw0OMMyiKkLDm44ecvu3UiNeqOsOktB1K3x6/NubUbn3JAI5XcUrKGsv+A==} + engines: {node: '>= 22'} + + '@intlify/devtools-types@11.4.13': + resolution: {integrity: sha512-f38d2yvjNc1/c+BnTLsxTB0729clTtyy7kTxHu4FFlvI6FpmBOp7b9sLYtsKJpXSZ70kIEexvNwDSzLkIlYnlQ==} + engines: {node: '>= 22'} + + '@intlify/h3@0.7.4': + resolution: {integrity: sha512-BtL5+U3Dd9Qz6so+ArOMQWZ+nV21rOqqYUXnqwvW6J3VUXr66A9+9+vUFb/NAQvOU4kdfkO3c/9LMRGU9WZ8vw==} + engines: {node: '>= 20'} + + '@intlify/message-compiler@11.4.13': + resolution: {integrity: sha512-cjKsDeWUD/i3mj0QtC8hydLCFP5mgZtTU1xZZaN9/O3FG94EXc0rTbecYpifglp26rpoJoIjSlW137VejLKsZw==} + engines: {node: '>= 22'} + + '@intlify/shared@11.4.13': + resolution: {integrity: sha512-ZjcNgEED1FtTCFb+ohWBdR21k5kvleKtM9peobQtLB83mNIfEhJK86dEbhfk+OcUrybrEbc4eDeE9UbFUVHsjQ==} + engines: {node: '>= 22'} + + '@intlify/unplugin-vue-i18n@11.2.5': + resolution: {integrity: sha512-wLpS0cZTNAzaNL/STjjwSFhLunuoARKzEJh7jM/G00A40cVH+GEPhdo/WsvnesPvQVoN6JfjI/mGXwDNnTbvhg==} + engines: {node: '>= 22.13'} + peerDependencies: + petite-vue-i18n: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.2.25 + vue-i18n: '*' + peerDependenciesMeta: + petite-vue-i18n: + optional: true + vite: + optional: true + vue-i18n: + optional: true + + '@intlify/utils@0.13.0': + resolution: {integrity: sha512-8i3uRdAxCGzuHwfmHcVjeLQBtysQB2aXl/ojoagDut5/gY5lvWCQ2+cnl2TiqE/fXj/D8EhWG/SLKA7qz4a3QA==} + engines: {node: '>= 18'} + + '@intlify/utils@0.14.1': + resolution: {integrity: sha512-/NVDhX6sG87h0PXIwUCTW9DeHbKeqlni6qVV8xzMULQRHE9azIETldBlTKaBji7z6ostyDIH4s6SWI3AAI4uFg==} + engines: {node: '>= 20'} + + '@intlify/vue-i18n-extensions@8.0.0': + resolution: {integrity: sha512-w0+70CvTmuqbskWfzeYhn0IXxllr6mU+IeM2MU0M+j9OW64jkrvqY+pYFWrUnIIC9bEdij3NICruicwd5EgUuQ==} + engines: {node: '>= 18'} + peerDependencies: + '@intlify/shared': ^9.0.0 || ^10.0.0 || ^11.0.0 + '@vue/compiler-dom': ^3.0.0 + vue: ^3.0.0 + vue-i18n: ^9.0.0 || ^10.0.0 || ^11.0.0 + peerDependenciesMeta: + '@intlify/shared': + optional: true + '@vue/compiler-dom': + optional: true + vue: + optional: true + vue-i18n: + optional: true + + '@ioredis/commands@1.10.0': + resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 + + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@mapbox/node-pre-gyp@2.0.3': + resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} + engines: {node: '>=18'} + hasBin: true + + '@miyaneee/rollup-plugin-json5@1.2.0': + resolution: {integrity: sha512-JjTIaXZp9WzhUHpElrqPnl1AzBi/rvRs065F71+aTmlqvTMVkdbjZ8vfFl4nRlgJy+TPBw69ZK4pwFdmOAt4aA==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + '@modelcontextprotocol/sdk@1.32.1': + resolution: {integrity: sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} + engines: {node: ^22.20 || ^24.12 || >=25} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@napi-rs/wasm-runtime@1.2.5': + resolution: {integrity: sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + + '@noble/hashes@2.4.0': + resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==} + engines: {node: '>= 20.19.0'} + + '@nodable/entities@3.1.0': + resolution: {integrity: sha512-LsS/DjHr+uDM647Gru/cA8+J3a3HfhttwCKLyuoyN7yXTFCxKBtSgMQBvrW9yNPa2/zDRUNuGPaH5QUFoa4arQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nuxt/cli@3.37.0': + resolution: {integrity: sha512-Zj9NwHjEBzVrgezsgMFjpMhNqwNgROk9DzNi/dyfk1mCbXIRigV11br2xOl0Satek30bmv7oZAfMtCnDe6Ip0Q==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@nuxt/schema': ^4.4.6 + peerDependenciesMeta: + '@nuxt/schema': + optional: true + + '@nuxt/content@3.16.1': + resolution: {integrity: sha512-h+oqO9hJwvyK2jtBeCkF9ZhLq0euQUFyOOM2oCtAyd1WFL43n0tkqA6DJHnB177sQnxuO5M2pnXp4tjutSs0Gw==} + engines: {node: '>= 20.19.0'} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + '@valibot/to-json-schema': ^1.5.0 + better-sqlite3: ^12.5.0 || ^13.0.0 + sqlite3: '*' + valibot: ^1.2.0 + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + '@valibot/to-json-schema': + optional: true + better-sqlite3: + optional: true + sqlite3: + optional: true + valibot: + optional: true + + '@nuxt/devalue@2.0.2': + resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} + + '@nuxt/devtools-kit@3.4.2': + resolution: {integrity: sha512-TPPbmH9xrExagYxfCe6JgtbHmgchfgDdA656Yws18rn8I/oCvB+gcw3kTWBBp2sC9ipZPXsgbsW/yZnVnGNBiA==} + peerDependencies: + vite: '>=6.0' + + '@nuxt/devtools-kit@4.0.0-alpha.7': + resolution: {integrity: sha512-Tgh+tSejh1GnZjdjgWyc4qCxskeX08XuSQBYMn/4SIV5AubeqYeAOMBD2qSmHOXjMCUpgyzpEhODcP3sgdgGRA==} + peerDependencies: + vite: '>=6.0' + + '@nuxt/devtools-wizard@3.4.2': + resolution: {integrity: sha512-U2G8fw7KW1rdECyJDho5N14z8hSllpTk430KG1QPLjrv5w3pDksZ+YcpITd0u762Vw3gq3Arpg65Bk6U4ua6aQ==} + hasBin: true + + '@nuxt/devtools@3.4.2': + resolution: {integrity: sha512-Nidg0/zB710cyK89ltTkv66hMfPlIPlKA+Yb67bIrAkNm5PoTwQ1goHdFWHIAGZ9nTadcVTzATwMwa56nvl/Wg==} + hasBin: true + peerDependencies: + '@vitejs/devtools': '*' + vite: '>=6.0' + peerDependenciesMeta: + '@vitejs/devtools': + optional: true + + '@nuxt/fonts@0.14.0': + resolution: {integrity: sha512-4uXQl9fa5F4ibdgU8zomoOcyMdnwgdem+Pi8JEqeDYI5yPR32Kam6HnuRr47dTb97CstaepAvXPWQUUHMtjsFQ==} + + '@nuxt/icon@2.5.1': + resolution: {integrity: sha512-zBP72Po7BS+tXzoeDRA/Y9TTY77OIcNCyzfgXsOmep7zZShTEoe4p1WZBXce/9oJDK3YXmbYC3ILQ7XvqM4/XA==} + + '@nuxt/image@2.1.0': + resolution: {integrity: sha512-UzAYq25uhwH1G6jvZBn/SwmniJr77fgF8KzbwUI3MuSdkIP3WQqt/F5wWKXgbGgAWWZGt8Vv2NQ0WZgFuxUBgQ==} + engines: {node: ^20.19.0 || >=22.3.0} + + '@nuxt/kit@4.4.8': + resolution: {integrity: sha512-ZUlZ5iYfyfJFDPluhn6ZxFWcsuxWbLnZBc8w3MAROcQ4lYfZ+qFpALBLSNlpc0zhOa++33EE+5PEbOAdVIY+dw==} + engines: {node: '>=18.12.0'} + + '@nuxt/kit@4.6.0': + resolution: {integrity: sha512-UXTajJ+MFJgwV9UL1CTNNd2PSw5PC3Pjb2rM7FsSYcr92ySQKXEslBnUKbvnXT+gG3NbZ/EF70+WenoNIHX2tw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@nuxt/schema': ^3.0.0 || ^4.0.0 || ^5.0.0-0 + confbox: '>=0.1.0' + dotenv: '*' + giget: '>=3.1.0' + jiti: ^2.0.0 + mlly: ^1.2.0 + oxc-parser: '>=0.56.0' + rolldown: '>=1.0.0' + peerDependenciesMeta: + '@nuxt/schema': + optional: true + confbox: + optional: true + dotenv: + optional: true + giget: + optional: true + jiti: + optional: true + mlly: + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + + '@nuxt/nitro-server@4.4.8': + resolution: {integrity: sha512-cc1fxgSx34Htesx3JBO+hMhbqd6VljXDC06P+UOA5z53cR224TmEFYT/MUuZDkrtt4qLnSG8yq0IxhEM3NCUlw==} + engines: {node: ^22.12.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@babel/plugin-proposal-decorators': ^7.25.0 + '@babel/plugin-syntax-typescript': ^7.25.0 + '@rollup/plugin-babel': ^6.0.0 || ^7.0.0 + nuxt: ^4.4.8 + peerDependenciesMeta: + '@babel/plugin-proposal-decorators': + optional: true + '@babel/plugin-syntax-typescript': + optional: true + '@rollup/plugin-babel': + optional: true + + '@nuxt/schema@4.4.8': + resolution: {integrity: sha512-igfWuMF0x0Pmx/XwhPwH/bcXgbuwNnjUjqxCAsY6VQhmGKo0e9soJq3Q0ohj+rBkBfX6o2ysTP1/t2M82aK4qA==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/schema@4.6.0': + resolution: {integrity: sha512-lwAA2MDJ5WkNKqIpNnvH3gK1aHfh3DK8evQNbun+nzMKPP7MqpQ6rs/UClqTnhhhTwqkw0b6Sm24VRCVw7f4Tw==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/telemetry@2.9.1': + resolution: {integrity: sha512-WYQs6GvebU278YXhbGlLA8pUO3ox+juHAiKCB3SEH0lq2PDRwX465tHRtpVIqsHv+lGK/n99FC7qqyBt9+p3oQ==} + engines: {node: '>=18.12.0'} + hasBin: true + peerDependencies: + '@nuxt/kit': '>=3.0.0' + + '@nuxt/ui@4.11.3': + resolution: {integrity: sha512-GbA/Xyg0R0sZhUqM7tc70j9Qr8GxyHnX0OenRuYRztVzgG3BtxafwZrN22xV36LH31ZEWabKj7CLDCDsVLSFPw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@inertiajs/vue3': ^2.0.7 || ^3 + '@internationalized/date': ^3 + '@internationalized/number': ^3 + '@nuxt/content': ^3 + '@tiptap/core': ^3 + '@tiptap/extension-bubble-menu': ^3 + '@tiptap/extension-code': ^3 + '@tiptap/extension-collaboration': ^3 + '@tiptap/extension-drag-handle': ^3 + '@tiptap/extension-drag-handle-vue-3': ^3 + '@tiptap/extension-floating-menu': ^3 + '@tiptap/extension-horizontal-rule': ^3 + '@tiptap/extension-image': ^3 + '@tiptap/extension-mention': ^3 + '@tiptap/extension-node-range': ^3 + '@tiptap/extension-placeholder': ^3 + '@tiptap/markdown': ^3 + '@tiptap/pm': ^3 + '@tiptap/starter-kit': ^3 + '@tiptap/suggestion': ^3 + '@tiptap/vue-3': ^3 + ai: ^6 || ^7 + joi: ^18 + superstruct: ^2 + tailwindcss: ^4 + typescript: ^5.6.3 || ^6 || ^7 + valibot: ^1 + vue-router: ^4.5.0 || ^5 + yup: ^1.7.0 + zod: ^3.24.0 || ^4 + peerDependenciesMeta: + '@inertiajs/vue3': + optional: true + '@internationalized/date': + optional: true + '@internationalized/number': + optional: true + '@nuxt/content': + optional: true + ai: + optional: true + joi: + optional: true + superstruct: + optional: true + valibot: + optional: true + vue-router: + optional: true + yup: + optional: true + zod: + optional: true + + '@nuxt/vite-builder@4.4.8': + resolution: {integrity: sha512-54M/k6qVY85Qeoe1m/lPZ0SANGJEbI50r5uYgh3XT942ENve3K5Nk6TMYp8i5wGGC4TWvPea+1mlCrp8rjsXag==} + engines: {node: ^22.12.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@babel/plugin-proposal-decorators': ^7.25.0 + '@babel/plugin-syntax-jsx': ^7.25.0 + nuxt: 4.4.8 + rolldown: ^1.0.0-beta.38 + rollup-plugin-visualizer: ^6.0.0 || ^7.0.1 + vue: ^3.3.4 + peerDependenciesMeta: + '@babel/plugin-proposal-decorators': + optional: true + '@babel/plugin-syntax-jsx': + optional: true + rolldown: + optional: true + rollup-plugin-visualizer: + optional: true + + '@nuxtjs/color-mode@4.0.1': + resolution: {integrity: sha512-eiA7hWXi5zNHaYKyJFCGF6i0wFZtuvR7KDXZ6jiSvwxjCpRFwphrw0MOSmNfArTSSsT1wpW+/2H92cejeVfUlg==} + + '@nuxtjs/i18n@10.6.0': + resolution: {integrity: sha512-20YXYOcc8cSh/pSpNgj+MHAn11qUbsFR1IBJh6qYtRPVhUUmgqJ1DyMu39MB+uEYYL/fsberL2ByMYrFaROslw==} + engines: {node: '>=20.11.1'} + + '@nuxtjs/mcp-toolkit@0.22.0': + resolution: {integrity: sha512-RnIKy0ePgFG5NchJ4TZCGW85jiRbBpMdF9CZBSaSvAQKulePEZy7hgKQEpohQgtkZTq6pxv+B9oKCofhibwMzA==} + peerDependencies: + '@vue/compiler-sfc': ^3.5.43 + agents: '>=0.24.0' + h3: '>=1.15.11' + secure-exec: '>=0.3.3' + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.5.43 + zod: ^4.1.13 + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true + agents: + optional: true + secure-exec: + optional: true + vite: + optional: true + vue: + optional: true + + '@nuxtjs/mdc@0.23.2': + resolution: {integrity: sha512-oM6wCKROrLg0g4qLG/cg/M9yMFLsqJxWH1tIjpf4L9uxzJ2twhRxVgKWXaiBNF/W0BoNkJ/kr1qpAJBj6fQSog==} + + '@nuxtjs/robots@6.2.4': + resolution: {integrity: sha512-+MyHUT6fAqJHnGPxzSrPgXCp+giH04A9aS4RwSvjgHDzYQ+xOqpaSy8jb7U7sPlXmPZE2Et3ened9ccfmwGPKA==} + peerDependencies: + zod: '>=3' + peerDependenciesMeta: + zod: + optional: true + + '@nuxtjs/sitemap@8.6.1': + resolution: {integrity: sha512-8tjWb0poZZSRUkJG9AICPn5TskHyxVRQDH9T8PXD1LCcDYuTqPbsJ7tB0qwbS7OFrTHQHcBWcnHX7MNdgLO77Q==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: '>=3' + peerDependenciesMeta: + zod: + optional: true + + '@oxc-minify/binding-android-arm-eabi@0.133.0': + resolution: {integrity: sha512-D8M1+nqwLaACHZsld/t6f+cE4N97XOu5iQ88f1ZaYH4ptFzFrXo5N7wUKACTI4xmNUD+6W0Y4Apk5U2r8HLdBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-minify/binding-android-arm64@0.133.0': + resolution: {integrity: sha512-dnQUJdpOEh/nZfQtvGGN61VcCCcPJ2aCm+ndl8GIA2lk2GpmIBgZ9h+phLVhgUFGt2es+2AQc0xvtK7RFNsViw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-minify/binding-darwin-arm64@0.133.0': + resolution: {integrity: sha512-K6+aXlOlsCcibpTiTitQYNXWGGwea0fEKF/kGHCNB+MNqOLCkdC7wesycaABYcXcyr58DhDoJnVb8E4Hq95iVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-minify/binding-darwin-x64@0.133.0': + resolution: {integrity: sha512-BFEXHxYNwThyaO63p1VE5MOOXNGkHsHfkmajOCKXH40TfllTHQenXhpJ9mHDoF7EhaQjArpPjlDY88BuPjhurw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-minify/binding-freebsd-x64@0.133.0': + resolution: {integrity: sha512-oT5dbcXnS/cbpdXCpudAeVg/fqH1XnKhLUE/vkuRTuocjOd/GA2MoNMMhLWUvqNXO0xJnYmo2ISmDxShkItfOQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-minify/binding-linux-arm-gnueabihf@0.133.0': + resolution: {integrity: sha512-tJ3B+b7DOuTsIMXSmu5xHHCakrBqqcrp4COYd/lelOdDvkbFoDRGnwH91POUOSUEOI/WLzIMkDqAH2SZ3N2jhQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-minify/binding-linux-arm-musleabihf@0.133.0': + resolution: {integrity: sha512-XMUHfdilk1KTtOM2vA1bwDso07/wkLm/GgDOO9z/ioxrZoQyjXnJRW665VXa08z2BqEgwHRc1zH9p7s6sKPQbg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-minify/binding-linux-arm64-gnu@0.133.0': + resolution: {integrity: sha512-UEff2jopbwJ4SndmxK06uqXrOpwWiJERJPdgDTBywwXP9QgW0p1YkQnBNt4+jK0I/hdLpbbyaCLLuUPKbaU70w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-arm64-musl@0.133.0': + resolution: {integrity: sha512-yqskeIapQvx7Tu/OLsepLPcGsHGzfYy9PX6gIbhaOHfF+LA2zHBKnKb587FGx+lQjHLQR0llfmoSuXQ6q2EN+A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-minify/binding-linux-ppc64-gnu@0.133.0': + resolution: {integrity: sha512-r7PnUNxRB9D/gQjCVeasoieJVUF48n43rvk/jYbGAw9sRfYGoEo/rOs0GyTZU9ttss8HzjBaerAbADbAL8K8vw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-riscv64-gnu@0.133.0': + resolution: {integrity: sha512-omXWC8I9lAMMjQIeadfItP5H4VDAiuU2BiVCtHMH3ktTbFq04sxscZhK4NFUUuw3fApDdXmfd7LW18q0JBHarg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-riscv64-musl@0.133.0': + resolution: {integrity: sha512-LtFA3Hi8LVD/zuiPLKy9Aiz7N1IOj8rRhdXiW38GKQ9mAhj+Ko6IHGcTk2A7yNDA1DZBl7r+Qd4PEGWgVelPPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-minify/binding-linux-s390x-gnu@0.133.0': + resolution: {integrity: sha512-rFsPDsT1j3beSInbrFukAAlTg101PcqdVMXDioR9AgJ1180tZ8s8D+pNDpQTRmPd3956mnpAE+Cs77Xoo/QZAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-x64-gnu@0.133.0': + resolution: {integrity: sha512-xlrtAmDWZI8BEmsaXMYfblWuLIY5UnnRkit1VLkmVDb5ceZRZf4oEXK1QeYf5Z33dT0WK1Ek++P+TL/ZMCpyGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-x64-musl@0.133.0': + resolution: {integrity: sha512-kd36CDkTkZDMNfVceNTSfpWnitE1+GjZmzJCeq8yaxsgvs/MXg8aauI2RgFjElYZIHSMyZku4pQ7Jtl3ZEYI6w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-minify/binding-openharmony-arm64@0.133.0': + resolution: {integrity: sha512-pI38dJBqfkNbFoL/GEarAzGDjKGVCZTdg0a8NKh1PP9GqWleXT6HLtXE4CZ+54e+2u68qVYVBwhbWAiRfwlUZA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-minify/binding-wasm32-wasi@0.133.0': + resolution: {integrity: sha512-AkLr+d+LLY4/55J/TrE0srNBUpZPzyU+cygdse7yZ9AhCndryNqe2y6e8naVK0TV7n8lxBd2OGGJAkho6blAkw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-minify/binding-win32-arm64-msvc@0.133.0': + resolution: {integrity: sha512-V92v7397t2073g+mSfaLHnPeoz6hA/1U4JNLeUBP87eWGZgVxDZ2qz3t3wFyYqXGJ/0VoEwdP8yrHLQQ7QzAOQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-minify/binding-win32-ia32-msvc@0.133.0': + resolution: {integrity: sha512-2DP5RbG/SSaRVtmuwgTH6Ati4+uuOJjoI88dQnC5hD0zCC90EVDXZSXyJQ5i/OxLE1UAy58Wo2DJot/OrUspzA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-minify/binding-win32-x64-msvc@0.133.0': + resolution: {integrity: sha512-PJ75c6PlBx87tau0W35J43eGCv4wrDmdZ+4ddTZAnGtZqEeCVsLdmDPOEMe2DepogqlSVUF2kGBWtnFUJ5c7Rw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-parser/binding-android-arm-eabi@0.133.0': + resolution: {integrity: sha512-l/44caGse+VpnY9gx0yvvc5QnnG3yG1FO3KZgYvNL1GZrfK86zIwAOgGEVlxDyRymzrU/KHiblPFpevKOmJmUA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm-eabi@0.139.0': + resolution: {integrity: sha512-22EsXTA3Vc7OvrF4bfT48PFln2UbxkVgrp/Tm32qLw76Dv7SmcInfClJe6yPYamnli6HiqasnESZ5ezN+X4ybg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm-eabi@0.141.0': + resolution: {integrity: sha512-jk7086MFvR/T4DG9IY7MKBVt1PMxvSZoz/TvnifodvS0pjghVwJHRttnAExhlwdMOgHv1TmLdENnbNpYk2zjvA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm-eabi@0.151.0': + resolution: {integrity: sha512-QLfrdT2XmHMo8krBiKHtnTtU2ugxruwnIWMcIl5qpCRV9KPZk1s2YZzSHkIjzabLxG6/1yOoDLvqfS3TrJhfWA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.133.0': + resolution: {integrity: sha512-KUHmPMziLBp4u+zbrLdB7iWS7KshuZe+RAp7ELnY9SI9nNXBZ+dp8fiBqWOxhXqn+FQg3a4UcQhwmsJOKV8Jjg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-android-arm64@0.139.0': + resolution: {integrity: sha512-uASQkZV+CUQ6xXvoMzDQyfhd8OMusdv2FyCPfAi5ZDYptesapJlw7erhpGi1Lc+U8QjQV2JUrIh7d/3su2LzmQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-android-arm64@0.141.0': + resolution: {integrity: sha512-a4XDQ27ZT7e7zwAlxJDTiCA7IBGWDuy2+MhFq85Of7XlBSmpkfcBFml11q0Zx6f7RMuI0B4xCtt2ytBS4yOptg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-android-arm64@0.151.0': + resolution: {integrity: sha512-APzs9QxkLGR85I6Slb93Onsd+9ZdR+PdKIy0g8oOuipiBRtXbEE3PW1QpRn3O2C9dCsfAC8+t7dWGRyByiTqJQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.133.0': + resolution: {integrity: sha512-q8dWmnU/8ea2tga9w2f1PinQ5rcMPDUGkF64T189b65YMjUomET4oy5oRldOr4AwOQkneOG/Zttnz1Dvrc62wg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-arm64@0.139.0': + resolution: {integrity: sha512-vuQOv2WF5pZCkdSPEExul98o853M3MCR24DpWsGrUoPJu5KcnGE34kLXY2yFwBwZwT+eN1x40Tt4q6ZzlEdNUA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-arm64@0.141.0': + resolution: {integrity: sha512-m/kVk6rzYmBeHYnz+1Y5fod00AVTTxMbC71azFfm/zjx1j9XxwKtA0+VfkKuVMC8rbghb9TtfevnuWZa9OuPEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-arm64@0.151.0': + resolution: {integrity: sha512-uPj085g+2TcYKm4LrPOF6mU/ilb48ghAfLMA+YIxaSAasgDAXO0c5UMjRrB9L59A1aMU9fvPtCGoW9cov9UtFQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.133.0': + resolution: {integrity: sha512-cOKeIELIB2bJnCKwqx4Rdj+1Lss/U6uCbLxRySZrhyOOQa1flKhwZFjEHRHxk8fU1NKmhK5OnTdPQ4CpjuFuVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.139.0': + resolution: {integrity: sha512-zxZB8ChS+7XactZhcyxQ292P/DNiiBaPPKYiVUlb3RC0V/hme5bokNubjcmEmbW9uTfmqLTpveAdkbe66H3pGg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.141.0': + resolution: {integrity: sha512-o0X+6KZlfucWU/v5oKRQPwdFXsXAjW8jmpo/Gpw/qyKsbKtlfkHoeH9Bjp/m13TwjewvJnCkwF0DWzgpC4HjTQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.151.0': + resolution: {integrity: sha512-gqOyGZsEX9r8i37ONL2X8heUKCbTAY3UvaWlEJKPJYdgaYoIAXSuZrG27legT+0e4m0X/53RupoH6lfbxtMiMw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.133.0': + resolution: {integrity: sha512-OpaSv4pW3KgFrMYQxTaS0aOE4T1DQF3qZE/4B6uqqv1KgPWWd4UQhJALi8PJPX1RRV5K7ThKXRfF7qGg2+3l1A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-freebsd-x64@0.139.0': + resolution: {integrity: sha512-iw2MsoCPBQwdJqywRAGsF1jEAcGoZ+DeG2LVzt5pdUvRHqajsMF46BH0rHiWoWtMwcMSia+oQYga7fHo7u7Bcw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-freebsd-x64@0.141.0': + resolution: {integrity: sha512-W5KbTnNkTMMMylqj6dYqnsXvkmESVPodPKYLJ5zdzIPdl9fUJtolkpUeSzYEbGGYB4a4A4avl3EePnZ/wLIdJg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-freebsd-x64@0.151.0': + resolution: {integrity: sha512-Uih9lYFoB9k87b8jZ2263b8/HC0AuCQo9qPfu14KjoDmC7AmGvo4pCLiuEVVHjQycUjTO2dNtG39MIGUuCOx3A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.133.0': + resolution: {integrity: sha512-JGK1wlGrGwxBIlVSF7KWTX1/ru6BEtf28fRROztDRkLfiW+Kxa4onnriezMIiogfn9hVw2KzYcKiLjkLR2ns8A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.139.0': + resolution: {integrity: sha512-SwjD/k3Y5bwGJWOH313VyaDrAuaYg1Pe+4AAXCgUKvSO5IHkj+mZ0oFcOWmB5nTuOM3uwdT+leL8h4OnFlI5hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.141.0': + resolution: {integrity: sha512-g3dtbJa8zeOGK36Sr9cQavsdi5H/ie2hVjrSjIxsNAR1qZA40ZYVXnfdfoMAlq8CmB9qFL1yhsSCUHeNmdmt8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.151.0': + resolution: {integrity: sha512-BW9ryFV0V7h37xAEpb1rx+jI/ArFjXlSvJ2CaPwqxCj+kcJdDMvt5/PpWLRRk56UpNpxpq/5+puTUd0/4OPCZw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.133.0': + resolution: {integrity: sha512-yuZO533Ftonxn/iyoqQzURzLQHMspvsIyfiCSNi1t/ER4eIQaR0SsmUOUm5b/lmSig7IWIUa5/BrbEkAPwcilQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.139.0': + resolution: {integrity: sha512-qbeygDkcvailKFhphb2YGMMXsaZIynHlPtoOrcx4NZB/tRbUKraCCMbw8dPeFtEKasfS2qWh1VnReY+Lcys1zA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.141.0': + resolution: {integrity: sha512-e6hwQqd+3lvP13G2jxvFpoA7dzHcFLN+Mq47JCVMtdNHbbyBRo756JCtbbJH6ca8inTfyqZoqBmS3vhQlzAK2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.151.0': + resolution: {integrity: sha512-68zJuPgiFpZ9FF5WgpJiE9cukBZVNv79Yod2VV/wJLaiws+abCEfcxwVEH0608a7E/0zOO1Pj2iY7UrnUS8ydg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.133.0': + resolution: {integrity: sha512-hvpbqT5pN2rR+3+xtWeizwfR/aZ0vGceg6TqYMl+ToxMpk9/tmnX7kSvQnfEUkoua8mhogzvIKsAkn0wxgblBA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-gnu@0.139.0': + resolution: {integrity: sha512-SrlL02KeImKlvx/9rCeopOLH7qKI3rqKKEguK6KBwVwEGLhV/A47dW4DNigf6/LFhrwoovaiayEQryjYAI86dQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-gnu@0.141.0': + resolution: {integrity: sha512-vXz2BLAuypA+4MLyBg94pzEo6THVnzYnCtAjXoihIIQo0t2pnp/AmW+SH1EI+4VbuJnC//KplIJ5yyaCGua4jA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-gnu@0.151.0': + resolution: {integrity: sha512-s/CCfZQcqoRo4Ij7ML43Yhe+gJZU7zmudd6StA0T9WDFPLaiWMoBlPRmoS39jPpODxPwI/6yPoiyjKOMNzSqCg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-musl@0.133.0': + resolution: {integrity: sha512-wJQGamIosQBoJHW9+S5XxrtKRo3eyJxsnS1XCPrqN0LHi8uw1pTqqTfn3t/NVuvbBg7Pumn4ez9Eidgcn0xbEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-arm64-musl@0.139.0': + resolution: {integrity: sha512-u9e884ChAVRmIZ1jr/m46S96FoDQnruFjISLi4Y0i6Wu/JUUmIiw7+umLyXILJsPfUuqnN5BJLe23t07+Y6+IA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-arm64-musl@0.141.0': + resolution: {integrity: sha512-jMkS/EztNW34HKsXIaT/SoHcmtocq/vWhwFOVduF9kduuuRIVwfwQ6uxzIO+qPKSXdd2TXt54of0BJ2zFMXnmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-arm64-musl@0.151.0': + resolution: {integrity: sha512-QSjn7WWZNGDTRlMT0SUGDHZNI9XOhGXWdqhL/FuDR/nh0MOqGQT8OHGBy95mZHne4WvoS0OgnUl/+55u07yBiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-ppc64-gnu@0.133.0': + resolution: {integrity: sha512-Koaz32/O5+abIfrNGdyndgRvdOZ9jEf5/z3Ep9h3h2QWpdDiUQpVwgH0OcMXCs+l9aXxPLtkupqyVig9W6FDKw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-ppc64-gnu@0.139.0': + resolution: {integrity: sha512-Z9tU2b3GJfAXOdirQmz4gZQkQkVjy53i77gf91l0733MQKa/qtk73KQQE2GzDtMqim+HyjpzvemmqzBtH2IJUA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-ppc64-gnu@0.141.0': + resolution: {integrity: sha512-vo+MR+n3zQJ6Mq92hiP084NZcgDv5iJlVR02gMf28neMvVT1tKVm7VeiW/DxhdqOi3QLeaXIk9cUcLL1qrkngw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-ppc64-gnu@0.151.0': + resolution: {integrity: sha512-RnvhC+cOND1dsNqbsirtZa9IWVJCCnxIZxs7nAvW0ZFjqqofwKbR3+TNKPqx2eASRC6+b78rZMLiNbDeDUp8+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.133.0': + resolution: {integrity: sha512-R4vOjWzxhnNWHnVLeiB6jNuIifdy9vcMXZGPc7StXcxBovI+U2zg1QhZ9o8OjV80oGivs1lX5NfPLzk4IPqlRA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.139.0': + resolution: {integrity: sha512-RyUbr7hzPK84YDWKs77PRYk9VBwWbsbuYsQzQWiSmLnARXTg2zntLPGfCH/1wpfUYdmGkp/6SsqTXSsYdw9Jgw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.141.0': + resolution: {integrity: sha512-oh80w+7RuiO5gBp9Jnoa/H8Qlt3JsHL2MkW+0dwEdlDMdslVZX/YsekSK6EeyEenY66/mhCfypsNATQ7Ph3qlQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.151.0': + resolution: {integrity: sha512-fpwItfDNVDgXOMV6GdMHD3QV3NdYWhwDH0E8BRuYNeQyUKchb8sNLvAQg+g1HxENvrYjiLqLWAafOja44/sLig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-musl@0.133.0': + resolution: {integrity: sha512-iwgBNUTHiMdxARLYuM0SBlnYeb19iw1Ea5M+4ERZupCsBMLArti6FyZ6UfFjJxIiTDr2oW2DGQFxlQVQ/dW9rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-riscv64-musl@0.139.0': + resolution: {integrity: sha512-dcQhjtcDvtR8BgkUpt03Yz5SzxdzYvTigenIJOEsiSX6G2t6yybEMxGWjp0dOuYGror0BaqcZfTyXR58amCEig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-riscv64-musl@0.141.0': + resolution: {integrity: sha512-LOyEmFA8sCnYbEXP1+iQvCC/P1YXHMA/t6x1Ksp0Y9VwhLFsiBJFzV1zIxrOIE2LKaGGhDjQ29xq9cbq6omDXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-riscv64-musl@0.151.0': + resolution: {integrity: sha512-fKchmw5aUlZem7uZZfxsQAl53cFiGWrAKhwjYxvJFiBPQyC9CZ2P7Qhv9unDJSezChu6iJ6XGQWQnRUyLp7j5g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.133.0': + resolution: {integrity: sha512-ZwZNo8FZmB/gVfboQl+wXilBigGl+6nQQs+nITOeAP/HcAOjiHl6XZJL9F/KXNEspODQcbjAiyjUbeCJd9a0fA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-s390x-gnu@0.139.0': + resolution: {integrity: sha512-iuGrxysV4rGUymdKpn7bgZQ6Vix8Bi/6D/rp71HYIzphq6NKrsBhsGOYsSZte+uBFL43tXh7Xr7TM72sGliJNA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-s390x-gnu@0.141.0': + resolution: {integrity: sha512-3wnwk/l1CvszVE5TJR1wSl/zSEfydRqrNhn6s7Vr9IzSJpUQIroqVsIoPARHRFA+FQwkxAFDAHDAasa7v8OobQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-s390x-gnu@0.151.0': + resolution: {integrity: sha512-vDtxikQV1AixMY5pFAW5tDtGHmoexjGpEgtmPBAF3tXvEubm9KucxV0CxtuAIGEZ1aGyvZ74Hfryb7Vvq52F3Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.133.0': + resolution: {integrity: sha512-govCvWx1dBlED3uu4qXctxpRcouu9I8Kn+DBktGCl760JtlGJzc9l/OmPJKlYWSbrRqKkMZehNeZ/4Wfma7uSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.139.0': + resolution: {integrity: sha512-NxJdZZyaa2JLLvNfH/iJQXfCNfKcPMylwY4ObMpBVmW4Nq+RyUpVVQXrMMelcQ6rwx3nuhF1Iga8n+eoAKGCIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.141.0': + resolution: {integrity: sha512-qtyQVAAebFq57B2tifTlel3TgGqUtsYNI/e+p6aya9rN9lOZVTDvr215fGYSA9XWooxzMxDiVxkBLk2jQHbsOQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.151.0': + resolution: {integrity: sha512-JHB/TuPCUdnkMq9RXB7C/SZuauJUp1EYHi5DaH7ge7uNlCY4AOhc0QeWOjo2rj308+NjxgTwminglWpqlllAig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-musl@0.133.0': + resolution: {integrity: sha512-ssTlpXD5Mq9uCssDJPzlRWqBt4Y7Zzd9i+XZhWmK/9Y6KUIuAxVYTYiI8lxcGWi0+3/Cz4A8q9UrD4NK9Y2j7g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-x64-musl@0.139.0': + resolution: {integrity: sha512-ePxBvvtzISmSsJ0RIj8FNikSCn58i1jtccj7XR4U9Li4iSzhkFyYlnJ51cQTUwkairz8WMTD4SpKoot8RyTnQA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-x64-musl@0.141.0': + resolution: {integrity: sha512-SkGV1nKw40roEc94pv5EaaeH2ay14G6+roe8Q0wIUC1LcEKxzKW921h7+ZuZX0D3q2Mb/7aSFmxEVqnko3lPRw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-x64-musl@0.151.0': + resolution: {integrity: sha512-rkoZa4Wv5LbUHdCJ+3vC9G68r49gaoaQPg52Jx7+aC60q3QHIiysrDHQlQ3hiIevsmDl0RgzD+Y389q/hb34WA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-openharmony-arm64@0.133.0': + resolution: {integrity: sha512-51aByfXhPtLEdWG4a2Ihdw6cPWV1ei1AarALpFdDP8MLWDLE2NuUMgbo3DERR2Kt8fT/ok1GUvBiLxVGke9uUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-openharmony-arm64@0.139.0': + resolution: {integrity: sha512-b/c2+mPXMOxG5x16n8yf9cjor/ntQQScmYnSmLEWIWJ4rfXd5dokMxx0kliSLA+YAGq6DD3K9BWi+aFXHiiV1w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-openharmony-arm64@0.141.0': + resolution: {integrity: sha512-cVgDM7n8QziQqOaP5hNgUYfMG7S/ZeuPxFWXnnHRv7rh025COk0rfQ6eEdKG3j/GaUuyvNZN4ifF1J8KmuXLLA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-openharmony-arm64@0.151.0': + resolution: {integrity: sha512-zp74XxS9WHSp6ct8LEoTa87F5pJOjFPG0o7dg2YCXaKo0raxabpFMC7NTbefIzWmF9KLIuJF/Rg6CPIu6P/Aaw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.133.0': + resolution: {integrity: sha512-2e16tkKp+wDO2GTAmXfxbBcCmGEaFPIJEIRBBmVKNVXSc8/fJsSIaBGyFTPHM9ST5GNWgJcYIt94rDTks+PLwA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-wasm32-wasi@0.139.0': + resolution: {integrity: sha512-rNU0pO+/CVPC2qZ+xtX5R2cOje9Q75q3UkfgwUCPlplqxMv6Iffd5tMPGVMCLGnPINxPlmi0WPsW94HltbYvfQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-wasm32-wasi@0.141.0': + resolution: {integrity: sha512-HggH++Fkn3OilBn+bs3jpgIFQa34oMAyUUHy0vpGum+gt1Eb5nyLc8dNU/RAPSw6lsLrx7ncKtHSZE+3Sp0l2g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.133.0': + resolution: {integrity: sha512-KPTNDKbxH1cglrqTyVeXHb4Pk4oksz8EcE1/v8zqU7N4UXbiHfA/IwtXZ2U77fnRAWBbgVkl/lZbL7o3hRdejg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-arm64-msvc@0.139.0': + resolution: {integrity: sha512-JPEmfncZfqAFiGsAN6UZSMIBqnG8wn8buywRacFOWjP+9dZwcs03SsBp4tmyjM/4l/VoH/IuThrW1Jof3OyQUw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-arm64-msvc@0.141.0': + resolution: {integrity: sha512-KLSEH9GwgbrqbJOjtGHt9STw96s+78yDzp7IDN8Lno+7Ut9sNBfZ4jYZIz4mD50qmWUjoOI7i9I6UENbhNbMZQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-arm64-msvc@0.151.0': + resolution: {integrity: sha512-xtqapASyiSTv6rdm29kKFoDsxTo1oCmMfhPLGCDbZQ0Y6sU4m7IPEH05NgNEs2SrTErBuldkvS6e0Aqzmu0BgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.133.0': + resolution: {integrity: sha512-Una1bNYv9zCavQrfnDR9wuZVB3itLjCEH4Oz7i6CwAJN/Xq9b+zbbcxmvdkKvvJt4Ngc/MBmIYlbLo3zS4TQ0A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.139.0': + resolution: {integrity: sha512-c06dWBwEnFHof5JN7T9/ts23uATXS9czPEBO60d4xnjH2Am29Bo7OGKdVHRmcWQnw0OBxlTg9fIEXAvtcwOBfw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.141.0': + resolution: {integrity: sha512-9UVWUOOCI/1YkiSSNjg2zyBJYM9E/t1A/8GNobd48JDn/fQ6mzxcVO3H08jb3rAaW/B1VBf8eCORTvSsO9T08g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.151.0': + resolution: {integrity: sha512-9s4L40gxkolXQx1Q675XEZqgI4j+7+os4kZAFHdrDQVapjB9J2iodub7A8VAZ0cGTfhZNLH4D9L26fwEyqu3fg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.133.0': + resolution: {integrity: sha512-kjBhCiOGSYTwDJQuuZa7a94JbP8htWu7J0X1KwH74kV2K5eYf6eyJRYmkpCDvr0XEL8tMxYI4WU1VekblFCLgg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.139.0': + resolution: {integrity: sha512-bI3/44urQjW/D495JPXe+c9d+4Q+ONi3DvDNnzwRZYTWHZ3hAlFdmirYK4mzhTfCZiAly02EbMYir7QGU+9O2Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.141.0': + resolution: {integrity: sha512-HI/wsvbWT5RHHw5c37D0fEgeTd8/1Q4OJs5jUmEBc17VZFG6SsCIe4barq7NsAPPks/JW+3ayi3Rp+PQI5h4Kg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.151.0': + resolution: {integrity: sha512-temy3DJf08taii88l13vfs5Om/HWECLSAj5Ca7ANMvocrekAgCuPC4GeHLi0mJ0cmGPznfeaaj80wqQoPIRYPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + + '@oxc-project/types@0.141.0': + resolution: {integrity: sha512-S4as7z0j0xQkXcJlyY5ehntwK8/wRkQb9Cyqw+J/N2rkWGQGK0SxD6X6DhQTc7qsxVTBxXbxZtBJh3mr3PtIzQ==} + + '@oxc-project/types@0.151.0': + resolution: {integrity: sha512-J1yXrIlNDZVzE3ada310xeAw7nH8yCAyLPuUIsjKatFPmfn5bS1oW+cM+QsGOtVWd5nhSpbwZWx/rue+r5Z+PA==} + + '@oxc-project/types@0.152.0': + resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==} + + '@oxc-transform/binding-android-arm-eabi@0.133.0': + resolution: {integrity: sha512-2A79NBpyBKgHJ0FwgC8D1hzp3x2ujyvqq/kG+M76YyDMMkxLhX6A3vjnAnfEKycOoZxuKhwYu8BF9hKq67ykIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-transform/binding-android-arm-eabi@0.141.0': + resolution: {integrity: sha512-FOdseb5KpV3JtkM+7TN4u3sW3aQkUSRy0bWWiKgT/qrIGqZHqzKEUpwaMybutsfwEglWBXuJgnrT9loWisPkrw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-transform/binding-android-arm64@0.133.0': + resolution: {integrity: sha512-dynEph/hyoSgBzd2XbNlW37NK97nU6tZMs5jrhObUxSasBV/Gv9THZrWj9AlbWiMXR07WFYE82C9axjntYyBSw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-transform/binding-android-arm64@0.141.0': + resolution: {integrity: sha512-jglqGwEnSuldt1nfFSpDBHQZ/RzjCjWQEMDatPOEOWIA0ZCCYFj/9ILUOTVllZz79FI9/c0p/bctVVlQqQxxYg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-transform/binding-darwin-arm64@0.133.0': + resolution: {integrity: sha512-4hGgKOG+dZSN3xjcgNWpcihekRG7/YbbAdjyz07yv0HjzA6kdqYAhGrn84374UPO2h6etYJwsCBoM9iJHHvJ8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-transform/binding-darwin-arm64@0.141.0': + resolution: {integrity: sha512-81jBeodJH0IRJ3/OnAgW2lBPm/kcoz603d8eGnnwgW2HbxAUs8rfw+YWaKLrWaKjT0oSIPOrGMJu9DeaKD68sQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-transform/binding-darwin-x64@0.133.0': + resolution: {integrity: sha512-7J11/9PFkznmKuANkCAjt3znV1BcDFXQSgDiBvDxXT3Wm6995/zxrJD5zmo+5XSgY4sm+2V8/ED6ZSD3mKOC5A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-transform/binding-darwin-x64@0.141.0': + resolution: {integrity: sha512-o2jD9E7CyPxhb3CuYbaYsnFH0Mo1hKa2R+Hfo6xJxOlyfcM8U4R73W3YXb9w6lRPUc0PBFUbCmJjtGR/k5SIYA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-transform/binding-freebsd-x64@0.133.0': + resolution: {integrity: sha512-5EMAO0vzCpUfhn6aSjIUeJeRI2ztevHwSVr/M8sZ2VBYc79UuOfjjMCQ67LtUbgpvQtpBWkzeAHCP3L7JFYmlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-transform/binding-freebsd-x64@0.141.0': + resolution: {integrity: sha512-DNF+Of7nckfwqu9fZin4vR8bGmF/3sWPvtw9Jc4cjeQoRB9vUuC6w9C/GxW+0Vr+PCH+gk4tR4Ygvjfx3LYOzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-transform/binding-linux-arm-gnueabihf@0.133.0': + resolution: {integrity: sha512-z6XT8tmo9sPmCIYaFIxDelBU4wXLwwWMX2VNCMIY6bkQp5r+kRtVXYS3yLbJHMKEhRKvw/g+Z7fO9aadsGGEAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm-gnueabihf@0.141.0': + resolution: {integrity: sha512-nolqi5WqP68qVQJdnPFCF50JT5KzqlcpvwGFyIV+IRCLcv5Hh11gIu4InMs3Uswcf0BJnV/oLIjzb7Sycd3zJg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm-musleabihf@0.133.0': + resolution: {integrity: sha512-GQDpEV2VhHG8hT5BviDv+emi9oHYhfv+JJJWROYp+eGgWjiQMp4QZVb6Bu3kwVMzkwy0r200ToA1KThYTq53ug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm-musleabihf@0.141.0': + resolution: {integrity: sha512-ytbO89DQl6KxjKCRlyCEtABgfs8njm623ambDkZZBer5J9dbTwbaV5hseZsPkVzZPxwXobu43/XS0jVZnrmCTA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm64-gnu@0.133.0': + resolution: {integrity: sha512-VstR+NEQAJb80ysWk2vPjEvg0JzwEjKn2hDbC/joa5zGXkCnVVCWgAGG8c6o23S981a7XRpCMcClBgeD1q9H2A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-arm64-gnu@0.141.0': + resolution: {integrity: sha512-Tjj3pobBAzbzUJE8ljbS61om6yfVnarSZzS8LaFCSn0rB+hs0IZRE3jC9IzpsVPHSoJl4uhbIGebuDY2G3B6gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-arm64-musl@0.133.0': + resolution: {integrity: sha512-Ec7xJdDrnukgiz20E3iDNzAIgx1XXn8cVVsNNUpgEIAvNlXZaocqlQT8Zalk0Lv3fbkxcJ+9BuWB0ndBRHQtzg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-arm64-musl@0.141.0': + resolution: {integrity: sha512-aUUptri02E4nqkUvyA+2oYkmU20pYnHIpNLPZOgom0kAa0Fx9X6QFKqKm1MopyucWolQ9XTgCK2PrupSSBdCdQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-ppc64-gnu@0.133.0': + resolution: {integrity: sha512-6YX38grimcigz20eYpyz6e4c9rDKzwK3i+tcDpgwYj0bWreaAOwrABmSmKplPJOorkDVlbT69wPCN+d11irBQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-ppc64-gnu@0.141.0': + resolution: {integrity: sha512-d28AT+SfcAYFnulI2C8HJ5OeoUa5w+eMpwy0uMzbU/3zXJpFjjFOvJlEL8FNvx7HBEENj5IfgD+aXdNzEEn1Tg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-riscv64-gnu@0.133.0': + resolution: {integrity: sha512-WxMIzItRJR66lgaAyyqj0FFwLMpcuCV9mTFcUMQpIz8+Hey1Enk8xuv+7QpSsqCR5zRlwNr092dsFkz5cbvtrw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-riscv64-gnu@0.141.0': + resolution: {integrity: sha512-P6XVhw+MJsjeliWJ6BBKdC0HU1VEiwMRHtqUADK+jK5wiqgzt3/JhIcMuRLzBPYfnOujLpe+fm63yEzKUIAcSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-riscv64-musl@0.133.0': + resolution: {integrity: sha512-+x6dnO87986rjVNjcF0tg8wVS0e/SH8nzLa/X0Wsh7jtEniN7buvR8iqZm8pnsfaZ8DH5F4GCSZpoPRrd9jJ6w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-riscv64-musl@0.141.0': + resolution: {integrity: sha512-6QUicErqoLpCVsXPYI+OEYJ95TjiV+trvX9VeCuyVcyL5p0Opi7DFQL2c1DcGHi1c9cqz1h09mUKCZ7Y52kxfw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-s390x-gnu@0.133.0': + resolution: {integrity: sha512-oEyQudXIwWM/+v0vZzPbAi25YMWyvjtQYYjuSrhMEQwe7ZEMDXscX7U1j6alrVdZq2DtCMeror3X/Dv7p/JUwg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-s390x-gnu@0.141.0': + resolution: {integrity: sha512-r2Jk0vfcnHnkPOjLnWvpGVTFcYDirGICBJYraCkWeplhPZ2Sgg9GvDVgah9VFOHRZVtK6XQynELP9A8EB/Ne0Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-gnu@0.133.0': + resolution: {integrity: sha512-G8P/OadKTbyUHz5TK63sDDtUHwn2SXG/o0oGo4GGTzBu70xmUSN5/ZUgpyl6ypAmbshoyw8nC7+msb3BjzHxaA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-gnu@0.141.0': + resolution: {integrity: sha512-lIsdGq4LA1IlbrZlmrhP/p0pCo4+5jrAlLp9BMzIHaV4mILBSr+ZtuTDkML4117cLHdzoWOqw0s3Rb7igOWtxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-musl@0.133.0': + resolution: {integrity: sha512-Oi/fyOzZ+aytmmsRND5pGgvux4n++v9cG4qNFiXj7qFwSqBKWZHBq7cJLXqbH1I81pyI3kvU1Za+1qk3afXuwg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-x64-musl@0.141.0': + resolution: {integrity: sha512-y+9FbVRBhUtHBVn0xHiVcaNHkoRudIhlKhRk1+CclE1uGD6af3xznTjCOrKGB7HZ2SzlCWLZwQGm/KERpUjX1w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-openharmony-arm64@0.133.0': + resolution: {integrity: sha512-/ZElgq+/tcga27X2G2AUpxcYX0baX94Gz658w6Zz2P+6Kr06bfYSrdtC0P7oPrbu3Gy/6kpiSoJPgZy8R2IjYQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-transform/binding-openharmony-arm64@0.141.0': + resolution: {integrity: sha512-Ul5Fu6zPL7kjTbtBU30HaRFHPL3bjjpdieHmAXJlJDuFukuOXqVD6dS70b314IjFy/rbqkD8OK4MQ4408eEjyg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-transform/binding-wasm32-wasi@0.133.0': + resolution: {integrity: sha512-GANcoEa8Nzza7saxdb4qWO24U6jk4nK6G+g87lGp8TTU45CUvWf1Igdze2+NrebgiwOy6F1/h6Esag4DM3JTtQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-transform/binding-wasm32-wasi@0.141.0': + resolution: {integrity: sha512-GaQJvcyFJyle5lll67+iYAgv+G21bQXvWPNhD6YIYoR/bV8kS0Qm8YSL22Y/YZC/8RwsneVFWpP2y6VZJfcM/g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-transform/binding-win32-arm64-msvc@0.133.0': + resolution: {integrity: sha512-2+uDo/+ZvGQu10J8xryg/l5PdBt2vXPtf+0aIosVKJavqCaKcBDdo95OUaEulx0bqvoytAQ4yyz2gcPZ40mjcQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-transform/binding-win32-arm64-msvc@0.141.0': + resolution: {integrity: sha512-Fbi/hC64tNa56mXEitjaWsxQoMvtJDbOe2MxO+BA1v1Ev28L9n1yMJwhKyOCA+Rm8lYK91oOb5CRv3Ct5RuvJA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-transform/binding-win32-ia32-msvc@0.133.0': + resolution: {integrity: sha512-zpPIZ1S3JHmSEFyyGyPYCwhOiNLyfaPifYxK8BQY21JXyHglu/wUr3/ESFrXb+XegEy/iBlWbzr3FzPtcq1MUw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-transform/binding-win32-ia32-msvc@0.141.0': + resolution: {integrity: sha512-2HlslqwOXQ2nxAZjhqZIpvPxENhQGvA6b4cGwmiVD6Uh5x+dZAopOeEJRxRPpKcrr/W5KXfwwbttwx4OWbg9TA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-transform/binding-win32-x64-msvc@0.133.0': + resolution: {integrity: sha512-cADrfLvc/VeyvpvQS+t5ktqfyqyyGANZC5NHp++JAElacfXqq/+k8bYkjqMWzNZ3HxkJtL1qDHfZZCA9+4hlSQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-transform/binding-win32-x64-msvc@0.141.0': + resolution: {integrity: sha512-JEgTv+y56FbwinH1/kqpNyD+bWRWDpbbPdSY7Ta7rCKFiRsYkUHZd1v+XWxda08cS8GAmlKS4WKcVwtrAbDUHA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@parcel/watcher-wasm@2.6.0': + resolution: {integrity: sha512-dtjbDxKSDPQ8AmA+pS4OFaHE1FKrjtGpLGBxw85uKFkRorjNbvDM/aFPgqosu40wprbp1xw2ZSxIKqghCUHe2w==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.7.0': + resolution: {integrity: sha512-0UTYalzk2t6S4rA2uHOz5bSSW2CHdv4vggJI6Alg90yvl0UgXs6XSXpH96OH+bRkX4J/06djv29pqXJ0lq5Kag==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + + '@publint/pack@0.1.7': + resolution: {integrity: sha512-4EDEmvxWtgsCnnVeBvtFIFZtUhPPt1+bA9JrSwU4Sa//6oKtzCSlGGXYJr44OD9aGISymbieJ4mCKHUygUDU+g==} + engines: {node: '>=18'} + + '@rolldown/binding-android-arm-eabi@1.2.12': + resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.12': + resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.12': + resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.12': + resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.12': + resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.12': + resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.12': + resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.12': + resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.12': + resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.12': + resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.12': + resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.12': + resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.12': + resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.12': + resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.12': + resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rollup/plugin-alias@6.0.0': + resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} + engines: {node: '>=20.19.0'} + peerDependencies: + rollup: '>=4.0.0' + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@29.0.3': + resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-inject@5.0.5': + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-terser@1.0.0': + resolution: {integrity: sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-yaml@4.1.2': + resolution: {integrity: sha512-RpupciIeZMUqhgFE97ba0s98mOFS7CWzN3EJNhJkqSv9XLlWYtwVdtE6cDw6ASOF/sZVFS7kRJXftaqM2Vakdw==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.64.0': + resolution: {integrity: sha512-FLLpX941CD/7aBvX3GqLGBM9OvY5PGXTryPJkG5r5/OuBpZpV5k45Uo3RxAvqd35tsyc3hH1bhtz921IKzoIzg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.64.0': + resolution: {integrity: sha512-iI32XM/jnDYJsvx5ai/za/7gWO9XoSeFFtU06/ZCaRgyilfJOjaopD3nOpk2WrTCGOyeDt4hleUiGOAnd5tHNg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.64.0': + resolution: {integrity: sha512-dRBZlbt2sEtF8Mn4MODThze9fIPdDoOhVSlXMAKy5dQbOYK9pOOoPY4Fat3OTtr0+8zbJo5TTZwlsfxY/kDNJg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.64.0': + resolution: {integrity: sha512-Y3whrJOMucfkhgNkvcM93M6j8C53iEAMmPMYD99C6G1kUy4ELigLWk9ar2/4aCBSRgsql0zdlOemLgW2m5GZgQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.64.0': + resolution: {integrity: sha512-S6S1GEzPjFF6IONYJX3AKt/799+8RgBgCcwRnUo+Ep1IvBxUbw5M51iU0TDdK2NWWVnSvCQ8yi6Em0fGASMOng==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.64.0': + resolution: {integrity: sha512-Ed1DPoFENkXj4IGzSB12SesV40iP6LxCCrbTIkSGIQBpOOxpBM+0kj62lmaeIHfMWTDoddqTOtqc7s8LYfn+Pw==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.64.0': + resolution: {integrity: sha512-J/6xhutJPtFyIkmHdf4olOdHHKH5kOJNumojdWn+Elv5ICEYTVOa362Vw27TxsK0BLzb1le3EDlO3UbvFK1lnQ==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.64.0': + resolution: {integrity: sha512-G4L/Nnx59d2LvDoV/P4S5lZ7oVLT6hodOHMacqjiq2LL2gts86KbkEBTYL53+fBt0odhf7XPIbIATGoYiJctxg==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.64.0': + resolution: {integrity: sha512-zF16pvJDEUksGYRbfnXne7pdklAyj2XDmJeYKgP93oq0cUyX9Y8O7lUo1R+IY1GagP/YBvCEDCe7eEcAKpw//g==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.64.0': + resolution: {integrity: sha512-nIggWn8n+w12+R5lsV+PYYoUY8vuObxPAQqJI7WES+9v0qspYuAHoZMfYM0yLxlipasT5BY9ht5W8t5c/rSCkg==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.64.0': + resolution: {integrity: sha512-WLOTiHPzszP0dxIMsHpFeDSOSB5I49Mj8K4+yKE3H1X/D0JRG5XZ5jrctJLMjnUc/LUzaKiwq6EHWNJ8pup8PA==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.64.0': + resolution: {integrity: sha512-35RK9aRhh7g7Pmeu5gQ01aCvrhXzj9LoBE6xtUcEH1ns+nyTaSzxSpADmBQINu4QiTDGvmQYwo1j5hlg1rRXFw==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.64.0': + resolution: {integrity: sha512-RqTfnpoTjuWfPAmqK5p2edt2AMCDJWm6oTn7sKfmyx+6tRga0ip05SJ977o6udTcIiDeF/CJMUfkaN4gtWt6Aw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.64.0': + resolution: {integrity: sha512-RQjZPigjxFvFZDijG6rjlSXxhRaTf9zLYVpGK+lVcga64oMqP1GbgVqCb46eHTTceSIgp89Ja0y5aPe3GFBYHg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.64.0': + resolution: {integrity: sha512-tjL58mgQcTRnDRpeky+Sth1MKQeYi2Ct6r3Luq9E5aTSjnM/i/JbozqZkKqp9thM5+oDSZxo+05f9kdQedfTGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.64.0': + resolution: {integrity: sha512-ictoRyVaoZ8C67myHef+8hhCa6IplXJJ/xUCkVCxziV4zxMZh+jvhkhGsPBLqj1S72fnqD0QH5zL4lcaa4X7DQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.64.0': + resolution: {integrity: sha512-8aVvZ2hfr9RLFzBQkQNmYeHLDja8fLeQAmLt757zdKN/B+8L809KlLJKctQjS22wZotptV8G6o7fVPuAs8S1tQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.64.0': + resolution: {integrity: sha512-2dEF8GAcDKwshUfydD+GhosppNyBzhVUHkdFF3CXd3FpOkzj/RZzF5aoEtzklujklT5qFVRU2GK/cFeLaTNKVg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.64.0': + resolution: {integrity: sha512-3XHTvoo2hKkh0MiOfS7SkhHjMaaWF7P4F3drocZZaho/Z8w7h/jpnuBHm91BOQLfvrKHs1yR+zir4E8RI3XzTQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.64.0': + resolution: {integrity: sha512-HKtkzodL4a3KFWDXDoO61cRynAWTR3LnAE0oGtfG9lcNFpNuVYUFOByxDgNqEvic9rvaQbAj+SFwTEWDptRaIw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.64.0': + resolution: {integrity: sha512-JBsxqiY16uyyCujtoC3s7zL+SrYyNElptD7K4V+KUoJ2V8/XG3hPWpheK+SuPwNh1cikJvIZmIdsrYXvD6PLJw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.64.0': + resolution: {integrity: sha512-S5Qrijh37qhnUYQ0ay8WN3LuWeKjow7wTUyCOPMZtnXiBXYXdsZETI6ZLfYnQAKovltckPLBFdNeD61P2rJc7g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.64.0': + resolution: {integrity: sha512-zbZ6iMmLFEsCtTdc2/y1F/cDFVNNCPF7Ae8PCT/wdPE//hGwYp6r+MyCLMFX+kOeIe09Pz6ASfnnfpSTN1FJQQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.64.0': + resolution: {integrity: sha512-L6Hw69oNpuYaOr1zCG30v0/DqKYCSRwodPGwIcVZ/6f8SOzq9rxtL/xNVI5MO4wjli+Ko0ErK9uHJL3mNPt8wQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.64.0': + resolution: {integrity: sha512-nl+CTWIgOGszQmUz/kanfgrfFZ4qiwxKIfT/ryl3N3Ewk5tqizmYtNXiqb7Bu/fDtNgu1kyxdFiAUJNur3iysg==} + cpu: [x64] + os: [win32] + + '@shikijs/core@4.5.0': + resolution: {integrity: sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.5.0': + resolution: {integrity: sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.5.0': + resolution: {integrity: sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==} + engines: {node: '>=20'} + + '@shikijs/langs@4.5.0': + resolution: {integrity: sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.5.0': + resolution: {integrity: sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==} + engines: {node: '>=20'} + + '@shikijs/stream@4.5.0': + resolution: {integrity: sha512-t9WVf2cUQ9WLE/Zv6eRYXfY/Til+zMY7WAsAvhnq0CA5YfdrUxqwv0ZVleLK1gl17v6u+cn7ZMDk1mg0FwHThQ==} + engines: {node: '>=20'} + peerDependencies: + react: ^19.0.0 + solid-js: ^1.9.0 + svelte: ^5.0.0-0 + vue: ^3.2.0 + peerDependenciesMeta: + react: + optional: true + solid-js: + optional: true + svelte: + optional: true + vue: + optional: true + + '@shikijs/themes@4.5.0': + resolution: {integrity: sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==} + engines: {node: '>=20'} + + '@shikijs/transformers@4.5.0': + resolution: {integrity: sha512-LM7twi043qCC3gRyGQfjoC2/sowzbEltWuruyRtT3RlBlk1hKzWk9ETnU7RcDBoVWQBmC8Mebnr7p28W7kPoaA==} + engines: {node: '>=20'} + + '@shikijs/types@4.5.0': + resolution: {integrity: sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@simple-git/args-pathspec@1.0.4': + resolution: {integrity: sha512-EtMX6XjRWSastG2SdkmSQByPtJ9dx/NIjnHbpQPCYt62j4RmSx5rgLTGpw0YCjF5h191gZOmBfheOT23cRSFdw==} + + '@simple-git/argv-parser@1.1.1': + resolution: {integrity: sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + + '@speed-highlight/core@1.2.24': + resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==} + + '@sqlite.org/sqlite-wasm@3.53.0-build1': + resolution: {integrity: sha512-PfWPWN2n+/37doa8oh2/oUXk4OOsRYZsxc1W1sDXIGb/Pu5Yrb+f2eyYpgQMGITVX7HVgxhs9P18Rc6I97ym/g==} + engines: {node: '>=22'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} + + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} + engines: {node: '>= 20'} + + '@tailwindcss/postcss@4.3.3': + resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==} + + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@takumi-rs/core-darwin-arm64@2.14.0': + resolution: {integrity: sha512-To8/1EFFVM40V3FlkQIkOl2Ge/xg6bP8KWlxoeBUEusJvjZ3d3PfmKoVmG9erM3oh7ztzw1u3nUXQqLFTNeJBQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@takumi-rs/core-darwin-x64@2.14.0': + resolution: {integrity: sha512-PQ5CiWB7gxap2NElJt9xzoqP0Bzm93SnY//x8OpXuiRQmsW8dOdk5M7mPpJOghebxfRuDc3YIcOEEcsQFpmncQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@takumi-rs/core-linux-arm64-gnu@2.14.0': + resolution: {integrity: sha512-2YKku0pJd63ojLKRY8UXerN/NCGhcdyc+HRxbFk27B4enMtxjPPKGgT6xVjBvW1J8vxsOo/eRSGMq2nDq5REBQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@takumi-rs/core-linux-arm64-musl@2.14.0': + resolution: {integrity: sha512-0XJyEleC6qzxxDOHhobo3TjMddOEvnI3uwSDNq8EH40SUp+Qw71DTBNXqwtwT/NPDj50f8bD3w/M54a86eK3Ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@takumi-rs/core-linux-x64-gnu@2.14.0': + resolution: {integrity: sha512-fINzz8oeamnFqbg75xgOXMrzljhI8BmCf2SZl31dUr+o1oRWUuQyTBm2RjSl2nKjamHd71IoQRo3ilAUqNkadg==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@takumi-rs/core-linux-x64-musl@2.14.0': + resolution: {integrity: sha512-aMDWTKRSnShorZHx/rFFfk7ovnK8kffmqprwYppNIG25DaTf90GN3CYsFlgGAIRYv0aJ1CbMGjRjzxu2raorYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@takumi-rs/core-win32-arm64-msvc@2.14.0': + resolution: {integrity: sha512-apuJ7bT+3tZO6PtZeuuMZ2Qkkxbi+lTniT+iAAX0lGziuTfoguIvDMhbQtQGKUbg7WUE2tqGixOHdUgab7KKCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@takumi-rs/core-win32-x64-msvc@2.14.0': + resolution: {integrity: sha512-s5FK8ntDdvIBPCro3OXQEWsHpMYwRLU3JLPdgZK8eILSKjCg+NenAiGDZdU+HmObuqRQn9Q3PYjMc1qwkBzmeQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@takumi-rs/core@2.14.0': + resolution: {integrity: sha512-PGgLdS+A1xaxPhJtYy/d+k5GYw9MOcwcLMs2zT4RGNkw28FxN+WWHvR1+nnn34rdyD6sG6K2W+50oQZtQV1h/g==} + engines: {node: '>=18'} + peerDependencies: + csstype: '*' + peerDependenciesMeta: + csstype: + optional: true + + '@takumi-rs/helpers@2.14.0': + resolution: {integrity: sha512-jFIpuWfBMAxlULx3tEk2V+FCs1CLOMo2/c7h3I2P+eNzMmxwE9TJ/BtwJVghnLlFW1M88QW/ZOY/E7MqXACWJA==} + engines: {node: '>=18'} + peerDependencies: + preact: ^10.0.0 + react: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + preact: + optional: true + react: + optional: true + + '@tanstack/table-core@8.21.3': + resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} + engines: {node: '>=12'} + + '@tanstack/virtual-core@3.17.11': + resolution: {integrity: sha512-+ILjvtHup6Y2hzQ6YzwMgX1Q+oQpxEGOXCEsCNaPoIP0VxMbizIBTmYTDtkerkIQS8/CbP1BRuyt8V/8BCsy1g==} + + '@tanstack/vue-table@8.21.3': + resolution: {integrity: sha512-rusRyd77c5tDPloPskctMyPLFEQUeBzxdQ+2Eow4F7gDPlPOB1UnnhzfpdvqZ8ZyX2rRNGmqNnQWm87OI2OQPw==} + engines: {node: '>=12'} + peerDependencies: + vue: '>=3.2' + + '@tanstack/vue-virtual@3.13.39': + resolution: {integrity: sha512-AG8sI+6nfrDvN6ixuHJL9LaJTf3//0V5VITZYW3UOaIuSVexnEzsbMu4LH/JhMfRTxwhUXPnLqkl1DlzkZbRtg==} + peerDependencies: + vue: ^2.7.0 || ^3.0.0 + + '@tiptap/core@3.31.4': + resolution: {integrity: sha512-cIVUQYBycighzsk6GbmCef8ZiEDVxoT5EuAe4xg2q9dNkDqCXVqI4YGr9aavCQEiAS4uHiRwqvcsPqJHipFDfg==} + peerDependencies: + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-blockquote@3.31.4': + resolution: {integrity: sha512-FHnbvCIW0eDKgUUFjmvEB0ax9YUBW7/Unm+38qpuQROvU872yRqhnDtycKT9IKk46jNdjM4A4fAGUbge10CrAA==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-bold@3.31.4': + resolution: {integrity: sha512-QX1xoXvO0gz6uVsoLegumqQ4MJXL7lcUDQZ4J7la7LBqiIh4efrCmp2EXbhpr37M/YQL7w8q3g7H/VovSh7xIg==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-bubble-menu@3.31.4': + resolution: {integrity: sha512-Ml/yswuys+3QkOMajfXyAGlUKCxEbT3dMyF8vHwQ5mDk9MDm+dqp10It5CrDBkUT/KkVTa6AJI3kb0TXZJZiAA==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-bullet-list@3.31.4': + resolution: {integrity: sha512-gHn1RDR4olCnmKpH+G9x+f8R+iKPNVdLlvbFkIpR/stjabZi7fB4Rr5GiHWsulbtxAjdQrNjnVeNdGM4rBxApw==} + peerDependencies: + '@tiptap/extension-list': 3.31.4 + + '@tiptap/extension-code-block@3.31.4': + resolution: {integrity: sha512-su/B/cfQ1HpiHl6JfJ6wa+RVEptiYsV4dCntE8XQNj2dUcII4y6w6PQbbswOoDrU79uXHsAvpy44215rghG4LA==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-code@3.31.4': + resolution: {integrity: sha512-pzi8GNDs5J1DEoO1HNYiJ5WZpgOZzlc/2VIa77mMpEuD4hZxuK0BQzlF/O6Ps/O5P1lGJT4xS0Yowpzb9mD9RA==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-collaboration@3.31.4': + resolution: {integrity: sha512-vIGuBU2oV1jIr0zGPdWc1qFo4NrzObktC06s8Z0zYCb59hm3lfnYzw0w4R2i/BYjjoKRgpiDVYweGAQHuLT7Vw==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + '@tiptap/y-tiptap': ^3.0.7 + yjs: ^13 + + '@tiptap/extension-document@3.31.4': + resolution: {integrity: sha512-vT20u62RWR+BLIyNJ54e24MPUY4zm8VF7tcgJnxQXi7BgVJWcNMtMWWDIkPJ4JNXwfoIznKh3jzYsaYmbCJgQQ==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-drag-handle-vue-3@3.31.4': + resolution: {integrity: sha512-bUYvpmjg26BpN4T4Yx7jUAzM2+Fg6nPsKFeN2yF9PWaGE4GIzK350BnPuqxWWdsyn0RXc+IvfJbRfv0k4uOyvg==} + peerDependencies: + '@tiptap/extension-drag-handle': 3.31.4 + '@tiptap/pm': 3.31.4 + '@tiptap/vue-3': 3.31.4 + vue: ^3.0.0 + + '@tiptap/extension-drag-handle@3.31.4': + resolution: {integrity: sha512-UiHZNmr3fU/YeZxVyMyFTbb/ougIGSX0q3BkiCE0l1JPARhfYEsT6oULP6IC3tV8qnZHxiAZBSLlwRuJH0vuAw==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/extension-collaboration': 3.31.4 + '@tiptap/extension-node-range': 3.31.4 + '@tiptap/pm': 3.31.4 + '@tiptap/y-tiptap': ^3.0.7 + + '@tiptap/extension-dropcursor@3.31.4': + resolution: {integrity: sha512-5TbCPCC4RL+QT1NYHjXCYDBHBtVqYOFvFEnk3v98lvXCM2PNL13ofXUfJPuykAVy1OdTAx4DlZOQAD9WKy/IdQ==} + peerDependencies: + '@tiptap/extensions': 3.31.4 + + '@tiptap/extension-floating-menu@3.31.4': + resolution: {integrity: sha512-pKzulkDmolpVt7IP9FSPsC5pKbXQ5pyeqkaAYr8cyOVW+KUObpPRIzAuXvEso8PCjWgwJ1f2qyishOEMw8MbfQ==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-gapcursor@3.31.4': + resolution: {integrity: sha512-hBogUAepQH6IQUhaePhPWzQ1Oeu+yqlJVMKO06Eue5m36uRy1PZZAQ780pCGT0SC4R5MH2td1N8EUQ7bupQdDA==} + peerDependencies: + '@tiptap/extensions': 3.31.4 + + '@tiptap/extension-hard-break@3.31.4': + resolution: {integrity: sha512-oLNajLyUvRMg1qtzFgKGduygTlpaHFB9PU+M+pUWdA4sa1bRnxS2Y++Ao4lHYopJ7nxatLndrYoCIHkotqkPDQ==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-heading@3.31.4': + resolution: {integrity: sha512-KqlSeLathpdxCc3kVHBCA/RkHvb+V7u5vgiSEu1Cv3L70r7F19COMGODav/k1AGYBgEXKL6lM9cy8cloE5/28g==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-horizontal-rule@3.31.4': + resolution: {integrity: sha512-ws0Kh8kfHL7ESILSXj0HJAXs8G10ewlW1sedXKm8dm0op9L8il+xl8bEJVoqG/jMf77900Fc2CaQldcCGRpF1g==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-image@3.31.4': + resolution: {integrity: sha512-vtD+rK73abJnPRKOjU37sQTCa5Auyg451yhqZD/3lZKiFJDBHAZKI7lQARkXBQYK289hBhK6yMIwofoqCBvi3g==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-italic@3.31.4': + resolution: {integrity: sha512-pftTQBPYZocNDAj/u6OyDIp7YxmN0+N895cQPogJQ6qMHdLiRhzgawiEewJkniyN1w8k3Wx/Etp8pTKrxaOOBQ==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-link@3.31.4': + resolution: {integrity: sha512-LLxW3qfeL9gvDdMPVdxYFYZ0zZSjsoIDhOqjJ5U2UfaK3U2iwkKTBgV2qT+FWf3uUHmBRjBZ08q3dRPmWBAD5g==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-list-item@3.31.4': + resolution: {integrity: sha512-ao8XAPvhOrtGFILs+fKtOM91omDSpUC8X19m44gbaq5xJDVpIMZ0rP+NAVUS72G7LskhcHa0bu/Pm022bUVjVw==} + peerDependencies: + '@tiptap/extension-list': 3.31.4 + + '@tiptap/extension-list-keymap@3.31.4': + resolution: {integrity: sha512-etdkl/YnYfwtALDxecJ+4WYgJAez1fn1vzzZqJklZBpgqiZtny3NxpvWS7/JhsltNG84Wo/oovpfJgVmzhddrw==} + peerDependencies: + '@tiptap/extension-list': 3.31.4 + + '@tiptap/extension-list@3.31.4': + resolution: {integrity: sha512-Wd4YRYxOdf+TtF33/QsRo1RK1CecVxjYGjUBIKNGHAywfh8tghgV4YOUCiV1iJqYt2IBs+RWlIqTmdIPzBrd4A==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-mention@3.31.4': + resolution: {integrity: sha512-O3wkrfD85z0o+tOAOy/XcT9gY0pJPfo3GwdgeJfHRy3zObtoz5XR48QvWeN7pDnXrsvupejpZegQtAmGlg/1Nw==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + '@tiptap/suggestion': 3.31.4 + + '@tiptap/extension-node-range@3.31.4': + resolution: {integrity: sha512-PctcI8ru/69CoOtWNtDt6HHxqIvX1zqzK7Zlt+mehdMCXOXLedHBvh4SwuqP19X/Vdzdm+OH8bHlnT+MGd0liw==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-ordered-list@3.31.4': + resolution: {integrity: sha512-UNWyF+Dhm08znszIMnT8Y2kJ1lvtiCvUGs1aG7m9cPHxDa7VycWnOqdtXWkc+6xRLNiC0zgWCFWgLLHduV8pRQ==} + peerDependencies: + '@tiptap/extension-list': 3.31.4 + + '@tiptap/extension-paragraph@3.31.4': + resolution: {integrity: sha512-WZlBgw+XVKXerRlmEsoQ7x1PwSU+dh3X+b70+ViZsLebdfsmmYBIaNDrvIGwG9UQr5eLnddJnZplMSTI2YKs+g==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-placeholder@3.31.4': + resolution: {integrity: sha512-3SoJopaOzaA9IZHSk9ZXHiO6ib8ErPh7ssRh3bIaxfD+BqRyXcm4hV4yfFXTqrDCnl5FE+DbBRGmeVAVkDko3g==} + peerDependencies: + '@tiptap/extensions': 3.31.4 + + '@tiptap/extension-strike@3.31.4': + resolution: {integrity: sha512-4MBr63TJIMqxCjE+gAPdlY1IdELgvbAP516K3Ntn/BkcpEbEoPMEYVz+XTxULyHQEuARDO6jsXPPxRXpA74jaw==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-text@3.31.4': + resolution: {integrity: sha512-WL2ZRpFksgQcXJN05/UQH09YCH9LlhdLrSEcviASvEH/aAfsKiJlDrouN8PET+YAWK/F5xFc5/Q1z0xj+I23jw==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extension-underline@3.31.4': + resolution: {integrity: sha512-0iFGPIqmqGkCrOFh1OPo7Dzv5s86dVN3bZaugsz0jK04otkb8bn04ZDKP2/6Wq+lcK0M9DfJ0QqfW5hC2nBZxQ==} + peerDependencies: + '@tiptap/core': 3.31.4 + + '@tiptap/extensions@3.31.4': + resolution: {integrity: sha512-nIupIne/sHpV2Kw1M4MOmr4+G454KI8BXM5+LWKOU2EpzfALZWVSy7koF9lVRna4Zp5Gv8hfg5Z8kvmrYQvhkw==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/markdown@3.31.4': + resolution: {integrity: sha512-lmR9V1/eQ41BaR2zBgYG/+Liy7K7Ch17ZNxVy8dpUVlNpWxxoHUMXNsCg2uEyXP3NLpZaKiY0+drSu9oK1DbSA==} + peerDependencies: + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/pm@3.31.4': + resolution: {integrity: sha512-x7dwth79cQp4QGae66/RJqMDJQv0+n7b7dD7cyFQBWqzPFLJxN/4paHY4qbWedZjNLhRyIOAD9a5q4AYM1zmPA==} + + '@tiptap/starter-kit@3.31.4': + resolution: {integrity: sha512-u7HIJ9vK6kFe4S4J2CIcDLrhRZzoTMSyU0XxjQ6lUNF7pWW3rMi//pvi8RcsZmxGjyb8CpXAqYgNl7f9WyaUeA==} + + '@tiptap/suggestion@3.31.4': + resolution: {integrity: sha512-J9WWMQDAzZOlF9VSdLohpxgrwlB1NscqvNhOPoS3WjwrzQqLj+FAvcchfJQcnybF5mYOtftFZexpOzOt1MqjUA==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + + '@tiptap/vue-3@3.31.4': + resolution: {integrity: sha512-xi/t4EfSX9QEbOSC0RhkzhT78GJSeJ2Jmz0EBV860lcxDdNd+Xw1pfOjFseNz2E+r3zhTcKDBsLblhCao7eF5Q==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.31.4 + '@tiptap/pm': 3.31.4 + vue: ^3.0.0 + + '@tiptap/y-tiptap@3.0.9': + resolution: {integrity: sha512-7/El8NQ8R5V5MkdrOUdfj9IgZacpt0H071xNimX7B0AnYiWiKefQnMKd41neQYzo2MOXbWdN3iZ+7Z7BruzOSA==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + prosemirror-model: ^1.7.1 + prosemirror-state: ^1.2.3 + prosemirror-view: ^1.9.10 + y-protocols: ^1.0.1 + yjs: ^13.5.38 + + '@tybys/wasm-util@0.10.4': + resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/hast@3.0.5': + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@26.6.4': + resolution: {integrity: sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg==} + + '@types/parse-path@7.1.0': + resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} + deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + + '@typescript-eslint/project-service@8.71.1': + resolution: {integrity: sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.71.1': + resolution: {integrity: sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.71.1': + resolution: {integrity: sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.71.1': + resolution: {integrity: sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.71.1': + resolution: {integrity: sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.71.1': + resolution: {integrity: sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.4.0': + resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==} + + '@unhead/bundler@3.4.2': + resolution: {integrity: sha512-rTMyDAjirL+fY9MzvlgY91+irU6p6VY/rklJtIfyVVaE4/VI0R2E2R1lQdatVz5gnGWZxQVeleBMqQwL2gTEwQ==} + peerDependencies: + '@unhead/cli': ^3.4.2 + '@vitejs/devtools-kit': ^0.4.1 + esbuild: '>=0.17.0' + lightningcss: '>=1.20.0' + oxc-parser: '>=0.98.0' + rolldown: '>=1.0.0' + unhead: ^3.4.2 + vite: '>=6.4.2' + webpack: '>=5.0.0' + peerDependenciesMeta: + '@unhead/cli': + optional: true + '@vitejs/devtools-kit': + optional: true + esbuild: + optional: true + lightningcss: + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + vite: + optional: true + webpack: + optional: true + + '@unhead/vue@2.1.17': + resolution: {integrity: sha512-pnC8x9HLV3qQXdvWfylUEU25uhfCAy3ly9nmpQz84j9py818DRfU8jOsQ5wjdWtxyU1vX/fW2udfm4jtxUK8Bg==} + peerDependencies: + vue: '>=3.5.18' + + '@unhead/vue@3.4.2': + resolution: {integrity: sha512-kIe9HaBEUvueM8HIyGw7Eu1c/1pcGy0gnCwC80rLhNJvxNwxXKywvnGSn1rKv9rAVxQTmbEL6Xec3UFXPoIwWA==} + peerDependencies: + vite: '>=6.4.2' + vue: '>=3.5.18' + webpack: '>=5.0.0' + peerDependenciesMeta: + vite: + optional: true + webpack: + optional: true + + '@vercel/nft@1.11.0': + resolution: {integrity: sha512-m1QFg+U+3yPOnP1xSYJ73UIRxLOXdts1JOhiOiyPYqEsALgrXFFINvgUaD6R6iNvaBFAjHllBCbkfx4FuOdpaA==} + engines: {node: '>=20'} + hasBin: true + + '@vercel/oidc@3.2.0': + resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} + engines: {node: '>= 20'} + + '@vitejs/plugin-vue-jsx@5.1.6': + resolution: {integrity: sha512-YXvi4as2clxt6DFw5+a0tTA97ntiQXm/raR8ofNj3aNwwdlVGTiG2gp7EvfZW17P50acL/9bP0ccF4XnqNmlgA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@6.0.9': + resolution: {integrity: sha512-rD/MORlhaZMlXWW0rEn4FB4wMinWC0z/D7Ye160S5+Rs1mC8ZDAdcDp4SjKfUhG5t8q1ktcPVw4xuTkPRlzrSA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} + + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} + + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} + + '@vue-macros/common@3.1.4': + resolution: {integrity: sha512-/5Fv+6DgIcM9ajY05ZmKBv+LMX1M9A0X+IUwDRVdt67ciw8OV9bvG2r34p3RiEadlsQybjhKPRKNXDC8Bp23cw==} + engines: {node: '>=20.19.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + + '@vue/babel-helper-vue-transform-on@2.0.1': + resolution: {integrity: sha512-uZ66EaFbnnZSYqYEyplWvn46GhZ1KuYSThdT68p+am7MgBNbQ3hphTL9L+xSIsWkdktwhPYLwPgVWqo96jDdRA==} + + '@vue/babel-plugin-jsx@2.0.1': + resolution: {integrity: sha512-a8CaLQjD/s4PVdhrLD/zT574ZNPnZBOY+IhdtKWRB4HRZ0I2tXBi5ne7d9eCfaYwp5gU5+4KIyFTV1W1YL9xZA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@2.0.1': + resolution: {integrity: sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.43': + resolution: {integrity: sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==} + + '@vue/compiler-dom@3.5.43': + resolution: {integrity: sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==} + + '@vue/compiler-sfc@3.5.43': + resolution: {integrity: sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==} + + '@vue/compiler-ssr@3.5.43': + resolution: {integrity: sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/devtools-api@8.2.1': + resolution: {integrity: sha512-6u4vXBlIBAC1wMplIZgpyPn7uh/s4Bf6F5bMzvLv+EdJ0aHs/+4B7Ygv864EStQSjRbsRzTko/kUG1A1IejQ3A==} + + '@vue/devtools-core@8.2.1': + resolution: {integrity: sha512-s/VfAY9oDTb/kFEWmy461jaFde2MIV1RO/gi1vwM+PAZBZ/Pc2Ndu3BNBdZUze8QDUuyYvElbEEGA83syjJfzA==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@8.2.1': + resolution: {integrity: sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==} + + '@vue/devtools-shared@8.2.1': + resolution: {integrity: sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==} + + '@vue/language-core@3.3.12': + resolution: {integrity: sha512-k7uIKR0n4CBidk233y7cac9osnDQ5WRidTl6nsrNvpZ3nf8cx9iJxRVsRzVsoPRHbowT/iKgGMTS9RGov3jeIA==} + + '@vue/reactivity@3.5.43': + resolution: {integrity: sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==} + + '@vue/runtime-core@3.5.43': + resolution: {integrity: sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==} + + '@vue/runtime-dom@3.5.43': + resolution: {integrity: sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==} + + '@vue/server-renderer@3.5.43': + resolution: {integrity: sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==} + + '@vue/shared@3.5.43': + resolution: {integrity: sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==} + + '@vueuse/core@10.11.1': + resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} + + '@vueuse/core@14.4.0': + resolution: {integrity: sha512-X4WHz1HlCzCBoYXesUkifzzWBAcZgXG8Fi5iNPQg/epdzOB3gu8Fawj3hvuwYR1nGcXGnvxwYYcUC/71++svtQ==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/core@15.0.0': + resolution: {integrity: sha512-Zv67h5mrk7YHDJsRObx+DXaCBz6RKBUpxqLesJ+3xZNPG6yuQs7ja7kg3veFrrouYLWAqydQ7CwGEbLVxB43Ng==} + engines: {node: '>=22'} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/integrations@14.4.0': + resolution: {integrity: sha512-oJz9qTgczvA7L1nXQFRU7h8tQbOCoiceqvMMhT9XYMyOGTqLJ2rEa09PON+nD2t48sZUfeOmg4eaWJXV4sZb/w==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 || ^8 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 || ^8 + vue: ^3.5.0 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@10.11.1': + resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} + + '@vueuse/metadata@14.4.0': + resolution: {integrity: sha512-swx/255R6JyHZFJhx845iz5CRWDZdCfvkZOpACWc5+c5WHcG24mv8gUT1WIdFQaHt6dq79rvILd9QnCWiyVm9g==} + + '@vueuse/metadata@15.0.0': + resolution: {integrity: sha512-sfWE5LADAKJ0KnjtGliMdSN8Ij/L7uP6rXIZlgPloAI4zvvefbw6H5Lt7KJA6RqQOYgVqWF5Guj50HHMIzygBg==} + engines: {node: '>=22'} + + '@vueuse/shared@10.11.1': + resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + + '@vueuse/shared@14.4.0': + resolution: {integrity: sha512-JRgY90Sz8DDtPMsaDflvPMp9xYk69JZAmbuDvAquUVXKr2gEjqtzGNTTthLfckH0BzBqvnu31gb4a8TGLRe79g==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/shared@15.0.0': + resolution: {integrity: sha512-vbNXhGrbV53xPOMSyOzMHQRvhMgZf7oNDw2RChUetVxwTIEkInQ1joZ9JbT0G3z2n2AJNjvmCWeM9ySYrnvogA==} + engines: {node: '>=22'} + peerDependencies: + vue: ^3.5.0 + + '@webcontainer/env@1.1.1': + resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} + + '@workflow/serde@4.1.0': + resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ai@7.0.128: + resolution: {integrity: sha512-WMKN83DodYtH52ETPHq0jrSwj3wU0aHkhLHXMrwMRabC/aMpIqeWsXJgjkUwrOqkaKHWONdupk/2ttPRvAyFcg==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + alien-signals@3.2.1: + resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansis@4.4.0: + resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==} + engines: {node: '>=14'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + anynum@1.0.1: + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} + + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + assert-never@1.4.0: + resolution: {integrity: sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==} + + ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} + engines: {node: '>=20.19.0'} + + ast-types@0.16.3: + resolution: {integrity: sha512-FvWoWYfSCM6kRxCSH+MGLHIKKGRL6A6AW7Zek2O32REPQRdg131428uRTKMBYAeRd3XXAaHDS60Wpri7CdKDrA==} + engines: {node: '>=4'} + + ast-walker-scope@0.9.0: + resolution: {integrity: sha512-IJdzo2vLiElBxKzwS36VsCue/62d6IdWjnPB2v3nuPKeWGynp6FF/CYoLa5i/3jXH/z97ZDdsXz6abpgM6w07A==} + engines: {node: '>=20.19.0'} + + async-lock@1.4.1: + resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} + + async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + autoprefixer@10.6.1: + resolution: {integrity: sha512-cL1Qz6ADZhcEbny/8HPfe99J6HhNoYtpX2LFLIbhgGE7Q1hlQVkYFdetDN7Id3KiQxhDrHwzlHr/YQCnZ8+xSA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + b4a@1.9.0: + resolution: {integrity: sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + babel-walk@3.0.0-canary-5: + resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} + engines: {node: '>= 10.0.0'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + bare-events@2.9.2: + resolution: {integrity: sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.8.2: + resolution: {integrity: sha512-+ZI68KHMUvosXfKbg/UOHK0tbCdRnegbvPEdEcZ3Nd6TetieQsJPRXBRXPdLyy8+3VSEbPXtsumTpEtt78xv9w==} + engines: {bare: '>=1.28.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-path@3.1.2: + resolution: {integrity: sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw==} + + bare-stream@2.13.4: + resolution: {integrity: sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==} + peerDependencies: + bare-abort-controller: '*' + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.5.4: + resolution: {integrity: sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.11.27: + resolution: {integrity: sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + better-sqlite3@12.11.1: + resolution: {integrity: sha512-dq9AtApgg5PGFtBzPFSBl3HZQjHok5gaQCM6zh2Yk0aSmDCs1CbnVI8/HgASQkNKsWFpseIO9beg5xxpYhbIfA==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x || 26.x} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + + birpc@4.2.0: + resolution: {integrity: sha512-KxgKcZPfrtzJDDALHPguGpGJUrzdgpymyiQQgzFjWreHMOpWrnFNVREr5J48x2DBh8ZVioscrV1SBkDipGiX+Q==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@2.1.7: + resolution: {integrity: sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==} + + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.29.3: + resolution: {integrity: sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bundle-name@4.1.1: + resolution: {integrity: sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA==} + engines: {node: '>=18'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + c12@3.3.4: + resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caniuse-api@4.0.0: + resolution: {integrity: sha512-B0hQ1OLyJuHTQSOWXvwibWqM6DCoqJdvBA6X1S/53bd4XU7LJ1yurIPlrsouol3mw1jh9pGI4ivubSpmJeIqCA==} + + caniuse-lite@1.0.30001814: + resolution: {integrity: sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-parser@2.2.0: + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chardet@2.2.0: + resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + chrome-launcher@1.2.2: + resolution: {integrity: sha512-sI90u5qf3854bTrWsQMMdsQfSjjMbeSn7QtxVb9zrikf+QgMfHQ71KepHW7ZfixQKrDlAFKb+qnVlSR+xepBzw==} + engines: {node: '>=12.13.0'} + hasBin: true + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + citty@0.2.2: + resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} + + clean-git-ref@2.0.1: + resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + cluster-key-slot@1.1.1: + resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} + engines: {node: '>=0.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colortranslator@5.0.0: + resolution: {integrity: sha512-Z3UPUKasUVDFCDYAjP2fmlVRf1jFHJv1izAmPjiOa0OCIw1W7iC8PZ2GsoDa8uZv+mKyWopxxStT9q05+27h7w==} + + comark@0.7.0: + resolution: {integrity: sha512-680hLtUOBcvBEJCD+iCU20jk5TrIJlIcE6X4npdC4x7LBhCvmiYJgByozR2fKav6DYw7AYoXsJVae65kXV6Qhw==} + peerDependencies: + beautiful-mermaid: ^1.1.3 + katex: ^0.17.0 + rangi: ^2.2.0 + shiki: ^4.3.1 + peerDependenciesMeta: + beautiful-mermaid: + optional: true + katex: + optional: true + rangi: + optional: true + shiki: + optional: true + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + + compatx@0.2.0: + resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} + + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + confbox@0.3.1: + resolution: {integrity: sha512-cKUSoKa8YxFZZSmraVi7onONx3amu77ngK3kGpsYHDH7drPwCRkQE1RYMPlLRrMtnciRj274XNRxcHxnKmDSnA==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + constantinople@4.0.1: + resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} + + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie-es@2.0.1: + resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} + + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + + croner@10.0.1: + resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} + engines: {node: '>=18.0'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crossws@0.4.14: + resolution: {integrity: sha512-Pt662HEASY/1s/pOUmTQYyiHgwYO2orX3ivD1lIGJDkO+QL2iz7j5ugMyUNvDiL71n2jV/+0VmU4UXStyiuQ+A==} + peerDependencies: + srvx: '>=0.11.5' + peerDependenciesMeta: + srvx: + optional: true + + css-select@6.0.0: + resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@7.0.0: + resolution: {integrity: sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@8.0.10: + resolution: {integrity: sha512-34uq3q7OXgmfxXn+MHTgIqysCLH7zRZZUMAwrBiO09F5/KLVD33iDFNRRUNYStKdj0SaAIUVr6Akao2Fpp0aVA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + cssnano-utils@6.0.4: + resolution: {integrity: sha512-j1z2mW4MqtcGM4I8TxXAdOXUifp1DZ5/bZnyYnCpHlzQ/ilCj2voLxE0aqEKnBDA5hF6HahSY13JU8kyZ1s8Mg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + cssnano@8.0.10: + resolution: {integrity: sha512-aMlBsvQW5g1b8vfPnkuy5Bk7g/jyRsf5eMpbhe4nKnePx+n2IrC0L6dFqnd3r4/OGNIYGEHfAt09oywi84fWKQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + db0@0.3.4: + resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true + + db0@0.4.1: + resolution: {integrity: sha512-6RBY/bSn42UrqATwsiULj2uYFyEykB3XeA/NLIVQeHNXlYV6D4Idxx3/aa6k5Y45Dwzx7sygeLotnqHWSeURYA==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.1: + resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==} + engines: {node: '>=18'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detab@3.0.2: + resolution: {integrity: sha512-7Bp16Bk8sk0Y6gdXiCtnpGbghn8atnTJdd/82aWvS5ESnlcNvgUc10U2NYS0PAiDSGjWiI8qs/Cv1b2uSGdQ8w==} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devalue@5.9.4: + resolution: {integrity: sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff3@0.0.3: + resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctypes@1.1.0: + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} + + docus@5.14.0: + resolution: {integrity: sha512-Zle9z54Wsc3pU12yLincka2SFmY2QCwhWxUW2r8SfcriIoNYKBxHlXByRRA2/6iZxnk8x+/yuEnkUkyk50ZCsQ==} + peerDependencies: + better-sqlite3: 12.x + nuxt: 4.x + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + dom-serializer@3.1.1: + resolution: {integrity: sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw==} + engines: {node: '>=20.19.0'} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domelementtype@3.0.0: + resolution: {integrity: sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg==} + engines: {node: '>=20.19.0'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domhandler@6.0.1: + resolution: {integrity: sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg==} + engines: {node: '>=20.19.0'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + domutils@4.0.2: + resolution: {integrity: sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==} + engines: {node: '>=20.19.0'} + + dot-prop@10.2.0: + resolution: {integrity: sha512-BTJ9aZYL3vCfZlZOBLy9v8TUqWGQ0pzFnygKwFZt5udj6viBoFIBviKPUoZLDCPn1FoXffv6McQFDenrm5Krfw==} + engines: {node: '>=20'} + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.445: + resolution: {integrity: sha512-iX7o1nF+qNb3Bv5mLYgqfgF9Znh9e/8MKXdmbb8Gv2Q47OKIzTwEPD1oda1HrgEwYatTLJj0wQjHvIFt8Db53Q==} + + embla-carousel-auto-height@8.6.0: + resolution: {integrity: sha512-/HrJQOEM6aol/oF33gd2QlINcXy3e19fJWvHDuHWp2bpyTa+2dm9tVVJak30m2Qy6QyQ6Fc8DkImtv7pxWOJUQ==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-auto-scroll@8.6.0: + resolution: {integrity: sha512-WT9fWhNXFpbQ6kP+aS07oF5IHYLZ1Dx4DkwgCY8Hv2ZyYd2KMCPfMV1q/cA3wFGuLO7GMgKiySLX90/pQkcOdQ==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-autoplay@8.6.0: + resolution: {integrity: sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-class-names@8.6.0: + resolution: {integrity: sha512-l1hm1+7GxQ+zwdU2sea/LhD946on7XO2qk3Xq2XWSwBaWfdgchXdK567yzLtYSHn4sWYdiX+x4nnaj+saKnJkw==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-fade@8.6.0: + resolution: {integrity: sha512-qaYsx5mwCz72ZrjlsXgs1nKejSrW+UhkbOMwLgfRT7w2LtdEB03nPRI06GHuHv5ac2USvbEiX2/nAHctcDwvpg==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-vue@8.6.0: + resolution: {integrity: sha512-v8UO5UsyLocZnu/LbfQA7Dn2QHuZKurJY93VUmZYP//QRWoCWOsionmvLLAlibkET3pGPs7++03VhJKbWD7vhQ==} + peerDependencies: + vue: ^3.2.37 + + embla-carousel-wheel-gestures@8.1.0: + resolution: {integrity: sha512-J68jkYrxbWDmXOm2n2YHl+uMEXzkGSKjWmjaEgL9xVvPb3HqVmg6rJSKfI3sqIDVvm7mkeTy87wtG/5263XqHQ==} + engines: {node: '>=10'} + peerDependencies: + embla-carousel: ^8.0.0 || ~8.0.0-rc03 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + emoticon@4.1.0: + resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + engine.io-client@6.6.7: + resolution: {integrity: sha512-GyAvmPA7gnRCpDQbYACAy79Lg4ewevrmaPzySZz0OVvgyZc3gEfLLqPTYk8wVBScjOEpM9ZO4KryyFpVItjGEA==} + + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + + enhanced-resolve@5.26.0: + resolution: {integrity: sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==} + engines: {node: '>=10.13.0'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + entities@8.1.0: + resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} + engines: {node: '>=20.19.0'} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + error-stack-parser-es@2.0.1: + resolution: {integrity: sha512-J36ntO+rMQVRuR/umlmxmfLi4TpWwtmTnHoJoXTiC2xDNazs0VDPKcX6pbhZMDd2HFtH9isMBJXMdbki+A++Pg==} + + errx@0.1.2: + resolution: {integrity: sha512-chfpPHmCerdo/rXr/nNvPZRkV4WwDRwzwnsJ0Uzz3tVi8Z41tDctRjduYy1138ii77AFlts1qvWtX3g/Acg91Q==} + + errx@0.2.2: + resolution: {integrity: sha512-HaPN6cxm6iZ9bIbQQ5orChcw7SY5smUzM08ZMc6OtV4UQhrrc3Ms1G8Ww2n/9lXkWqiioNTssF8bCvchrSbFEQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.12.0: + resolution: {integrity: sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + esm-resolve@1.0.11: + resolution: {integrity: sha512-LxF0wfUQm3ldUDHkkV2MIbvvY0TgzIpJ420jHSV1Dm+IlplBEWiJTKWM61GtxUfvjV6iD4OtTYFGAGM2uuIUWg==} + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource-parser@3.1.1: + resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + express-rate-limit@8.7.1: + resolution: {integrity: sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + exsolve@1.1.3: + resolution: {integrity: sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-npm-meta@2.2.0: + resolution: {integrity: sha512-99jPl8JkCSCa4VlboNU1XuL98ijm74Pm9CGo6H4BoMVoVh1uhguQcvwLgXDT8Vkl2qj/UEQ0J9gD8beHjTFk1w==} + hasBin: true + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fast-xml-builder@1.3.1: + resolution: {integrity: sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==} + + fast-xml-parser@5.11.2: + resolution: {integrity: sha512-R9iDuNrQYeQut46cn2r2wHKn4HYzVDvDm5J1wW+koZewykv0yuO2HChTYeZtrULyHIDM9cj9TUXloCsueCQUog==} + hasBin: true + + fastq@1.20.3: + resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@11.1.5: + resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@6.1.23: + resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} + + flat@6.0.1: + resolution: {integrity: sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw==} + engines: {node: '>=18'} + hasBin: true + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + + fnv1a-64@0.1.2: + resolution: {integrity: sha512-mJbcILTPybAR1jdOwt/lVv8N2cffeJFFP+gVbSAwLEx1ujXH27RpPd8Rokec/KX9c76UYIB6Co+H4lQzxPnJfA==} + + fontaine@0.8.0: + resolution: {integrity: sha512-eek1GbzOdWIj9FyQH/emqW1aEdfC3lYRCHepzwlFCm5T77fBSRSyNRKE6/antF1/B1M+SfJXVRQTY9GAr7lnDg==} + engines: {node: '>=18.12.0'} + + fontkitten@1.0.3: + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} + engines: {node: '>=20'} + + fontless@0.2.1: + resolution: {integrity: sha512-mUWZ8w91/mw2KEcZ6gHNoNNmsAq9Wiw2IypIux5lM03nhXm+WSloXGUNuRETNTLqZexMgpt7Aj/v63qqrsWraQ==} + engines: {node: '>=18.12.0'} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + framer-motion@14.0.0: + resolution: {integrity: sha512-QAtHmybrDFSliyW1sexMtSQTQd+1jw2ajibEmzpuI4XdPVzQkn+dAzJMm2sW3pl9MJuSS4xN51djQ7huhlP/VA==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + fuse.js@7.5.0: + resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==} + engines: {node: '>=10'} + + fzf@0.5.2: + resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + giget@3.3.1: + resolution: {integrity: sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg==} + hasBin: true + + git-up@8.1.1: + resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} + + git-url-parse@16.1.0: + resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@16.2.4: + resolution: {integrity: sha512-c8B/VNLmxRcmqqenRA9t+9IyOjf9+V6lTxPaUJLqOCONdQkWZ0ETYgX0qbtJqPsgCNusT9MZ5Jeidw8Eb9tn2g==} + engines: {node: '>=20'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hash-sum@2.0.0: + resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + + hast-util-format@1.1.0: + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-mdast@10.1.2: + resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + + hono@4.13.13: + resolution: {integrity: sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA==} + engines: {node: '>=16.9.0'} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hookable@6.1.2: + resolution: {integrity: sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==} + + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + + hookified@2.2.0: + resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-whitespace-sensitive-tag-names@3.0.1: + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + + htmlparser2@12.0.0: + resolution: {integrity: sha512-Tz7u1i95/g2x2jz81+x0FBVhBhY5aRTvD3tXXdFaljuNdzDLJ8UGNRrTcj2cgQvAg3iW/h77Fz15nLW0L0CrZw==} + engines: {node: '>=20.19.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + httpxy@0.5.5: + resolution: {integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==} + + human-id@4.2.2: + resolution: {integrity: sha512-Z+8unD6em/MJwyrkWQ2M3wygRGI1+MztbutiNwk1DCuEPXOZRWGjtcMPZYP1exY9iNZMhd7ZOSMQSo9WYtiQRw==} + hasBin: true + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.12: + resolution: {integrity: sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==} + engines: {node: '>= 4'} + + image-meta@0.2.2: + resolution: {integrity: sha512-3MOLanc3sb3LNGWQl1RlQlNWURE5g32aUphrDyFeCsxBTk08iE3VNe4CwsUZ0Qs1X+EfX0+r29Sxdpza4B+yRA==} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + impound@1.2.0: + resolution: {integrity: sha512-hbFh2WURN+XQ364SbblzubhEEj/B3qZCe80l/EHXPWM6/kZP2mvOllxwRBBWNxe4gLbqXZL0fxOZwoDCSlJZQw==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ioredis@5.11.1: + resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==} + engines: {node: '>=12.22.0'} + + ip-address@10.7.3: + resolution: {integrity: sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipx@4.0.0-beta.1: + resolution: {integrity: sha512-y6bt8CakzpsSO/TiiD8j+1oM+BFJs4rCiJyg8SyBiEaOUIhOu6DFX7lwCpZB/RnUzxVNQFqU4c4IL4MzyRcEQQ==} + engines: {node: ^20.16.0 || >=22.3.0} + hasBin: true + peerDependencies: + unstorage: '*' + peerDependenciesMeta: + unstorage: + optional: true + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-absolute-url@4.0.1: + resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.17.0: + resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-expression@4.0.0: + resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@1.0.1: + resolution: {integrity: sha512-li88H4QGRoNMX27jEmY8nR515oJVspAgC/WFMlhHfFV8RJ4QyGpHhXnwAe9gH5RIgKmdYRUmrOhQobcgEjIdSw==} + engines: {node: '>=18'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-unsafe@2.0.2: + resolution: {integrity: sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + + isomorphic-git@1.43.1: + resolution: {integrity: sha512-88y5HlB8RfZDwWsWyV/wBuXOLfnoZ5Sa7zrfledz/cWkhVxNHRVl105/MGfsReELV7PxChe5jJUphbAl1sKnHQ==} + engines: {node: '>=14.17'} + hasBin: true + + isomorphic.js@0.2.5: + resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + jose@6.2.12: + resolution: {integrity: sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==} + + js-stringify@1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.15.2: + resolution: {integrity: sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==} + hasBin: true + + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} + hasBin: true + + js-yaml@5.4.3: + resolution: {integrity: sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-schema-to-typescript-lite@15.0.0: + resolution: {integrity: sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-eslint-parser@2.4.2: + resolution: {integrity: sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jstransformer@1.0.0: + resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + knitwork@1.3.0: + resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + launch-editor@2.14.2: + resolution: {integrity: sha512-NHJEb30MGBCkmZXLZwz25t37QR4aY03ZzPYUJXOJaOa92uWwExI9SBQUuIznBYc1xkD7cJNGX7oc3Nl3sq2kQQ==} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lib0@0.2.119: + resolution: {integrity: sha512-vh+TiejVy8Xm+hCdnRfn9BthGNvNUZdEXltNjVZL3TzRIKP3s1lnQh8pWd/Q0wCgY0FPAGVVjFF4ZiHUV3LFgA==} + engines: {node: '>=16'} + hasBin: true + + lighthouse-logger@2.0.2: + resolution: {integrity: sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + linkify-it@5.0.2: + resolution: {integrity: sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==} + + linkifyjs@4.3.3: + resolution: {integrity: sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==} + + listhen@1.10.1: + resolution: {integrity: sha512-6nt/86SkqUQSLW1ofz8MxC6RhRMqOl3ONISe6qqvJ3xj09aJWQx6DhgSZpugs3PX4PXdOas/WD6A9jx6J2N19A==} + hasBin: true + peerDependencies: + '@parcel/watcher': ^2.5.6 + peerDependenciesMeta: + '@parcel/watcher': + optional: true + + local-pkg@1.2.1: + resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@8.0.5: + resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} + engines: {node: '>=16.14'} + + magic-regexp@0.10.0: + resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} + + magic-string-ast@1.0.3: + resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} + engines: {node: '>=20.19.0'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} + + magicast@0.5.5: + resolution: {integrity: sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==} + + markdown-exit@1.1.0-beta.2: + resolution: {integrity: sha512-8CzMGVlFZ4DEfnc8KU+4ycUW2SIOuiXqCHD7z51ecVEi/weyc0f2ylQbCm4KoKuVlTZSuMUMnWT0hTyquZ7anQ==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@17.0.6: + resolution: {integrity: sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA==} + engines: {node: '>= 20'} + hasBin: true + + marky@1.3.0: + resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-find-and-replace@3.0.3: + resolution: {integrity: sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==} + + mdast-util-from-markdown@2.1.0: + resolution: {integrity: sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.1: + resolution: {integrity: sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.2.0: + resolution: {integrity: sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + mdurl@2.1.0: + resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==} + + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + microdiff@1.6.0: + resolution: {integrity: sha512-w7JWt8Bno6I8h0rEqlxr4lNG4UbT1FVtWo42wWosIiaJ+rP3pXh7shCYDnyqBrYx36LJ1CZ64p8A62aVp0sJpQ==} + + micromark-core-commonmark@2.0.4: + resolution: {integrity: sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.2: + resolution: {integrity: sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.1.0: + resolution: {integrity: sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-edit-map@1.0.0: + resolution: {integrity: sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.3: + resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==} + + micromark@4.0.3: + resolution: {integrity: sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@4.1.0: + resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} + engines: {node: '>=16'} + hasBin: true + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimark@0.2.0: + resolution: {integrity: sha512-AmtWU9pO0C2/3AM2pikaVhJ//8E5rOpJ7+ioFQfjIq+wCsBeuZoxPd97hBFZ9qrI7DMHZudwGH3r8A7BMnsIew==} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minimisted@2.0.1: + resolution: {integrity: sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + mocked-exports@0.1.1: + resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} + + motion-dom@14.0.0: + resolution: {integrity: sha512-aU3ApXo1yTpeUi3JU+jbDk2TELjxPE3MbBMUP7nZHlARb6RweJK+ojmLjpuB0YsY6zhbBl1YWGo8LMsI1/Llqw==} + + motion-utils@14.0.0: + resolution: {integrity: sha512-jBsyjVxTTRZNeuvd/v+btVXr90LQkYl4HhRu9T2ARc+PMnvkmjsjRVeAg4Qm10b6TlTw+kykWI8gu/6LuvpLSQ==} + + motion-v@2.6.0: + resolution: {integrity: sha512-AJ/fNF7d53DyUg0xfzncDIQ6ztCHUMdLlFAZrSZ0HGQ65Y2ULTOMOlWI5FqQss1JDTstI3A2kOSQVf2+O5C1gg==} + peerDependencies: + '@vueuse/core': '>=10.0.0' + vue: '>=3.0.0' + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanotar@0.3.0: + resolution: {integrity: sha512-Kv2JYYiCzt16Kt5QwAc9BFG89xfPNBx+oQL4GQXD9nLqPkZBiNaqaCWtwnbk/q7UVsTYevvM1b0UF8zmEI4pCg==} + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@1.1.0: + resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} + engines: {node: '>=18'} + + nitropack@2.13.4: + resolution: {integrity: sha512-tX7bT6zxNeMwkc6hxHiZeUoTOjVrcjoh1Z3cmxOlodIqjl4HISgqfGOmkWSayky3Nv9Z5+KQH52F8nmXJY5AAA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + xml2js: ^0.6.2 + peerDependenciesMeta: + xml2js: + optional: true + + node-abi@3.97.0: + resolution: {integrity: sha512-6Pu8F0eXGZlyz0EepPJrWgWDcBI8rKt2Wj8exOJU1tjVbu/VyZy5ZaLYS5N+Jp/Y3IP3sIRKcIOElTu7uC6KKA==} + engines: {node: '>=10'} + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-forge@1.4.0: + resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} + engines: {node: '>= 6.13.0'} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.5: + resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==} + + node-releases@2.0.57: + resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==} + engines: {node: '>=18'} + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nostics@1.3.0: + resolution: {integrity: sha512-wzRsrJwNlFbqIRQt8aCeL2WE8USip/uuvGSOZV1D02CxX8ABTMbw8IywKjH7yWHETMXbWJI4OBpihg9rmz2Vyg==} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nuxt-agent-discovery@0.7.0: + resolution: {integrity: sha512-WaYkVm+NmG6JE1JvSe3iyoRafn2qj347yCB+LY3l/6IJK9+WapoPltXCYloeiDnB0+pn+sgl3rn7Ps/BW3BdWQ==} + peerDependencies: + '@nuxt/content': ^3.0.0 + '@nuxtjs/mcp-toolkit': '>=0.19.0' + '@nuxtjs/robots': ^6.0.0 + '@nuxtjs/sitemap': ^8.0.0 + comark: ^0.6.0 + nuxt-llms: '>=0.1.0' + peerDependenciesMeta: + '@nuxt/content': + optional: true + '@nuxtjs/mcp-toolkit': + optional: true + '@nuxtjs/robots': + optional: true + '@nuxtjs/sitemap': + optional: true + comark: + optional: true + nuxt-llms: + optional: true + + nuxt-component-meta@0.18.0: + resolution: {integrity: sha512-Lo++ctinehNtQvU1SdYdIfYvhUqFtP5nOQsMvbrpFYh53TqwoS97BrS/tjWQe68cfXQaerzhKPFY1Xb1EH4mJg==} + hasBin: true + + nuxt-define@1.0.0: + resolution: {integrity: sha512-CYZ2WjU+KCyCDVzjYUM4eEpMF0rkPmkpiFrybTqqQCRpUbPt2h3snswWIpFPXTi+osRCY6Og0W/XLAQgDL4FfQ==} + + nuxt-llms@0.2.0: + resolution: {integrity: sha512-GoEW00x8zaZ1wS0R0aOYptt3b54JEaRwlyVtuAiQoH51BwYdjN5/3+00/+4wi39M5cT4j5XcnGwOxJ7v4WVb9A==} + + nuxt-og-image@6.9.1: + resolution: {integrity: sha512-34P2MkogprKfpwhT1hcyF+uUR8SpX8Ltg0A29bsPqXtzQV92QqCvMMXw4w00B6WaxY+YXZkT7FCoOOQaAxQoHg==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + '@resvg/resvg-js': ^2.6.0 + '@resvg/resvg-wasm': ^2.6.0 + '@takumi-rs/core': ^1.0.0-beta.3 || ^2.0.0 + '@takumi-rs/wasm': ^1.0.0-beta.3 || ^2.0.0 + '@unhead/vue': ^2.0.5 || ^3.0.0 + '@unocss/config': ^66.10.5 + '@unocss/core': ^66.10.5 + fontless: ^0.2.0 || ^0.4.3 || ^1.0.0 + nitropack: ^2.13.4 + playwright-core: ^1.50.0 + satori: '>=0.33.5' + sharp: ^0.35.4 + tailwindcss: ^4.0.0 + unifont: ^0.7.0 || ^0.8.3 + unstorage: ^1.15.0 + zod: '>=3' + peerDependenciesMeta: + '@resvg/resvg-js': + optional: true + '@resvg/resvg-wasm': + optional: true + '@takumi-rs/core': + optional: true + '@takumi-rs/wasm': + optional: true + '@unocss/config': + optional: true + '@unocss/core': + optional: true + fontless: + optional: true + nitropack: + optional: true + playwright-core: + optional: true + satori: + optional: true + sharp: + optional: true + tailwindcss: + optional: true + unifont: + optional: true + zod: + optional: true + + nuxt-schema-org@6.4.3: + resolution: {integrity: sha512-2iZC8iyELkRo0rf58ZKa7pp+RepVwGOdfwa9/n8DV/wVuR6TxEBZxZmOcXrdx9a1vB55ulZiI6Dc32s+f1aJeQ==} + peerDependencies: + '@unhead/vue': ^2.0.7 || ^3.0.0 + unhead: ^2.0.7 || ^3.0.0 + zod: '>=3' + peerDependenciesMeta: + '@unhead/vue': + optional: true + unhead: + optional: true + zod: + optional: true + + nuxt-site-config-kit@4.2.3: + resolution: {integrity: sha512-xAU061MrxDlv1CjHjP9+Qg3mAdKxQgO9sFzoy+LblKW+DDLRMGjaEIna/QUk0F0kWzhrf4dSpOVTW8OZv26xVg==} + + nuxt-site-config@4.2.3: + resolution: {integrity: sha512-m0CK1Q43T3qtVHSBYeDHav/hp8t/ahhlJGzwdBOQM6WcxeZpF1wcJazoGQAJEFamX1xcRAtA0ZuvvEkwHSMG0w==} + peerDependencies: + vue: ^3.5.30 + + nuxt@4.4.8: + resolution: {integrity: sha512-r/DGE4cNkEDclOw9tbJ18zqu+ix3me+7QCfumPdl5lBXGWgCajskzuq/HzDkHKfIZsn7ACVEjMLRNA2teh++bQ==} + engines: {node: ^22.12.0 || ^24.11.0 || >=26.0.0} + hasBin: true + peerDependencies: + '@parcel/watcher': ^2.1.0 + '@types/node': '>=18.12.0' + peerDependenciesMeta: + '@parcel/watcher': + optional: true + '@types/node': + optional: true + + nuxtseo-shared@5.3.16: + resolution: {integrity: sha512-0Ood/aB/6PtWHFx6JB4Ub/InEbilW29cvTFGX5pIWyGf9Wewyil0T4481F/IUhvabHUGssWqErmn+mKoY/z6qA==} + peerDependencies: + '@nuxt/schema': ^3.16.0 || ^4.0.0 || ^5.0.0 + nuxt: ^3.16.0 || ^4.0.0 || ^5.0.0 + nuxt-site-config: ^3.2.0 || ^4.0.0 + vue: ^3.5.0 + zod: ^3.23.0 || ^4.0.0 + peerDependenciesMeta: + nuxt-site-config: + optional: true + zod: + optional: true + + nypm@0.6.10: + resolution: {integrity: sha512-W72Hrj1petq+b3Hk2aAC+9zswetlIFTnDW4s5djseZh2nYqBbyQLOtj472HwcbcWykPBUW1WpWpjOd4nK6gMRw==} + engines: {node: '>=18'} + hasBin: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-identity@0.2.3: + resolution: {integrity: sha512-2J8Joz2Tf7aaylhqFvIUJHNgpuGR38Hh75Voq9GzTbStBxJUaOtN0K1aOd3cV5qp+ij1pMqRbPrGCGMOyX303w==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@2.2.1: + resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} + engines: {node: '>=12.20.0'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.12: + resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==} + + on-change@6.0.2: + resolution: {integrity: sha512-08+12qcOVEA0fS9g/VxKS27HaT94nRutUT77J2dr8zv/unzXopvhBuF8tNLWsoLQ5IgrQ6eptGeGqUYat82U1w==} + engines: {node: '>=20'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + + open@11.0.4: + resolution: {integrity: sha512-++Zlftm0kVLPmzC06t6epuWmcRMDbI4z5P3NNX979WA/k23+NtSOynEGzsVfZwguKw2mi5umVgnBlJQMwRz4Pg==} + engines: {node: '>=20'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + oxc-minify@0.133.0: + resolution: {integrity: sha512-6bNsYU+5WNIaNHB16zHnL24cUaJuKiPzUvjENoMale3+U8ZBMbGYgdgt//frx0ge7UcgEGIpqtukGGNPT0kxfQ==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-parser@0.133.0: + resolution: {integrity: sha512-661RSx+ZcjBmjBYid+Fpp/2F5EbtildpeoZh5HdgnGs+jZ03nqQEQW8yGkt4BGyOC3OMPDQQRl8M5kqD2/g6jw==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-parser@0.139.0: + resolution: {integrity: sha512-cf1TKZN+zc0lwqigeyXKzKVk5+vNRe99Or2+wVJsXLdlhJgC+gsIniYDfj/ZEBzCJ8Xm21ZG6YtMbR262CcS2w==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-parser@0.141.0: + resolution: {integrity: sha512-uFkGGr1KMWd6aWv9UAqooYrN78trw8MWWmoPvgWokfBEUq1+eiIQ+qfj3wokhy0fxtZWZk+0dHoS7/yRTJtd6w==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-parser@0.151.0: + resolution: {integrity: sha512-cX++XpBDCtSe52KKH3rhbh6xIRidYPpyB2reI3azD4l+Y0ci4JZiUgVXyM/r9rrMnYZf9gdWi+9fvFl1wol7nA==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-transform@0.133.0: + resolution: {integrity: sha512-9lt2b+hkG6yqe0fUDMHhMk7rgI9uTjNxU9wauQiYnHzc4kZI8JP/OhBqXTIJQTrqRJ8CkSH3O5AhQ13ke28yNg==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-transform@0.141.0: + resolution: {integrity: sha512-CrMPblXfPl57WIvGjynrUThcyEGcS3E3YUHkPYAwXYYla23gLlaIYifVFTMQsFr5uxA/2k/XMG5n6c/XsuAvaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-walker@0.7.0: + resolution: {integrity: sha512-54B4KUhrzbzc4sKvKwVYm7E2PgeROpGba0/2nlNZMqfDyca+yOor5IMb4WLGBatGDT0nkzYdYuzylg7n3YfB7A==} + peerDependencies: + oxc-parser: '>=0.98.0' + + oxc-walker@1.1.1: + resolution: {integrity: sha512-Hwd7dq28zu/Er99+bpWp16CGwFrhyalJh0W3JOB7XpPvgWo3MqMi2ksWGKuzzA9zt50mJ2pIUwR5lpAdZ9ACNQ==} + peerDependencies: + '@oxc-project/types': '>=0.98.0' + oxc-parser: '>=0.98.0' + rolldown: '>=1.0.0' + peerDependenciesMeta: + '@oxc-project/types': + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + package-manager-detector@1.9.0: + resolution: {integrity: sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-url@9.2.0: + resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} + engines: {node: '>=14.13.0'} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-expression-matcher@1.6.2: + resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} + engines: {node: '>=14.0.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.3: + resolution: {integrity: sha512-j/lCFdcppV0JxWpCEITdbDltBxPP6cHT+yNJ6Go2OgoSA9518X847X9z0p6LtA4Nc16+eQzCZjRrWanTGvHJ5w==} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@8.0.5: + resolution: {integrity: sha512-U/N+7tkHgHoD24NB6q9k9uFcRfVJRdzVSit0fM0T2L6fvnpUoTIAYgzkyjD56LHEoCoPNfkMcfTB47SW/lNegQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-convert-values@8.0.4: + resolution: {integrity: sha512-ifBmAJBfpDymi7r/CqxYRJWlG+BLdVmusUC/kFPOqH/+TitdBeHA68CYqY79wXL+iQnqg6e4LGHA2Mte14X6Ig==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-discard-comments@8.0.4: + resolution: {integrity: sha512-SU1uLYRQPKLJJmqEmqzu+Ze+9xDurBm7m/LOzXG/ANBAfAGLjbQF+oIyZnf3jV3F155q5rRMYXsoTNEJsPyHng==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-discard-duplicates@8.0.4: + resolution: {integrity: sha512-/ugMYYTE+IpHpTmwz6/S8w+blCz9pZNroUgadTdlbPnHoLLWis9QvwmoyWui2mOgFzuRM6Me7AnoGU3i0Ua2ng==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-discard-empty@8.0.5: + resolution: {integrity: sha512-im0QtfNFa6V3SGPrfqzrWYuhzSz1ztWORKsuhZHQbWdKMh0DiNj3pmqBnABbhdKjyeW6nZ1oZYGh4dMc3biyaw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-discard-overridden@8.0.4: + resolution: {integrity: sha512-NqupxmnSSfWPJJDYbQk1qXWRwr+lw4Kyp/LSOjqwTpy/vSwo34EVXYKywgemSWpgh39P7Cs/G+tqynbRlXoJhw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-merge-longhand@8.0.4: + resolution: {integrity: sha512-ammolHhMvuTz/L9YN/ge1SWbUDcD3Y9o2gXlo3S6H4MCJHheyVPwcI/LAnSuNT4gcUmSF9pNTXo7+3M/2MFPAQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-merge-rules@8.0.5: + resolution: {integrity: sha512-jz+QaKz4VhjsqTVsJMRuH+EvrX1F9l6kYFuF8g6geVxFoYnPEZN4G+zqCb6zhxOIcc2aeAo38XEl2pOIZi2gBw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-minify-font-values@8.0.4: + resolution: {integrity: sha512-wZZgJ87U5WbQCEM0EOY/oM7M1a+sqW6vrOClGC9lNbsY0HYmbMFvFuukBn8PzF+ikKmaT0QB+uSAHTRLzMkD+A==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-minify-gradients@8.0.6: + resolution: {integrity: sha512-NsqlG34WSO44NOHVT6m6ZWpN80fK2l5Zt73PMDXBJKT6fO6GPnI0NBi6xIVFr/naej3ukVUlIFQGxb7JGaa9Zg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-minify-params@8.0.4: + resolution: {integrity: sha512-TDx9O/ni7KazRK32pVvoo3MjExyVxWE0949vB2XZ0oHnxdAtQFHa9oG21wWkvsOL3osjiOVejwDLe6a0d0EuSw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-minify-selectors@8.0.5: + resolution: {integrity: sha512-i+PlhVCaPa7xevjhpActH2PrP27kDNSuuFf/ZGk8YrIcd1pd3Mfcfiv8H7dbY1/vz7U+QparioAtJaFV+IEwQg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-charset@8.0.5: + resolution: {integrity: sha512-l0L1rIe9YHbLaf4xfL2pkkQV3gq/QIy8D0bjsaHYdGVgR+eQk7IBp3dUdIKe6XuG7DzFiCwJn248nvAFAi5CjA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-display-values@8.0.4: + resolution: {integrity: sha512-F8DGtzelJDV6S5mhcugc+EJ8sXI+kFv2PBedkfMWqd8mvTE4qyy3kva6AQwjy2+L2lZ9TGTkSumdq+n3EhGeAw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-positions@8.0.4: + resolution: {integrity: sha512-anOMhqe6Z0OP4jvchK1v1hIG08kO7rsp8uHrxT2+XaKp8wbvVcUO3QHUzRmQDazWUPtRzy1h2UlixyJenF42sg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-repeat-style@8.0.4: + resolution: {integrity: sha512-vY8+k+/bFT7B8gzlHVye8FxBTMEpUAQxAgb4UYFAGGsKmXfwEvc7VPs+kpFNrTeqVKAvVh8+VVhZ+f3S4TWJPg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-string@8.0.4: + resolution: {integrity: sha512-dWnV1frIV1XUlSYzJudceAbQ7PGyho9EgVHQXMcAoog6Nwnet3G9rz8IXcCb0EF2eefmpYG9hDT9+yWJOxc5zw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-timing-functions@8.0.4: + resolution: {integrity: sha512-VANJsokAWdQ03ZJwmcdEKXJjVHRtMgalB/BgbCgN3CRTdbwB5TXlSDRmdShSCxpnZs8WLAm0mPa//p5o5D/ZTg==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-unicode@8.0.4: + resolution: {integrity: sha512-SxVEoFdYed0bxxwZwAXnaAZ2lzNb5jtiQvYWyMIEqnGOzCuztWpVO8LvsqpOfUIacOb6oYaWi7WOAZR36OhYqw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-url@8.0.4: + resolution: {integrity: sha512-JKZW8KRHkLEYkUb/55n3knDUMZeyvxlTv7ZA82bcHiCjL81b0Yyf9fIUBAYKZ6ucDgKfCDM78xhXuteVlk/o9Q==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-normalize-whitespace@8.0.5: + resolution: {integrity: sha512-xuFovful3vVIA9fWWmAL2pG1Qr95Udj2MrLgjU50C6r+Xnh3s6t2BN1xXQ8lnCOCAtzMvMpPWYlnAh4nSv5VEQ==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-ordered-values@8.0.5: + resolution: {integrity: sha512-aDL7nPR7w1foUqo4rN6QY1Kr45+SYELnmUg5taZehh7FfFdxQmUjbuOOBuffIXjiHV45zqgFHCb4azsWW19jyw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-reduce-initial@8.0.5: + resolution: {integrity: sha512-Bh5d7zjH1Ai9LzJ1qULUZIaC18cniD+wA6gFlOPglMxJRC7meXbuPvpJ/zHQGg5QKwQgit++XQhDTiEIhCk8Ow==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-reduce-transforms@8.0.4: + resolution: {integrity: sha512-ZGU7/R0GmjE3x2mOGB0g9Ohx74X+JjYX62RB5IBYLOe6R0fuHGZ76HtTY2CdM5NE8Yey/ew5clEf8iZQnjDjWA==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-selector-parser@7.1.6: + resolution: {integrity: sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==} + engines: {node: '>=4'} + + postcss-svgo@8.0.6: + resolution: {integrity: sha512-auQHNmduFFHzz1sWYM3sroW7IDMzxshlLjnwAALfkrAgPegHFats+jMK6BRCcdIulxPmqXFSQvgoAX4vw8I59g==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-unique-selectors@8.0.4: + resolution: {integrity: sha512-Sby0EtmD1mlvcZSWP5eXjxhxVgvXE5QVRzd+8NH0IbF+lYQIM57ybwAvJYYtI/fexMgCWcRnDETovjKOcLJb8w==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.29: + resolution: {integrity: sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==} + engines: {node: ^10 || ^12 || >=14} + + powershell-utils@0.2.1: + resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==} + engines: {node: '>=20'} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-bytes@7.2.0: + resolution: {integrity: sha512-T2kroepGB5DRVbkN/nOpW03+VRWqdtJhZNuCW3wYk3chdPjgi4GcTBOaxWfHq1MIM0ypidxsSWbQaAiRpxnXmg==} + engines: {node: '>=20'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + + prosemirror-changeset@2.4.4: + resolution: {integrity: sha512-Gyuz9jYdrAeA9I7AholyOes9KUmv/lEwsC5O9s5xF5VB3EgTPsXMGUxz4+H1B+wKVPdZbvRcg1Cp3x8qX+8ofA==} + + prosemirror-commands@1.7.2: + resolution: {integrity: sha512-q6Q6szxqdu9Xd6EcdKsqXghu5nQdZTpB4Q9yd04WRc7/jt763e/rT60Owh0L1GYY+T46o5rD+9lEN36dZS43tw==} + + prosemirror-dropcursor@1.8.4: + resolution: {integrity: sha512-VmKxhcA6a+h5oPSYmfF1ZNeQqPbyYaIxqZsKqeYCyTlPtrjUgNaHL3P8vVaO19oqAV0zuaM/axkowZHrB1P3Tg==} + + prosemirror-gapcursor@1.4.1: + resolution: {integrity: sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==} + + prosemirror-history@1.5.1: + resolution: {integrity: sha512-onlwnqKvgtFg6srZOmDOAhlAy1FIHQpOExORybX0S+DvJepE5tPALrB9iGet/2sqqqrelSnB10OoiOJqAvu2DA==} + + prosemirror-inputrules@1.5.1: + resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-model@1.25.12: + resolution: {integrity: sha512-Ue2gTmXMa7EhpLNhC7J+h4+ykD8ha12K6rrZFFKKJHBForfIStw5gJ6Zrf1mqqAa9NmpmEB4wp9bKmA4eUVjWg==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + + prosemirror-tables@1.8.5: + resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} + + prosemirror-transform@1.12.2: + resolution: {integrity: sha512-PE/aY0HEY4zczvmqrilgkUK/WautF0chvMqkmM/iN5/aPHvwrCWaQZjS6CIZp+K84YrvPFqrL+YArrfJX8xX7g==} + + prosemirror-view@1.42.6: + resolution: {integrity: sha512-3g25f6hKV2bBxo3puH3EcYWmmVNSH0iWmNsMVT7sugDSpA025jgpOLarcDWr39SdzPjYMaiYtRdNtXialPSjEQ==} + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} + engines: {node: '>= 0.10'} + + publint@0.3.25: + resolution: {integrity: sha512-WMMbn/d7JqRlfXQL/JUI4n5skC8cJ5WVr8/wT5mmiYWkUdENkZr1I5rgs2+dQPVRgoJd+JRYtB46MTsuDylw9g==} + engines: {node: '>=18'} + hasBin: true + + pug-attrs@3.0.0: + resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} + + pug-code-gen@3.0.4: + resolution: {integrity: sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==} + + pug-error@2.1.0: + resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==} + + pug-filters@4.0.0: + resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} + + pug-lexer@5.0.1: + resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} + + pug-linker@4.0.0: + resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} + + pug-load@3.0.0: + resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} + + pug-parser@6.0.0: + resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} + + pug-runtime@3.0.1: + resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} + + pug-strip-comments@2.0.0: + resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} + + pug-walk@2.0.0: + resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} + + pug@3.0.4: + resolution: {integrity: sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qified@0.10.1: + resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} + engines: {node: '>=20'} + + qs@6.16.0: + resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} + engines: {node: '>=0.6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + rc9@3.1.0: + resolution: {integrity: sha512-ufjkNVzbRHKcCOmTahZkmVsyc3W+MSk3jY03m+a7tGHkIsdVMG9l10/3HvFbWkkKzY5VFp3pkRsIo/UYgmFL7Q==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + recast@0.23.21: + resolution: {integrity: sha512-mFAyJq9vUbSTARLZUvAEf1z3YxlvAwswbmxMx2mPA/MSm4KmpwvwvhsH/NIrZhyOuwD60Lzyw2qh83uCbgTPYw==} + engines: {node: '>= 4'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + rehype-external-links@3.0.0: + resolution: {integrity: sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==} + + rehype-minify-whitespace@6.0.2: + resolution: {integrity: sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-remark@10.0.1: + resolution: {integrity: sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ==} + + rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + + rehype-sort-attribute-values@5.0.1: + resolution: {integrity: sha512-lU3ABJO5frbUgV132YS6SL7EISf//irIm9KFMaeu5ixHfgWf6jhe+09Uf/Ef8pOYUJWKOaQJDRJGCXs6cNsdsQ==} + + rehype-sort-attributes@5.0.1: + resolution: {integrity: sha512-Bxo+AKUIELcnnAZwJDt5zUDDRpt4uzhfz9d0PVGhcxYWsbFj5Cv35xuWxu5r1LeYNFNhgGqsr9Q2QiIOM/Qctg==} + + reka-ui@2.10.5: + resolution: {integrity: sha512-/8o0y9BThE0hcHKFg+3770tWcJh3qKdOEFxLOPb9HIajXeFoH/J530cZH62jUJunbqwBgpSBL9v7nB8LJ5pDXA==} + peerDependencies: + vue: '>= 3.4.0' + + remark-emoji@5.0.2: + resolution: {integrity: sha512-IyIqGELcyK5AVdLFafoiNww+Eaw/F+rGrNSXoKucjo95uL267zrddgxGM83GN1wFIb68pyDuAsY3m5t2Cav1pQ==} + engines: {node: '>=18'} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdc@3.11.1: + resolution: {integrity: sha512-bjH7Q1OO1BSXVPmUxYIrGH2dUAZkizNY3i9WJUEcIFLowZAEjLTT7fUAH2vH0Tpkeh+/MrzwFFmeWcZ66QLh7A==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown@1.2.12: + resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup-plugin-visualizer@7.1.1: + resolution: {integrity: sha512-ThaGiHTU8XW02OkK80TrTHATraJmM9OAduU4otal+7gyXLpYEtmGBLfx5kW+EHvvLwn03YGW2NnwKUIqsYlJAA==} + engines: {node: '>=22'} + hasBin: true + peerDependencies: + rolldown: 1.x || ^1.0.0-beta || ^1.0.0-rc + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup@4.64.0: + resolution: {integrity: sha512-gjA/kFeDfffII8COoPsvLPvE16hWDTEc1+0QKQNKUkuV8iJjqsC4xXs8/FzuL0v9EV39kuxTbAgcFoTRyy2TGQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + + rou3@0.8.1: + resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} + engines: {node: '>=11.0.0'} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serialize-javascript@7.1.2: + resolution: {integrity: sha512-GL2BWwVa6JydKO6l/ljVgjAZF4QJ3S7dWDWi53s5GZT8PJzD2fNxi67HANQGKAqPrwEpL5ba7gUBGi0Ls/sEoQ==} + engines: {node: '>=20.0.0'} + + seroval@1.6.8: + resolution: {integrity: sha512-HlSgSAkTk4EqHcje1ptJjfZi1YDv5KbhVJ/d3P7T/nAXua2VmDu+AKDX5VTdFfZf48nDkWB2TKYt0DrCSa+3wg==} + engines: {node: '>=10'} + + serve-placeholder@2.0.2: + resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + sharp@0.35.5: + resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.12.0: + resolution: {integrity: sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==} + engines: {node: '>= 0.4'} + + shiki@4.5.0: + resolution: {integrity: sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==} + engines: {node: '>=20'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + simple-git@3.36.0: + resolution: {integrity: sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + site-config-stack@4.2.3: + resolution: {integrity: sha512-9kJn4YoJvJqbxbE5T1WYl7ibL4SYngcKQ3sP8SfJcgzqtawMMwuBuC2h/DuFSLqVE5ZyMqGtMONm/ax8nSHVrw==} + peerDependencies: + vue: ^3.5.30 + + sitemapd@0.2.2: + resolution: {integrity: sha512-XAuW9x2cI3B757A/h2sFYfye5kBUHM8Gr6Muzwtve1oYRCv3BntoKMcgNu+GNF/LKIvUD1fQpBTVUCoHlzMihg==} + engines: {node: '>=18.0.0'} + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + slugify@1.6.9: + resolution: {integrity: sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==} + engines: {node: '>=8.0.0'} + + smob@1.6.2: + resolution: {integrity: sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==} + engines: {node: '>=20.0.0'} + + socket.io-client@4.8.4: + resolution: {integrity: sha512-7wjKAvVXYOJsbmUgkWbnhPD4bFpkqrUR0++XOjpGFmqDqsqV1CI93VTraeExLxpjxEqrWgFoSRZu1ihjLWfkAA==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.7: + resolution: {integrity: sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg==} + engines: {node: '>=10.0.0'} + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + source-map@0.8.0: + resolution: {integrity: sha512-d8EqvL+k/SOXCreS/SUzg2ciyHqBBLcN/yuRjFsbvVhHTE2pgei7oAhmPM7kWFbkX6OSMQfUq4KbkF3au9lhYQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + srvx@0.11.22: + resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==} + engines: {node: '>=20.16.0'} + hasBin: true + + srvx@0.12.8: + resolution: {integrity: sha512-7k9HoDhluTlD7UJ+F+OopZoPZXB2J8f/5nW2VMLaB8KsSlZlRQxyyoX0hWEQCxB+F+3ZvB5QX3LqB6xSBRfxQQ==} + engines: {node: '>=20.16.0'} + hasBin: true + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@4.3.0: + resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==} + + streamx@2.28.1: + resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-literal@4.0.0: + resolution: {integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==} + + strnum@2.4.2: + resolution: {integrity: sha512-rDG3Ah4TV0k1hWvLSzkZtMmLN9+eS+h3knq4MP6A42Y3Yh5qGNnOUs1jJkoSr8FG5dsL28c7KgkIBzSEykqtuw==} + + structured-clone-es@2.0.1: + resolution: {integrity: sha512-10ZL5r77LhknxlP1FBiCW+VdnuWOEFLdSS2SKtjyEV+L4qP1hUEIMIZW94LC3jKxRmT/Dj7KkD1mqh/IY6lhKQ==} + + stylehacks@8.0.4: + resolution: {integrity: sha512-irgZeyYBFVkb8k7yTRQ9No/bTniTGqzptGVMG1/Mj3N2YnI8nIozzY1pcok4i01NfrCSqvc0PdQB6O6kr6dJHw==} + engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} + peerDependencies: + postcss: ^8.5.26 + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@4.1.0: + resolution: {integrity: sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==} + engines: {node: '>=16'} + hasBin: true + + swrv@1.3.0: + resolution: {integrity: sha512-6uyQ79QemgpJzdwVNkxZdypTmKC80uHdjSZGAGo0HnizL2AzQJUZXQFR3KZq8yru32IC7HngiBA7o2FtL/Lozw==} + peerDependencies: + '@vue/test-utils': '>=2.0.0' + vue: ^3.2.0 + peerDependenciesMeta: + '@vue/test-utils': + optional: true + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tailwind-merge@3.7.0: + resolution: {integrity: sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==} + + tailwind-variants@3.3.1: + resolution: {integrity: sha512-4pAvwUtM4HKBiRZftncAbpn6V9Hhwoa5Fl7O2u5zbp7Z5Cvu+/o/6+176WY3WCEES209543quG8zFIcXCsc5Jw==} + engines: {node: '>=16.9.x', pnpm: '>=7.x'} + peerDependencies: + tailwind-merge: '>=3.0.0' + tailwindcss: '*' + peerDependenciesMeta: + tailwind-merge: + optional: true + tailwindcss: + optional: true + + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tar-fs@2.1.5: + resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar-stream@3.2.2: + resolution: {integrity: sha512-+8NeqHRjQWH9nYlwo2gamAMImZCVzI4UoEgDpWorBt9OEfppiZn+uSkskzQKPWIZyji/C8fpWO7u69G0DX0tbg==} + + tar@7.5.22: + resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} + engines: {node: '>=18'} + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + terser@5.51.2: + resolution: {integrity: sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==} + engines: {node: '>=10'} + hasBin: true + + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinyclip@0.1.15: + resolution: {integrity: sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==} + engines: {node: ^16.14.0 || >= 17.3.0} + + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-stream@1.0.0: + resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + + tosource@2.0.0-alpha.3: + resolution: {integrity: sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==} + engines: {node: '>=10'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trim-trailing-lines@2.1.0: + resolution: {integrity: sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-map@1.0.3: + resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} + engines: {node: '>=20'} + + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + + type-level-regexp@0.1.17: + resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + ultrahtml@1.7.0: + resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + unctx@2.5.0: + resolution: {integrity: sha512-p+Rz9x0R7X+CYDkT+Xg8/GhpcShTlU8n+cf9OtOEf7zEQsNcCZO1dPKNRDqvUTaq+P32PMMkxWHwfrxkqfqAYg==} + + unctx@3.0.1: + resolution: {integrity: sha512-5RAt2etv7g362RXyd33R82gm9u/kbtQlpoaOs9Bgm4E32GRMJ0xjbZyvdxUTmiuHk3V1IQb1aUNrp5IWY+JaWw==} + peerDependencies: + magic-string: '>=0.30.21' + oxc-parser: '>=0.140.0' + rolldown: ^1.1.5 + unplugin: ^3.3.0 + peerDependenciesMeta: + magic-string: + optional: true + oxc-parser: + optional: true + rolldown: + optional: true + unplugin: + optional: true + + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + + undici@7.30.0: + resolution: {integrity: sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==} + engines: {node: '>=20.18.1'} + + undici@8.11.2: + resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==} + engines: {node: '>=22.19.0'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + + unhead@2.1.17: + resolution: {integrity: sha512-HLMKXOszRhAPBrr6VlqCeVeJq2kbC4kXwzGLEZvvojPLWNYTJw22xG7Bfwhsvs31+IBet3Wl8ADg9dwYdyphfQ==} + + unhead@3.4.2: + resolution: {integrity: sha512-LmD1cV1QFIru0AyJi404no2p0ivXUli+lOLs2/fxP56ATJzTF2wSTJNh45YSYGtFD5QmQTWNHmhnXHkVAET1dA==} + peerDependencies: + vite: '>=6.4.2' + peerDependenciesMeta: + vite: + optional: true + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unicorn-magic@0.4.1: + resolution: {integrity: sha512-lzlXPoVB0Uy/FvTaUgX39RbixYiSKoc3JSoSf01+0c2B6FR3qdYIPN7Qjo/AV7n6sqLCk0509cT3LRj1oSZ1+A==} + engines: {node: '>=20'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unifont@0.7.5: + resolution: {integrity: sha512-ULe/Cs+ZIsq+dcFofNkhqielCrUJnb5mr+Yc4EBM2VlL+6OZR6+cjtI2mT1bJvRBrVncqHAbLURxmPLcCXzWMg==} + + unimport@6.5.0: + resolution: {integrity: sha512-t0KLJLRbebz3f7NrQe+vy2ObeugVeM1XqI2oeYnauddmHSglYj3U6bxOJ65IbXmOFkcAGFJK2OyGH7aqHPM6Ug==} + engines: {node: '>=18.12.0'} + peerDependencies: + oxc-parser: '*' + rolldown: ^1.0.0 + peerDependenciesMeta: + oxc-parser: + optional: true + rolldown: + optional: true + + unist-builder@4.0.0: + resolution: {integrity: sha512-wmRFnH+BLpZnTKpc5L7O67Kac89s9HMrtELpnNaE6TAobq5DTZZs5YaTQfAZBA9bFPECx2uVAPO31c+GVug8mg==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-auto-import@21.1.0: + resolution: {integrity: sha512-EzrSqWIBulEqCuP7idADXH+tVKYrbwKlR5+r/lOWik0o+Ksny1kitmtryHGNSv7puzzORlcIwT/x2JStiszlHA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@nuxt/kit': ^4.0.0 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-dts@1.1.2: + resolution: {integrity: sha512-RDqy90XUmFj6rz4U5YoTMdYdaCJe2ZnQZaWIjkWS4952Gv0zBTQyqWtlGgVMPYHa982dURvyoc+sUOFIcDFv+w==} + peerDependencies: + '@microsoft/api-extractor': '>=7' + '@rspack/core': ^1 + '@vue/language-core': ^3.1.5 + esbuild: '*' + rolldown: '*' + rollup: '>=3' + typescript: '>=4' + vite: '>=3' + webpack: ^4 || ^5 + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@rspack/core': + optional: true + '@vue/language-core': + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + + unplugin-utils@0.3.2: + resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==} + engines: {node: '>=20.19.0'} + + unplugin-vue-components@32.1.0: + resolution: {integrity: sha512-YiUkSxuRjab18XFOrX5VsIxXzccrfmHVGsGeJgSgklb829DQmCy9E4vvDUE4tuvZZdxyFJZX0Oc4TPnnxiiMyg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@nuxt/kit': ^3.2.2 || ^4.0.0 + vue: ^3.0.0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + unplugin@3.4.0: + resolution: {integrity: sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rsbuild/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rsbuild/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + + unrouting@0.1.7: + resolution: {integrity: sha512-+0hfD+CVWtD636rc5Fn9VEjjTEDhdqgMpbwAuVoUmydSHDaMNiFW93SJG4LV++RoGSEAyvQN5uABAscYpDphpQ==} + + unrouting@0.2.3: + resolution: {integrity: sha512-8wOFT/fBh8YeeDr1aVmkXCqYVTMbQ6vzfNzwzybKmSfXdRhGCq1Y2B1e9YeB0JEf85gbvSwJHAMu3D2IEcLGKA==} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + untun@0.2.2: + resolution: {integrity: sha512-+NnOJcSiEtYsVgJmXUzQbJeRAFXJC4yPJYuh6kF9B0Rm6zunXcs/3GZOTllyocSbUDIxD6Bj7e/4ATw7sph1Sw==} + hasBin: true + + untyped@2.0.0: + resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} + hasBin: true + + unwasm@0.5.3: + resolution: {integrity: sha512-keBgTSfp3r6+s9ZcSma+0chwxQdmLbB5+dAD9vjtB21UTMYuKAxHXCU1K2CbCtnP09EaWeRvACnXk0EJtUx+hw==} + + update-browserslist-db@1.3.3: + resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uqr@0.1.3: + resolution: {integrity: sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vaul-vue@0.4.1: + resolution: {integrity: sha512-A6jOWOZX5yvyo1qMn7IveoWN91mJI5L3BUKsIwkg6qrTGgHs1Sb1JF/vyLJgnbN1rH4OOOxFbtqL9A46bOyGUQ==} + peerDependencies: + reka-ui: ^2.0.0 + vue: ^3.3.0 + + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-dev-rpc@2.0.0: + resolution: {integrity: sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 || ^8.0.0 + + vite-hot-client@2.2.0: + resolution: {integrity: sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0 + + vite-node@5.3.0: + resolution: {integrity: sha512-8f20COPYJujc3OKPX6OuyBy3ZIv2det4eRRU4GY1y2MjbeGSUmPjedxg1b72KnTagCofwvZ65ThzjxDW2AtQFQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + vite-plugin-checker@0.14.5: + resolution: {integrity: sha512-c9lQ92eisUO+F7Fd93aelojmiOS+NQpPgQ1XR2LTQHox1/laZf4yAoQj+L3RA9Vgh10e2nFd9b8r2LLyYZsbpA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@biomejs/biome': '>=2.4.12' + eslint: '>=9.39.4' + meow: ^13.2.0 || ^14.0.0 + optionator: ^0.9.4 + oxlint: '>=1' + stylelint: '>=16.26.1' + typescript: '*' + vite: '>=5.4.21' + vue-tsc: ~2.2.10 || ^3.0.0 + peerDependenciesMeta: + '@biomejs/biome': + optional: true + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + oxlint: + optional: true + stylelint: + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + vite-plugin-dts@5.1.2: + resolution: {integrity: sha512-1bXUz836sWq6ewEMQre3ZtNFVfZk/92DppgCCKP8tWx/NWwV2wHuXlRHb2TztHjbikPxvyAGLGu7hVh94Plwww==} + peerDependencies: + '@microsoft/api-extractor': '>=7' + rollup: '>=3' + vite: '>=3' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + rollup: + optional: true + vite: + optional: true + + vite-plugin-inspect@11.4.1: + resolution: {integrity: sha512-ShOFe2PURXGvRS5OrgmOLZOCwDTD7dEBVt0tMpFPKb9AsvqXKCRGM8QgKrUbRbJYFXScHvDPpGRd28rYidC0tA==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 || ^7.0.0-0 || ^8.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-singlefile@2.3.3: + resolution: {integrity: sha512-XVnGH0QzbOa8fxRSsHdCarVN1BSBXNi7uLMQYlrGRN5apdHkk62XQWRJhVever0lnfuyBkwn+kvVChdm/OoOUg==} + engines: {node: '>18.0.0'} + peerDependencies: + rollup: ^4.59.0 + vite: ^5.4.21 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + rollup: + optional: true + + vite-plugin-vue-tracer@1.5.0: + resolution: {integrity: sha512-G2aQ676fLBPnYhRi5lsARoL4hbtc/sx6fVzO7p44AB+1xQXo2UuiRgv7K26UdijrNzmuQprmJ121n3rdjBk1CA==} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vue: ^3.5.0 + + vite@7.3.7: + resolution: {integrity: sha512-AHEzTORMbi7/7aXp7w7KZ5+DCUdSeLsJz0grY8xHpc9DHdYb0vQu6DqJfm2tOw3gDExNgPgnJTXxM6syYFHaCA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.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 + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vite@8.3.3: + resolution: {integrity: sha512-cTAldKPImjg6c+gk48U19POPn3GCBzZwpdsN8ZMEEcbpes+6/wvfqUd0C2y3qYY4wsj8PwgFwrZ/1jBPVttMSg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.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 + '@vitejs/devtools': + 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 + + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + + vscode-uri@3.2.0: + resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==} + + vue-bundle-renderer@2.4.0: + resolution: {integrity: sha512-IxHopQZgzTGBiuGERrQrAS7Lr3dCv+qxvgirEgCUFGAD4gYNfiaGYzC1DDojeZmJAmehp9gG8+17PGuVP6Ab2Q==} + + vue-component-meta@3.3.12: + resolution: {integrity: sha512-UT2ax02yye/xT/eiVBaXjuLDS92spt2V6Aj9C3gJpKKBZg/etrDIGCTLG34M4zGN5qWJEkcpnRjDt3wXBoxOjw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vue-component-type-helpers@3.3.12: + resolution: {integrity: sha512-HwCqmgTfLFskQc4P5TRnbduCMyPat2Ezu0elLWOGn0dD/6BKHP15B5bxce6aDi+E4kblPtru8amIBQzu0Di3qQ==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-devtools-stub@0.1.0: + resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} + + vue-docgen-api@4.79.2: + resolution: {integrity: sha512-n9ENAcs+40awPZMsas7STqjkZiVlIjxIKgiJr5rSohDP0/JCrD9VtlzNojafsA1MChm/hz2h3PDtUedx3lbgfA==} + peerDependencies: + vue: '>=2' + + vue-i18n@11.4.13: + resolution: {integrity: sha512-2G7LC9XcdZ0IljFib7lKGHNiBBOTv6HO+2bnBaOiQgDYZ+uUnqSpuED5DbBo1t7su50o/WRGn+ZfDQTGd26xEw==} + engines: {node: '>= 22'} + peerDependencies: + vue: ^3.0.0 + + vue-inbrowser-compiler-independent-utils@4.71.1: + resolution: {integrity: sha512-K3wt3iVmNGaFEOUR4JIThQRWfqokxLfnPslD41FDZB2ajXp789+wCqJyGYlIFsvEQ2P61PInw6/ph5iiqg51gg==} + peerDependencies: + vue: '>=2' + + vue-router@5.3.1: + resolution: {integrity: sha512-GDBZzgmILxA/kFnkFbJjQZdZ2QQbngnIMMuoUcjhZIfH1RGMaPjPwX5ASnV38qamuA9uhO0RDjSBHTDNG2uXyQ==} + peerDependencies: + '@pinia/colada': '>=0.21.2' + '@vue/compiler-sfc': ^3.5.34 || ^4.0.0 + pinia: ^3.0.4 || ^4.0.2 + vite: ^7.3.0 || ^8.0.0 + vue: ^3.5.34 || ^4.0.0 + peerDependenciesMeta: + '@pinia/colada': + optional: true + '@vue/compiler-sfc': + optional: true + pinia: + optional: true + vite: + optional: true + + vue-tsc@3.3.12: + resolution: {integrity: sha512-kbpaz18O9jPVkXVHD1BEjpUXM6WhXSu+62L1sGGr6Wbzd8GbvkBQWjoj3KZ/C0aq2MZllce7UdtWzwCIYsBMGA==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.43: + resolution: {integrity: sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + wheel-gestures@2.3.0: + resolution: {integrity: sha512-6b+PIXuKIy0ibVnF04GoijGKGIDwjlYSK7bCgicuQwPLivfjoLeCCK0bwbjyOdrStDTNPlyGFixIj0d0kZzwiQ==} + engines: {node: '>=18'} + + which-typed-array@1.1.24: + resolution: {integrity: sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + with@7.0.2: + resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} + engines: {node: '>= 10.0.0'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + 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 + + ws@8.22.0: + resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} + 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 + + wsl-utils@1.0.1: + resolution: {integrity: sha512-c16PKLIRxBYpR3jSWsdS7SFp0COm5SOQdiFjY818dYFHJbMGuLBszpF07LBWmOS1uzrHa9VGdynsEgoeKy0oOQ==} + engines: {node: '>=20'} + + xml-naming@0.3.0: + resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} + engines: {node: '>=16.0.0'} + + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} + engines: {node: '>=0.4.0'} + + y-protocols@1.0.7: + resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + yjs: ^13.0.0 + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml-eslint-parser@1.3.2: + resolution: {integrity: sha512-odxVsHAkZYYglR30aPYRY4nUGJnoJ2y1ww2HDvZALo0BDETv9kWbi16J52eHs+PWRNmF4ub6nZqfVOeesOvntg==} + engines: {node: ^14.17.0 || >=16.0.0} + + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yjs@13.6.33: + resolution: {integrity: sha512-q/UYvr1gOk4XII+Cu1CW2dINjYqJJFifTzogEaIARznrvX7uOlHsdTEXcnOBMuIsrCGEEKdNxi74kyMLZlKVfw==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.1: + resolution: {integrity: sha512-mxW3qiSnl+GRxXsaUMzv2Mbada1Y8CDltET9UxejDQe6DBYlSekghl5U5K0ReAikcHDi0G1vKZEmmo/NWAGKLA==} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.6.5: + resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ai-sdk/gateway@4.0.104(zod@4.6.5)': + dependencies: + '@ai-sdk/provider': 4.0.22 + '@ai-sdk/provider-utils': 5.0.54(zod@4.6.5) + '@vercel/oidc': 3.2.0 + zod: 4.6.5 + + '@ai-sdk/mcp@2.0.67(zod@4.6.5)': + dependencies: + '@ai-sdk/provider': 4.0.22 + '@ai-sdk/provider-utils': 5.0.54(zod@4.6.5) + cross-spawn: 7.0.6 + pkce-challenge: 5.0.1 + zod: 4.6.5 + + '@ai-sdk/provider-utils@5.0.54(zod@4.6.5)': + dependencies: + '@ai-sdk/provider': 4.0.22 + '@standard-schema/spec': 1.1.0 + '@workflow/serde': 4.1.0 + eventsource-parser: 3.1.1 + undici: 7.30.0 + zod: 4.6.5 + + '@ai-sdk/provider@4.0.22': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/vue@4.0.128(vue@3.5.43(typescript@5.9.3))(zod@4.6.5)': + dependencies: + '@ai-sdk/provider-utils': 5.0.54(zod@4.6.5) + ai: 7.0.128(zod@4.6.5) + swrv: 1.3.0(vue@3.5.43(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@vue/test-utils' + - zod + + '@alloc/quick-lru@5.3.0': {} + + '@antfu/install-pkg@2.1.0': + dependencies: + package-manager-detector: 1.9.0 + tinyexec: 1.3.1 + + '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': + dependencies: + '@types/json-schema': 7.0.15 + js-yaml: 4.3.2 + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.29.7': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.29.3 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/traverse': 7.29.8 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-member-expression-to-functions@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.29.7': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-plugin-utils@7.29.7': {} + + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/traverse': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + + '@babel/parser@7.29.9': + dependencies: + '@babel/types': 7.29.8 + + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-transform-typescript@7.29.9(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.29.7': {} + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + + '@babel/traverse@7.29.8': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@bomb.sh/tab@0.0.19(cac@6.7.14)(citty@0.2.2)': + optionalDependencies: + cac: 6.7.14 + citty: 0.2.2 + + '@cacheable/memory@2.2.0': + dependencies: + '@cacheable/utils': 2.5.0 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.5.0': + dependencies: + hashery: 1.5.1 + keyv: 5.6.0 + + '@capsizecss/unpack@4.0.1': + dependencies: + fontkitten: 1.0.3 + + '@changesets/apply-release-plan@7.1.1': + dependencies: + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.8.5 + + '@changesets/assemble-release-plan@6.0.10': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.8.5 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.31.1(@types/node@26.6.4)': + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@26.6.4) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.8.5 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.4': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.8.5 + + '@changesets/get-release-plan@4.0.16': + dependencies: + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.3.2 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.2.2 + prettier: 2.8.8 + + '@clack/core@1.5.1': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.8.1': + dependencies: + '@clack/core': 1.5.1 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@cloudflare/kv-asset-handler@0.4.2': {} + + '@colordx/core@5.8.0': {} + + '@comark/vue@0.7.0(shiki@4.5.0)(vue@3.5.43(typescript@5.9.3))': + dependencies: + comark: 0.7.0(shiki@4.5.0) + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + shiki: 4.5.0 + transitivePeerDependencies: + - rangi + + '@dxup/nuxt@0.4.1(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(typescript@5.9.3)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + '@dxup/unimport': 0.1.2 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + chokidar: 5.0.0 + pathe: 2.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@dxup/unimport@0.1.2': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/core@1.11.2': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@eslint-community/eslint-utils@4.10.1(eslint@10.12.0(jiti@2.7.0))': + dependencies: + eslint: 10.12.0(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.6 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.7.0': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.7.3': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + + '@fingerprintjs/botd@2.0.0': {} + + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/utils@0.2.12': {} + + '@floating-ui/vue@1.1.11(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@floating-ui/dom': 1.8.0 + '@floating-ui/utils': 0.2.12 + vue-demi: 0.14.10(vue@3.5.43(typescript@5.9.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@hono/node-server@2.1.3(hono@4.13.13)': + dependencies: + hono: 4.13.13 + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@iconify-json/lucide@1.2.140': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/simple-icons@1.2.99': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/vscode-icons@1.2.85': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/collections@1.0.747': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.7': + dependencies: + '@antfu/install-pkg': 2.1.0 + '@iconify/types': 2.0.0 + import-meta-resolve: 4.2.0 + + '@iconify/vue@5.0.3(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@iconify/types': 2.0.0 + vue: 3.5.43(typescript@5.9.3) + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.4 + optional: true + + '@img/sharp-darwin-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.4 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.5': + dependencies: + '@img/sharp-wasm32': 0.35.5 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + optional: true + + '@img/sharp-linux-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.4 + optional: true + + '@img/sharp-linux-arm@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.4 + optional: true + + '@img/sharp-linux-ppc64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.4 + optional: true + + '@img/sharp-linux-riscv64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.4 + optional: true + + '@img/sharp-linux-s390x@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.4 + optional: true + + '@img/sharp-linux-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + optional: true + + '@img/sharp-wasm32@0.35.5': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.5': + dependencies: + '@img/sharp-wasm32': 0.35.5 + optional: true + + '@img/sharp-win32-arm64@0.35.5': + optional: true + + '@img/sharp-win32-ia32@0.35.5': + optional: true + + '@img/sharp-win32-x64@0.35.5': + optional: true + + '@inquirer/external-editor@1.0.3(@types/node@26.6.4)': + dependencies: + chardet: 2.2.0 + iconv-lite: 0.7.3 + optionalDependencies: + '@types/node': 26.6.4 + + '@internationalized/date@3.12.4': + dependencies: + '@swc/helpers': 0.5.23 + + '@internationalized/number@3.6.8': + dependencies: + '@swc/helpers': 0.5.23 + + '@intlify/bundle-utils@11.2.5(vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3)))': + dependencies: + '@intlify/message-compiler': 11.4.13 + '@intlify/shared': 11.4.13 + acorn: 8.19.0 + esbuild: 0.25.12 + escodegen: 2.1.0 + estree-walker: 2.0.2 + jsonc-eslint-parser: 2.4.2 + source-map-js: 1.2.2 + yaml-eslint-parser: 1.3.2 + optionalDependencies: + vue-i18n: 11.4.13(vue@3.5.43(typescript@5.9.3)) + + '@intlify/core-base@11.4.13': + dependencies: + '@intlify/devtools-types': 11.4.13 + '@intlify/message-compiler': 11.4.13 + '@intlify/shared': 11.4.13 + + '@intlify/core@11.4.13': + dependencies: + '@intlify/core-base': 11.4.13 + '@intlify/shared': 11.4.13 + + '@intlify/devtools-types@11.4.13': + dependencies: + '@intlify/core-base': 11.4.13 + '@intlify/shared': 11.4.13 + + '@intlify/h3@0.7.4': + dependencies: + '@intlify/core': 11.4.13 + '@intlify/utils': 0.13.0 + + '@intlify/message-compiler@11.4.13': + dependencies: + '@intlify/shared': 11.4.13 + source-map-js: 1.2.2 + + '@intlify/shared@11.4.13': {} + + '@intlify/unplugin-vue-i18n@11.2.5(@vue/compiler-dom@3.5.43)(eslint@10.12.0(jiti@2.7.0))(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)) + '@intlify/bundle-utils': 11.2.5(vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3))) + '@intlify/shared': 11.4.13 + '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.4.13)(@vue/compiler-dom@3.5.43)(vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)) + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + '@typescript-eslint/scope-manager': 8.71.1 + '@typescript-eslint/typescript-estree': 8.71.1(typescript@5.9.3) + debug: 4.4.3 + fast-glob: 3.3.3 + pathe: 2.0.3 + picocolors: 1.1.1 + unplugin: 2.3.11 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vue-i18n: 11.4.13(vue@3.5.43(typescript@5.9.3)) + transitivePeerDependencies: + - '@vue/compiler-dom' + - eslint + - rollup + - supports-color + - typescript + + '@intlify/utils@0.13.0': {} + + '@intlify/utils@0.14.1': {} + + '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.4.13)(@vue/compiler-dom@3.5.43)(vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@babel/parser': 7.29.9 + optionalDependencies: + '@intlify/shared': 11.4.13 + '@vue/compiler-dom': 3.5.43 + vue: 3.5.43(typescript@5.9.3) + vue-i18n: 11.4.13(vue@3.5.43(typescript@5.9.3)) + + '@ioredis/commands@1.10.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@keyv/bigmap@1.3.1(keyv@5.6.0)': + dependencies: + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 + + '@keyv/serialize@1.1.1': {} + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.7 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.7 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@mapbox/node-pre-gyp@2.0.3': + dependencies: + consola: 3.4.2 + detect-libc: 2.1.2 + https-proxy-agent: 7.0.6 + node-fetch: 2.7.0 + nopt: 8.1.0 + semver: 7.8.5 + tar: 7.5.22 + transitivePeerDependencies: + - encoding + - supports-color + + '@miyaneee/rollup-plugin-json5@1.2.0(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + json5: 2.2.3 + rollup: 4.64.0 + + '@modelcontextprotocol/sdk@1.32.1(zod@4.6.5)': + dependencies: + '@hono/node-server': 2.1.3(hono@4.13.13) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + express: 5.2.1 + express-rate-limit: 8.7.1(express@5.2.1) + hono: 4.13.13 + jose: 6.2.12 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.6.5 + zod-to-json-schema: 3.25.2(zod@4.6.5) + transitivePeerDependencies: + - supports-color + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + optional: true + + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.4 + optional: true + + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.4 + optional: true + + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.4 + optional: true + + '@noble/hashes@2.4.0': {} + + '@nodable/entities@3.1.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.3 + + '@nuxt/cli@3.37.0(@nuxt/schema@4.4.8)(cac@6.7.14)(magicast@0.5.5)': + dependencies: + '@bomb.sh/tab': 0.0.19(cac@6.7.14)(citty@0.2.2) + '@clack/prompts': 1.8.1 + c12: 3.3.4(magicast@0.5.5) + citty: 0.2.2 + confbox: 0.2.4 + consola: 3.4.2 + debug: 4.4.3 + defu: 6.1.7 + exsolve: 1.1.3 + fuse.js: 7.5.0 + fzf: 0.5.2 + giget: 3.3.1 + jiti: 2.7.0 + listhen: 1.10.1(srvx@0.11.22) + nypm: 0.6.10 + ofetch: 1.5.1 + ohash: 2.0.12 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.3 + scule: 1.3.0 + semver: 7.8.5 + srvx: 0.11.22 + std-env: 4.3.0 + tinyclip: 0.1.15 + tinyexec: 1.3.1 + ufo: 1.6.4 + youch: 4.1.1 + optionalDependencies: + '@nuxt/schema': 4.4.8 + transitivePeerDependencies: + - '@parcel/watcher' + - cac + - commander + - magicast + - supports-color + + '@nuxt/content@3.16.1(@nuxt/schema@4.6.0)(@oxc-project/types@0.152.0)(better-sqlite3@12.11.1)(confbox@0.2.4)(dotenv@17.4.2)(esbuild@0.28.2)(giget@3.3.1)(magic-string@0.30.21)(magicast@0.5.5)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxtjs/mdc': 0.23.2(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@shikijs/langs': 4.5.0 + '@sqlite.org/sqlite-wasm': 3.53.0-build1 + '@standard-schema/spec': 1.1.0 + '@webcontainer/env': 1.1.1 + c12: 3.3.4(magicast@0.5.5) + chokidar: 5.0.0 + consola: 3.4.2 + db0: 0.4.1 + defu: 6.1.7 + destr: 2.0.5 + git-url-parse: 16.1.0 + h3: 1.15.11 + hookable: 5.5.3 + isomorphic-git: 1.43.1 + jiti: 2.7.0 + json-schema-to-typescript-lite: 15.0.0 + mdast-util-to-hast: 13.2.1 + mdast-util-to-string: 4.0.0 + micromark: 4.0.3 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromatch: 4.0.8 + minimark: 0.2.0 + minimatch: 10.2.6 + nuxt-component-meta: 0.18.0(@nuxt/schema@4.6.0)(@oxc-project/types@0.152.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(rolldown@1.2.12) + nypm: 0.6.10 + ohash: 2.0.12 + pathe: 2.0.3 + pkg-types: 2.3.3 + remark-mdc: 3.11.1 + scule: 1.3.0 + shiki: 4.5.0 + slugify: 1.6.9 + socket.io-client: 4.8.4 + std-env: 4.3.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unctx: 3.0.1(magic-string@0.30.21)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + unified: 11.0.5 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + optionalDependencies: + better-sqlite3: 12.11.1 + transitivePeerDependencies: + - '@farmfe/core' + - '@nuxt/schema' + - '@oxc-project/types' + - '@rsbuild/core' + - '@rspack/core' + - bufferutil + - bun-types-no-globals + - confbox + - dotenv + - esbuild + - giget + - magic-string + - magicast + - mlly + - oxc-parser + - rolldown + - rollup + - supports-color + - unloader + - utf-8-validate + - vite + - webpack + + '@nuxt/devalue@2.0.2': {} + + '@nuxt/devtools-kit@3.4.2(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + execa: 8.0.1 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-kit@3.4.2(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + execa: 8.0.1 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-kit@4.0.0-alpha.7(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + tinyexec: 1.3.1 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-kit@4.0.0-alpha.7(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + tinyexec: 1.3.1 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-kit@4.0.0-alpha.7(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + tinyexec: 1.3.1 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@nuxt/devtools-wizard@3.4.2': + dependencies: + '@clack/prompts': 1.8.1 + consola: 3.4.2 + diff: 8.0.4 + execa: 8.0.1 + magicast: 0.5.5 + pathe: 2.0.3 + pkg-types: 2.3.3 + semver: 7.8.5 + + '@nuxt/devtools@3.4.2(@nuxt/schema@4.4.8)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(giget@3.3.1)(ioredis@5.11.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@nuxt/devtools-kit': 3.4.2(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/devtools-wizard': 3.4.2 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@vue/devtools-core': 8.2.1(vue@3.5.43(typescript@5.9.3)) + '@vue/devtools-kit': 8.2.1 + birpc: 4.2.0 + consola: 3.4.2 + destr: 2.0.5 + error-stack-parser-es: 2.0.1 + execa: 8.0.1 + fast-npm-meta: 2.2.0 + get-port-please: 3.2.0 + hookable: 6.1.2 + image-meta: 0.2.2 + is-installed-globally: 1.0.1 + launch-editor: 2.14.2 + local-pkg: 1.2.1 + magicast: 0.5.5 + nypm: 0.6.10 + ohash: 2.0.12 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.3 + semver: 7.8.5 + simple-git: 3.36.0 + sirv: 3.0.2 + structured-clone-es: 2.0.1 + tinyglobby: 0.2.17 + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vite-plugin-inspect: 11.4.1(@nuxt/kit@4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + vite-plugin-vue-tracer: 1.5.0(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + which: 6.0.1 + ws: 8.22.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@nuxt/schema' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - confbox + - db0 + - dotenv + - giget + - idb-keyval + - ioredis + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - supports-color + - unplugin + - uploadthing + - utf-8-validate + - vue + + '@nuxt/fonts@0.14.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(giget@3.3.1)(ioredis@5.11.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@nuxt/devtools-kit': 3.4.2(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + defu: 6.1.7 + fontless: 0.2.1(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + h3: 1.15.11 + magic-regexp: 0.10.0 + ofetch: 1.5.1 + pathe: 2.0.3 + sirv: 3.0.2 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unifont: 0.7.5 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@farmfe/core' + - '@netlify/blobs' + - '@nuxt/schema' + - '@planetscale/database' + - '@rsbuild/core' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bun-types-no-globals + - confbox + - db0 + - dotenv + - esbuild + - giget + - idb-keyval + - ioredis + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - rollup + - unloader + - uploadthing + - vite + - webpack + + '@nuxt/icon@2.5.1(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@iconify/collections': 1.0.747 + '@iconify/types': 2.0.0 + '@iconify/utils': 3.1.7 + '@iconify/vue': 5.0.3(vue@3.5.43(typescript@5.9.3)) + '@nuxt/devtools-kit': 3.4.2(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + local-pkg: 1.2.1 + mlly: 1.8.2 + ohash: 2.0.12 + picomatch: 4.0.7 + std-env: 4.3.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - oxc-parser + - rolldown + - unplugin + - vite + - vue + + '@nuxt/image@2.1.0(@nuxt/schema@4.6.0)(@types/node@26.6.4)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(unstorage@1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1))': + dependencies: + '@noble/hashes': 2.4.0 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + defu: 6.1.7 + h3: 1.15.11 + image-meta: 0.2.2 + knitwork: 1.3.0 + ohash: 2.0.12 + pathe: 2.0.3 + std-env: 4.3.0 + ufo: 1.6.4 + optionalDependencies: + ipx: 4.0.0-beta.1(@types/node@26.6.4)(unstorage@1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1)) + transitivePeerDependencies: + - '@nuxt/schema' + - '@types/node' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - unstorage + + '@nuxt/kit@4.4.8(magicast@0.5.5)': + dependencies: + c12: 3.3.4(magicast@0.5.5) + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.1.2 + exsolve: 1.1.3 + ignore: 7.0.12 + jiti: 2.7.0 + klona: 2.0.6 + mlly: 1.8.2 + ohash: 2.0.12 + pathe: 2.0.3 + pkg-types: 2.3.3 + rc9: 3.1.0 + scule: 1.3.0 + semver: 7.8.5 + tinyglobby: 0.2.17 + ufo: 1.6.4 + unctx: 2.5.0 + untyped: 2.0.0 + transitivePeerDependencies: + - magicast + + '@nuxt/kit@4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.2.2 + exsolve: 1.1.3 + ignore: 7.0.12 + klona: 2.0.6 + microdiff: 1.6.0 + nostics: 1.3.0 + package-manager-detector: 1.9.0 + pathe: 2.0.3 + rc9: 3.1.0 + scule: 1.3.0 + std-env: 4.3.0 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + unctx: 3.0.1(magic-string@0.30.21)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + verkit: 0.5.0 + optionalDependencies: + '@nuxt/schema': 4.4.8 + confbox: 0.2.4 + dotenv: 17.4.2 + giget: 3.3.1 + jiti: 2.7.0 + mlly: 1.8.2 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - magic-string + - unplugin + + '@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.2.2 + exsolve: 1.1.3 + ignore: 7.0.12 + klona: 2.0.6 + microdiff: 1.6.0 + nostics: 1.3.0 + package-manager-detector: 1.9.0 + pathe: 2.0.3 + rc9: 3.1.0 + scule: 1.3.0 + std-env: 4.3.0 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + unctx: 3.0.1(magic-string@0.30.21)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + verkit: 0.5.0 + optionalDependencies: + '@nuxt/schema': 4.6.0 + confbox: 0.2.4 + dotenv: 17.4.2 + giget: 3.3.1 + jiti: 2.7.0 + mlly: 1.8.2 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - magic-string + - unplugin + + '@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.139.0)(rolldown@1.2.12)(unplugin@2.3.11)': + dependencies: + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.2.2 + exsolve: 1.1.3 + ignore: 7.0.12 + klona: 2.0.6 + microdiff: 1.6.0 + nostics: 1.3.0 + package-manager-detector: 1.9.0 + pathe: 2.0.3 + rc9: 3.1.0 + scule: 1.3.0 + std-env: 4.3.0 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + unctx: 3.0.1(magic-string@0.30.21)(oxc-parser@0.139.0)(rolldown@1.2.12)(unplugin@2.3.11) + verkit: 0.5.0 + optionalDependencies: + '@nuxt/schema': 4.6.0 + confbox: 0.2.4 + dotenv: 17.4.2 + giget: 3.3.1 + jiti: 2.7.0 + mlly: 1.8.2 + oxc-parser: 0.139.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - magic-string + - unplugin + + '@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.2.2 + exsolve: 1.1.3 + ignore: 7.0.12 + klona: 2.0.6 + microdiff: 1.6.0 + nostics: 1.3.0 + package-manager-detector: 1.9.0 + pathe: 2.0.3 + rc9: 3.1.0 + scule: 1.3.0 + std-env: 4.3.0 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + unctx: 3.0.1(magic-string@0.30.21)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + verkit: 0.5.0 + optionalDependencies: + '@nuxt/schema': 4.6.0 + confbox: 0.2.4 + dotenv: 17.4.2 + giget: 3.3.1 + jiti: 2.7.0 + mlly: 1.8.2 + oxc-parser: 0.141.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - magic-string + - unplugin + + '@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.2.2 + exsolve: 1.1.3 + ignore: 7.0.12 + klona: 2.0.6 + microdiff: 1.6.0 + nostics: 1.3.0 + package-manager-detector: 1.9.0 + pathe: 2.0.3 + rc9: 3.1.0 + scule: 1.3.0 + std-env: 4.3.0 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + unctx: 3.0.1(magic-string@1.4.3)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + verkit: 0.5.0 + optionalDependencies: + '@nuxt/schema': 4.6.0 + confbox: 0.2.4 + dotenv: 17.4.2 + giget: 3.3.1 + jiti: 2.7.0 + mlly: 1.8.2 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - magic-string + - unplugin + + '@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + errx: 0.2.2 + exsolve: 1.1.3 + ignore: 7.0.12 + klona: 2.0.6 + microdiff: 1.6.0 + nostics: 1.3.0 + package-manager-detector: 1.9.0 + pathe: 2.0.3 + rc9: 3.1.0 + scule: 1.3.0 + std-env: 4.3.0 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + unctx: 3.0.1(magic-string@1.4.3)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + verkit: 0.5.0 + optionalDependencies: + '@nuxt/schema': 4.6.0 + confbox: 0.2.4 + dotenv: 17.4.2 + giget: 3.3.1 + jiti: 2.7.0 + mlly: 1.8.2 + oxc-parser: 0.151.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - magic-string + - unplugin + + '@nuxt/nitro-server@4.4.8(48a86a4ff7055e06671b0a1a877d44c0)': + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/kit': 4.4.8(magicast@0.5.5) + '@unhead/vue': 2.1.17(vue@3.5.43(typescript@5.9.3)) + '@vue/shared': 3.5.43 + consola: 3.4.2 + defu: 6.1.7 + destr: 2.0.5 + devalue: 5.9.4 + errx: 0.1.2 + escape-string-regexp: 5.0.0 + exsolve: 1.1.3 + h3: 1.15.11 + impound: 1.2.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + klona: 2.0.6 + mocked-exports: 0.1.1 + nitropack: 2.13.4(better-sqlite3@12.11.1)(oxc-parser@0.133.0)(rolldown@1.2.12)(srvx@0.11.22)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + nuxt: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + nypm: 0.6.10 + ohash: 2.0.12 + pathe: 2.0.3 + rou3: 0.8.1 + std-env: 4.3.0 + ufo: 1.6.4 + unctx: 2.5.0 + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + vue: 3.5.43(typescript@5.9.3) + vue-bundle-renderer: 2.4.0 + vue-devtools-stub: 0.1.0 + optionalDependencies: + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@libsql/client' + - '@netlify/blobs' + - '@parcel/watcher' + - '@planetscale/database' + - '@rsbuild/core' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bare-abort-controller + - bare-buffer + - better-sqlite3 + - bun-types-no-globals + - db0 + - drizzle-orm + - encoding + - esbuild + - idb-keyval + - ioredis + - magicast + - mysql2 + - oxc-parser + - react-native-b4a + - rolldown + - rollup + - sqlite3 + - srvx + - supports-color + - typescript + - unloader + - uploadthing + - vite + - webpack + - xml2js + + '@nuxt/schema@4.4.8': + dependencies: + '@vue/shared': 3.5.43 + defu: 6.1.7 + pathe: 2.0.3 + pkg-types: 2.3.3 + std-env: 4.3.0 + + '@nuxt/schema@4.6.0': + dependencies: + '@vue/shared': 3.5.43 + defu: 6.1.7 + nostics: 1.3.0 + pathe: 2.0.3 + pkg-types: 2.3.3 + std-env: 4.3.0 + + '@nuxt/telemetry@2.9.1(@nuxt/kit@4.4.8(magicast@0.5.5))': + dependencies: + '@nuxt/kit': 4.4.8(magicast@0.5.5) + citty: 0.2.2 + consola: 3.4.2 + rc9: 3.1.0 + std-env: 4.3.0 + + '@nuxt/ui@4.11.3(52dc97e73ae1b4e2a4688c82dbaae761)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@iconify/vue': 5.0.3(vue@3.5.43(typescript@5.9.3)) + '@nuxt/fonts': 0.14.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(giget@3.3.1)(ioredis@5.11.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/icon': 2.5.1(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxt/schema': 4.6.0 + '@nuxtjs/color-mode': 4.0.1(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@standard-schema/spec': 1.1.0 + '@tailwindcss/postcss': 4.3.3 + '@tailwindcss/vite': 4.3.3(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@tanstack/vue-table': 8.21.3(vue@3.5.43(typescript@5.9.3)) + '@tanstack/vue-virtual': 3.13.39(vue@3.5.43(typescript@5.9.3)) + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/extension-bubble-menu': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-code': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-collaboration': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33) + '@tiptap/extension-drag-handle': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/extension-collaboration@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33))(@tiptap/extension-node-range@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33)) + '@tiptap/extension-drag-handle-vue-3': 3.31.4(@tiptap/extension-drag-handle@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/extension-collaboration@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33))(@tiptap/extension-node-range@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33)))(@tiptap/pm@3.31.4)(@tiptap/vue-3@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)) + '@tiptap/extension-floating-menu': 3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-horizontal-rule': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-image': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-mention': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/suggestion@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-node-range': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-placeholder': 3.31.4(@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/markdown': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + '@tiptap/starter-kit': 3.31.4 + '@tiptap/suggestion': 3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/vue-3': 3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(vue@3.5.43(typescript@5.9.3)) + '@unhead/vue': 3.4.2(@oxc-project/types@0.152.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + '@vueuse/core': 14.4.0(vue@3.5.43(typescript@5.9.3)) + '@vueuse/integrations': 14.4.0(fuse.js@7.5.0)(vue@3.5.43(typescript@5.9.3)) + '@vueuse/shared': 14.4.0(vue@3.5.43(typescript@5.9.3)) + colortranslator: 5.0.0 + consola: 3.4.2 + defu: 6.1.7 + embla-carousel-auto-height: 8.6.0(embla-carousel@8.6.0) + embla-carousel-auto-scroll: 8.6.0(embla-carousel@8.6.0) + embla-carousel-autoplay: 8.6.0(embla-carousel@8.6.0) + embla-carousel-class-names: 8.6.0(embla-carousel@8.6.0) + embla-carousel-fade: 8.6.0(embla-carousel@8.6.0) + embla-carousel-vue: 8.6.0(vue@3.5.43(typescript@5.9.3)) + embla-carousel-wheel-gestures: 8.1.0(embla-carousel@8.6.0) + fuse.js: 7.5.0 + hookable: 6.1.2 + knitwork: 1.3.0 + magic-string: 1.4.3 + mlly: 1.8.2 + motion-v: 2.6.0(@vueuse/core@14.4.0(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)) + ohash: 2.0.12 + pathe: 2.0.3 + reka-ui: 2.10.5(vue@3.5.43(typescript@5.9.3)) + scule: 1.3.0 + tailwind-merge: 3.7.0 + tailwind-variants: 3.3.1(tailwind-merge@3.7.0)(tailwindcss@4.3.3) + tailwindcss: 4.3.3 + tinyglobby: 0.2.17 + typescript: 5.9.3 + ufo: 1.6.4 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-auto-import: 21.1.0(@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))))(@vueuse/core@14.4.0(vue@3.5.43(typescript@5.9.3)))(esbuild@0.28.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-vue-components: 32.1.0(@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))))(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + vaul-vue: 0.4.1(reka-ui@2.10.5(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)) + vue-component-type-helpers: 3.3.12 + optionalDependencies: + '@internationalized/date': 3.12.4 + '@internationalized/number': 3.6.8 + '@nuxt/content': 3.16.1(@nuxt/schema@4.6.0)(@oxc-project/types@0.152.0)(better-sqlite3@12.11.1)(confbox@0.2.4)(dotenv@17.4.2)(esbuild@0.28.2)(giget@3.3.1)(magic-string@0.30.21)(magicast@0.5.5)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + ai: 7.0.128(zod@4.6.5) + vue-router: 5.3.1(@vue/compiler-sfc@3.5.43)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + zod: 4.6.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@farmfe/core' + - '@netlify/blobs' + - '@oxc-project/types' + - '@planetscale/database' + - '@rsbuild/core' + - '@rspack/core' + - '@unhead/cli' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools-kit' + - '@vue/composition-api' + - async-validator + - aws4fetch + - axios + - bun-types-no-globals + - change-case + - confbox + - db0 + - dotenv + - drauu + - embla-carousel + - esbuild + - focus-trap + - giget + - idb-keyval + - ioredis + - jiti + - jwt-decode + - lightningcss + - nprogress + - oxc-parser + - qrcode + - react + - react-dom + - rolldown + - rollup + - sortablejs + - universal-cookie + - unloader + - uploadthing + - vite + - vue + - webpack + + '@nuxt/vite-builder@4.4.8(cd1fd25ac58f65e1d415a14637c7c918)': + dependencies: + '@nuxt/kit': 4.4.8(magicast@0.5.5) + '@rollup/plugin-replace': 6.0.3(rollup@4.64.0) + '@vitejs/plugin-vue': 6.0.9(vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + '@vitejs/plugin-vue-jsx': 5.1.6(vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + autoprefixer: 10.6.1(postcss@8.5.29) + consola: 3.4.2 + cssnano: 8.0.10(postcss@8.5.29) + defu: 6.1.7 + escape-string-regexp: 5.0.0 + exsolve: 1.1.3 + get-port-please: 3.2.0 + jiti: 2.7.0 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.2 + mocked-exports: 0.1.1 + nuxt: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + nypm: 0.6.10 + pathe: 2.0.3 + pkg-types: 2.3.3 + postcss: 8.5.29 + seroval: 1.6.8 + std-env: 4.3.0 + ufo: 1.6.4 + unenv: 2.0.0-rc.24 + vite: 7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1) + vite-node: 5.3.0(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1) + vite-plugin-checker: 0.14.5(eslint@10.12.0(jiti@2.7.0))(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + vue-bundle-renderer: 2.4.0 + optionalDependencies: + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) + rolldown: 1.2.12 + rollup-plugin-visualizer: 7.1.1(rolldown@1.2.12)(rollup@4.64.0) + transitivePeerDependencies: + - '@biomejs/biome' + - '@types/node' + - eslint + - less + - lightningcss + - magicast + - meow + - optionator + - oxlint + - rollup + - sass + - sass-embedded + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - vue-tsc + - yaml + + '@nuxtjs/color-mode@4.0.1(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + exsolve: 1.1.3 + pathe: 2.0.3 + pkg-types: 2.3.3 + semver: 7.8.5 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + '@nuxtjs/i18n@10.6.0(@nuxt/schema@4.6.0)(@vue/compiler-dom@3.5.43)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(jiti@2.7.0)(rolldown@1.2.12)(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@intlify/core': 11.4.13 + '@intlify/h3': 0.7.4 + '@intlify/message-compiler': 11.4.13 + '@intlify/shared': 11.4.13 + '@intlify/unplugin-vue-i18n': 11.2.5(@vue/compiler-dom@3.5.43)(eslint@10.12.0(jiti@2.7.0))(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)) + '@intlify/utils': 0.14.1 + '@miyaneee/rollup-plugin-json5': 1.2.0(rollup@4.64.0) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@rollup/plugin-yaml': 4.1.2(rollup@4.64.0) + '@vue/compiler-sfc': 3.5.43 + confbox: 0.2.4 + defu: 6.1.7 + devalue: 5.9.4 + h3: 1.15.11 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.2 + nuxt-define: 1.0.0 + oxc-parser: 0.141.0 + oxc-transform: 0.141.0 + oxc-walker: 0.7.0(oxc-parser@0.141.0) + pathe: 2.0.3 + ufo: 1.6.4 + unhead: 3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unrouting: 0.2.3 + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + vue-i18n: 11.4.13(vue@3.5.43(typescript@5.9.3)) + vue-router: 5.3.1(@vue/compiler-sfc@3.5.43)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@farmfe/core' + - '@netlify/blobs' + - '@nuxt/schema' + - '@pinia/colada' + - '@planetscale/database' + - '@rsbuild/core' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vue/compiler-dom' + - aws4fetch + - bun-types-no-globals + - db0 + - dotenv + - esbuild + - eslint + - giget + - idb-keyval + - ioredis + - jiti + - petite-vue-i18n + - pinia + - rolldown + - rollup + - supports-color + - typescript + - unloader + - uploadthing + - vite + - vue + - webpack + + '@nuxtjs/mcp-toolkit@0.22.0(@nuxt/schema@4.6.0)(@vue/compiler-sfc@3.5.43)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(h3@1.15.11)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))(zod@4.6.5)': + dependencies: + '@modelcontextprotocol/sdk': 1.32.1(zod@4.6.5) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@vitejs/plugin-vue': 6.0.9(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + h3: 1.15.11 + tinyglobby: 0.2.17 + vite-plugin-singlefile: 2.3.3(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + zod: 4.6.5 + optionalDependencies: + '@vue/compiler-sfc': 3.5.43 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - rollup + - supports-color + - unplugin + + '@nuxtjs/mdc@0.23.2(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@shikijs/core': 4.5.0 + '@shikijs/engine-javascript': 4.5.0 + '@shikijs/langs': 4.5.0 + '@shikijs/themes': 4.5.0 + '@shikijs/transformers': 4.5.0 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@vue/compiler-core': 3.5.43 + consola: 3.4.2 + debug: 4.4.3 + defu: 6.1.7 + destr: 2.0.5 + detab: 3.0.2 + github-slugger: 2.0.0 + hast-util-format: 1.1.0 + hast-util-to-mdast: 10.1.2 + hast-util-to-string: 3.0.1 + mdast-util-to-hast: 13.2.1 + micromark-util-sanitize-uri: 2.0.1 + parse5: 8.0.1 + pathe: 2.0.3 + property-information: 7.2.0 + rehype-external-links: 3.0.0 + rehype-minify-whitespace: 6.0.2 + rehype-raw: 7.0.0 + rehype-remark: 10.0.1 + rehype-slug: 6.0.0 + rehype-sort-attribute-values: 5.0.1 + rehype-sort-attributes: 5.0.1 + remark-emoji: 5.0.2 + remark-gfm: 4.0.1 + remark-mdc: 3.11.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-stringify: 11.0.0 + scule: 1.3.0 + shiki: 4.5.0 + ufo: 1.6.4 + unified: 11.0.5 + unist-builder: 4.0.0 + unist-util-visit: 5.1.0 + unwasm: 0.5.3 + vfile: 6.0.3 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - supports-color + - unplugin + + '@nuxtjs/robots@6.2.4(f3894709c99f9419e33f31d22c529704)': + dependencies: + '@fingerprintjs/botd': 2.0.0 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + defu: 6.1.7 + h3: 1.15.11 + nuxt-site-config: 4.2.3(f3894709c99f9419e33f31d22c529704) + nuxtseo-shared: 5.3.16(b97a8e7b967e68b693fa07cffe2a3a62) + pathe: 2.0.3 + pkg-types: 2.3.3 + ufo: 1.6.4 + optionalDependencies: + zod: 4.6.5 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - nuxt + - oxc-parser + - rolldown + - unplugin + - vite + - vue + + '@nuxtjs/sitemap@8.6.1(0a52acb8d92efb1ee145a4ff7aa49f49)': + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + defu: 6.1.7 + nuxt-site-config: 4.2.3(d8ea7552347a2867d6807977194af270) + nuxtseo-shared: 5.3.16(feeb53ea913f9923d52180f5bfa646b9) + ofetch: 1.5.1 + oxc-parser: 0.141.0 + oxc-walker: 1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.141.0)(rolldown@1.2.12) + pathe: 2.0.3 + pkg-types: 2.3.3 + radix3: 1.1.2 + sitemapd: 0.2.2 + ufo: 1.6.4 + ultrahtml: 1.7.0 + optionalDependencies: + zod: 4.6.5 + transitivePeerDependencies: + - '@nuxt/schema' + - '@oxc-project/types' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - nuxt + - rolldown + - unplugin + - vite + - vue + + '@oxc-minify/binding-android-arm-eabi@0.133.0': + optional: true + + '@oxc-minify/binding-android-arm64@0.133.0': + optional: true + + '@oxc-minify/binding-darwin-arm64@0.133.0': + optional: true + + '@oxc-minify/binding-darwin-x64@0.133.0': + optional: true + + '@oxc-minify/binding-freebsd-x64@0.133.0': + optional: true + + '@oxc-minify/binding-linux-arm-gnueabihf@0.133.0': + optional: true + + '@oxc-minify/binding-linux-arm-musleabihf@0.133.0': + optional: true + + '@oxc-minify/binding-linux-arm64-gnu@0.133.0': + optional: true + + '@oxc-minify/binding-linux-arm64-musl@0.133.0': + optional: true + + '@oxc-minify/binding-linux-ppc64-gnu@0.133.0': + optional: true + + '@oxc-minify/binding-linux-riscv64-gnu@0.133.0': + optional: true + + '@oxc-minify/binding-linux-riscv64-musl@0.133.0': + optional: true + + '@oxc-minify/binding-linux-s390x-gnu@0.133.0': + optional: true + + '@oxc-minify/binding-linux-x64-gnu@0.133.0': + optional: true + + '@oxc-minify/binding-linux-x64-musl@0.133.0': + optional: true + + '@oxc-minify/binding-openharmony-arm64@0.133.0': + optional: true + + '@oxc-minify/binding-wasm32-wasi@0.133.0': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@oxc-minify/binding-win32-arm64-msvc@0.133.0': + optional: true + + '@oxc-minify/binding-win32-ia32-msvc@0.133.0': + optional: true + + '@oxc-minify/binding-win32-x64-msvc@0.133.0': + optional: true + + '@oxc-parser/binding-android-arm-eabi@0.133.0': + optional: true + + '@oxc-parser/binding-android-arm-eabi@0.139.0': + optional: true + + '@oxc-parser/binding-android-arm-eabi@0.141.0': + optional: true + + '@oxc-parser/binding-android-arm-eabi@0.151.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.133.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.139.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.141.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.151.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.133.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.139.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.141.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.151.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.133.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.139.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.141.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.151.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.133.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.139.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.141.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.151.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.139.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.141.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.151.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.139.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.141.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.151.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.139.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.141.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.151.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.139.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.141.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.151.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.139.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.141.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.151.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.139.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.141.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.151.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.133.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.139.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.141.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.151.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.139.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.141.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.151.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.139.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.141.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.151.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.133.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.139.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.141.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.151.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.133.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.139.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.141.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.151.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.133.0': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.139.0': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.141.0': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.133.0': + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.139.0': + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.141.0': + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.151.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.133.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.139.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.141.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.151.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.133.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.139.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.141.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.151.0': + optional: true + + '@oxc-project/types@0.133.0': {} + + '@oxc-project/types@0.139.0': {} + + '@oxc-project/types@0.141.0': {} + + '@oxc-project/types@0.151.0': {} + + '@oxc-project/types@0.152.0': {} + + '@oxc-transform/binding-android-arm-eabi@0.133.0': + optional: true + + '@oxc-transform/binding-android-arm-eabi@0.141.0': + optional: true + + '@oxc-transform/binding-android-arm64@0.133.0': + optional: true + + '@oxc-transform/binding-android-arm64@0.141.0': + optional: true + + '@oxc-transform/binding-darwin-arm64@0.133.0': + optional: true + + '@oxc-transform/binding-darwin-arm64@0.141.0': + optional: true + + '@oxc-transform/binding-darwin-x64@0.133.0': + optional: true + + '@oxc-transform/binding-darwin-x64@0.141.0': + optional: true + + '@oxc-transform/binding-freebsd-x64@0.133.0': + optional: true + + '@oxc-transform/binding-freebsd-x64@0.141.0': + optional: true + + '@oxc-transform/binding-linux-arm-gnueabihf@0.133.0': + optional: true + + '@oxc-transform/binding-linux-arm-gnueabihf@0.141.0': + optional: true + + '@oxc-transform/binding-linux-arm-musleabihf@0.133.0': + optional: true + + '@oxc-transform/binding-linux-arm-musleabihf@0.141.0': + optional: true + + '@oxc-transform/binding-linux-arm64-gnu@0.133.0': + optional: true + + '@oxc-transform/binding-linux-arm64-gnu@0.141.0': + optional: true + + '@oxc-transform/binding-linux-arm64-musl@0.133.0': + optional: true + + '@oxc-transform/binding-linux-arm64-musl@0.141.0': + optional: true + + '@oxc-transform/binding-linux-ppc64-gnu@0.133.0': + optional: true + + '@oxc-transform/binding-linux-ppc64-gnu@0.141.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-gnu@0.133.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-gnu@0.141.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-musl@0.133.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-musl@0.141.0': + optional: true + + '@oxc-transform/binding-linux-s390x-gnu@0.133.0': + optional: true + + '@oxc-transform/binding-linux-s390x-gnu@0.141.0': + optional: true + + '@oxc-transform/binding-linux-x64-gnu@0.133.0': + optional: true + + '@oxc-transform/binding-linux-x64-gnu@0.141.0': + optional: true + + '@oxc-transform/binding-linux-x64-musl@0.133.0': + optional: true + + '@oxc-transform/binding-linux-x64-musl@0.141.0': + optional: true + + '@oxc-transform/binding-openharmony-arm64@0.133.0': + optional: true + + '@oxc-transform/binding-openharmony-arm64@0.141.0': + optional: true + + '@oxc-transform/binding-wasm32-wasi@0.133.0': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@oxc-transform/binding-wasm32-wasi@0.141.0': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + + '@oxc-transform/binding-win32-arm64-msvc@0.133.0': + optional: true + + '@oxc-transform/binding-win32-arm64-msvc@0.141.0': + optional: true + + '@oxc-transform/binding-win32-ia32-msvc@0.133.0': + optional: true + + '@oxc-transform/binding-win32-ia32-msvc@0.141.0': + optional: true + + '@oxc-transform/binding-win32-x64-msvc@0.133.0': + optional: true + + '@oxc-transform/binding-win32-x64-msvc@0.141.0': + optional: true + + '@parcel/watcher-wasm@2.6.0': + dependencies: + is-glob: 4.0.3 + picomatch: 4.0.7 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.29': {} + + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.7.0': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + + '@publint/pack@0.1.7': + dependencies: + tinyexec: 1.3.1 + + '@rolldown/binding-android-arm-eabi@1.2.12': + optional: true + + '@rolldown/binding-android-arm64@1.2.12': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.12': + optional: true + + '@rolldown/binding-darwin-x64@1.2.12': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.12': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.12': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.12': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.12': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.12': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.12': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.12': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@rollup/plugin-alias@6.0.0(rollup@4.64.0)': + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-commonjs@29.0.3(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@4.0.7) + is-reference: 1.2.1 + magic-string: 0.30.21 + picomatch: 4.0.7 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-inject@5.0.5(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + estree-walker: 2.0.2 + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-json@6.1.0(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.12 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-replace@6.0.3(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-terser@1.0.0(rollup@4.64.0)': + dependencies: + serialize-javascript: 7.1.2 + smob: 1.6.2 + terser: 5.51.2 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/plugin-yaml@4.1.2(rollup@4.64.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + js-yaml: 4.3.2 + tosource: 2.0.0-alpha.3 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/pluginutils@5.4.0(rollup@4.64.0)': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.7 + optionalDependencies: + rollup: 4.64.0 + + '@rollup/rollup-android-arm-eabi@4.64.0': + optional: true + + '@rollup/rollup-android-arm64@4.64.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.64.0': + optional: true + + '@rollup/rollup-darwin-x64@4.64.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.64.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.64.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.64.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.64.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.64.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.64.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.64.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.64.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.64.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.64.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.64.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.64.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.64.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.64.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.64.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.64.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.64.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.64.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.64.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.64.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.64.0': + optional: true + + '@shikijs/core@4.5.0': + dependencies: + '@shikijs/primitive': 4.5.0 + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + + '@shikijs/primitive@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/stream@4.5.0(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@shikijs/core': 4.5.0 + optionalDependencies: + vue: 3.5.43(typescript@5.9.3) + + '@shikijs/themes@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + + '@shikijs/transformers@4.5.0': + dependencies: + '@shikijs/core': 4.5.0 + '@shikijs/types': 4.5.0 + + '@shikijs/types@4.5.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@simple-git/args-pathspec@1.0.4': {} + + '@simple-git/argv-parser@1.1.1': + dependencies: + '@simple-git/args-pathspec': 1.0.4 + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@7.2.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@socket.io/component-emitter@3.1.2': {} + + '@speed-highlight/core@1.2.24': {} + + '@sqlite.org/sqlite-wasm@3.53.0-build1': {} + + '@standard-schema/spec@1.1.0': {} + + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.3.3': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.26.0 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.2 + tailwindcss: 4.3.3 + + '@tailwindcss/oxide-android-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide@4.3.3': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/postcss@4.3.3': + dependencies: + '@alloc/quick-lru': 5.3.0 + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + postcss: 8.5.29 + tailwindcss: 4.3.3 + + '@tailwindcss/vite@4.3.3(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + + '@takumi-rs/core-darwin-arm64@2.14.0': + optional: true + + '@takumi-rs/core-darwin-x64@2.14.0': + optional: true + + '@takumi-rs/core-linux-arm64-gnu@2.14.0': + optional: true + + '@takumi-rs/core-linux-arm64-musl@2.14.0': + optional: true + + '@takumi-rs/core-linux-x64-gnu@2.14.0': + optional: true + + '@takumi-rs/core-linux-x64-musl@2.14.0': + optional: true + + '@takumi-rs/core-win32-arm64-msvc@2.14.0': + optional: true + + '@takumi-rs/core-win32-x64-msvc@2.14.0': + optional: true + + '@takumi-rs/core@2.14.0(csstype@3.2.3)': + dependencies: + '@takumi-rs/helpers': 2.14.0 + optionalDependencies: + '@takumi-rs/core-darwin-arm64': 2.14.0 + '@takumi-rs/core-darwin-x64': 2.14.0 + '@takumi-rs/core-linux-arm64-gnu': 2.14.0 + '@takumi-rs/core-linux-arm64-musl': 2.14.0 + '@takumi-rs/core-linux-x64-gnu': 2.14.0 + '@takumi-rs/core-linux-x64-musl': 2.14.0 + '@takumi-rs/core-win32-arm64-msvc': 2.14.0 + '@takumi-rs/core-win32-x64-msvc': 2.14.0 + csstype: 3.2.3 + transitivePeerDependencies: + - preact + - react + + '@takumi-rs/helpers@2.14.0': {} + + '@tanstack/table-core@8.21.3': {} + + '@tanstack/virtual-core@3.17.11': {} + + '@tanstack/vue-table@8.21.3(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@tanstack/table-core': 8.21.3 + vue: 3.5.43(typescript@5.9.3) + + '@tanstack/vue-virtual@3.13.39(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@tanstack/virtual-core': 3.17.11 + vue: 3.5.43(typescript@5.9.3) + + '@tiptap/core@3.31.4(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-blockquote@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-bold@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-bubble-menu@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-bullet-list@3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extension-list': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-code-block@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-code@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-collaboration@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + '@tiptap/y-tiptap': 3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33) + yjs: 13.6.33 + + '@tiptap/extension-document@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-drag-handle-vue-3@3.31.4(@tiptap/extension-drag-handle@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/extension-collaboration@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33))(@tiptap/extension-node-range@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33)))(@tiptap/pm@3.31.4)(@tiptap/vue-3@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@tiptap/extension-drag-handle': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/extension-collaboration@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33))(@tiptap/extension-node-range@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33)) + '@tiptap/pm': 3.31.4 + '@tiptap/vue-3': 3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(vue@3.5.43(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + + '@tiptap/extension-drag-handle@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/extension-collaboration@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33))(@tiptap/extension-node-range@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/extension-collaboration': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33))(yjs@13.6.33) + '@tiptap/extension-node-range': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + '@tiptap/y-tiptap': 3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33) + + '@tiptap/extension-dropcursor@3.31.4(@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extensions': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-floating-menu@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-gapcursor@3.31.4(@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extensions': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-hard-break@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-heading@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-horizontal-rule@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-image@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-italic@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-link@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + linkifyjs: 4.3.3 + + '@tiptap/extension-list-item@3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extension-list': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-list-keymap@3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extension-list': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-mention@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(@tiptap/suggestion@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + '@tiptap/suggestion': 3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-node-range@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/extension-ordered-list@3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extension-list': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-paragraph@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-placeholder@3.31.4(@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/extensions': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/extension-strike@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-text@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extension-underline@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + + '@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/markdown@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + marked: 17.0.6 + + '@tiptap/pm@3.31.4': + dependencies: + prosemirror-changeset: 2.4.4 + prosemirror-commands: 1.7.2 + prosemirror-dropcursor: 1.8.4 + prosemirror-gapcursor: 1.4.1 + prosemirror-history: 1.5.1 + prosemirror-inputrules: 1.5.1 + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.12 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.4 + prosemirror-tables: 1.8.5 + prosemirror-transform: 1.12.2 + prosemirror-view: 1.42.6 + + '@tiptap/starter-kit@3.31.4': + dependencies: + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/extension-blockquote': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-bold': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-bullet-list': 3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-code': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-code-block': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-document': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-dropcursor': 3.31.4(@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-gapcursor': 3.31.4(@tiptap/extensions@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-hard-break': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-heading': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-horizontal-rule': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-italic': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-link': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-list': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-list-item': 3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-list-keymap': 3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-ordered-list': 3.31.4(@tiptap/extension-list@3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)) + '@tiptap/extension-paragraph': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-strike': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-text': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extension-underline': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4)) + '@tiptap/extensions': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/suggestion@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + + '@tiptap/vue-3@3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4)(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@floating-ui/dom': 1.8.0 + '@tiptap/core': 3.31.4(@tiptap/pm@3.31.4) + '@tiptap/pm': 3.31.4 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + '@tiptap/extension-bubble-menu': 3.31.4(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + '@tiptap/extension-floating-menu': 3.31.4(@floating-ui/dom@1.8.0)(@tiptap/core@3.31.4(@tiptap/pm@3.31.4))(@tiptap/pm@3.31.4) + + '@tiptap/y-tiptap@3.0.9(prosemirror-model@1.25.12)(prosemirror-state@1.4.4)(prosemirror-view@1.42.6)(y-protocols@1.0.7(yjs@13.6.33))(yjs@13.6.33)': + dependencies: + lib0: 0.2.119 + prosemirror-model: 1.25.12 + prosemirror-state: 1.4.4 + prosemirror-view: 1.42.6 + y-protocols: 1.0.7(yjs@13.6.33) + yjs: 13.6.33 + + '@tybys/wasm-util@0.10.4': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.9': {} + + '@types/hast@3.0.5': + dependencies: + '@types/unist': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/linkify-it@5.0.0': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + + '@types/ms@2.1.0': {} + + '@types/node@12.20.55': {} + + '@types/node@26.6.4': + dependencies: + undici-types: 8.9.0 + + '@types/parse-path@7.1.0': + dependencies: + parse-path: 7.1.0 + + '@types/resolve@1.20.2': {} + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/web-bluetooth@0.0.20': {} + + '@types/web-bluetooth@0.0.21': {} + + '@typescript-eslint/project-service@8.71.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.71.1(typescript@5.9.3) + '@typescript-eslint/types': 8.71.1 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.71.1': + dependencies: + '@typescript-eslint/types': 8.71.1 + '@typescript-eslint/visitor-keys': 8.71.1 + + '@typescript-eslint/tsconfig-utils@8.71.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/types@8.71.1': {} + + '@typescript-eslint/typescript-estree@8.71.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.71.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.71.1(typescript@5.9.3) + '@typescript-eslint/types': 8.71.1 + '@typescript-eslint/visitor-keys': 8.71.1 + debug: 4.4.3 + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.71.1': + dependencies: + '@typescript-eslint/types': 8.71.1 + eslint-visitor-keys: 5.0.1 + + '@ungap/structured-clone@1.4.0': {} + + '@unhead/bundler@3.4.2(@oxc-project/types@0.152.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(unhead@3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))': + dependencies: + magic-string: 1.4.3 + oxc-walker: 1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.133.0)(rolldown@1.2.12) + unhead: 3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + optionalDependencies: + esbuild: 0.28.2 + lightningcss: 1.33.0 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@oxc-project/types' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - rollup + - unloader + + '@unhead/vue@2.1.17(vue@3.5.43(typescript@5.9.3))': + dependencies: + hookable: 6.1.2 + unhead: 2.1.17 + vue: 3.5.43(typescript@5.9.3) + + '@unhead/vue@3.4.2(@oxc-project/types@0.152.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@unhead/bundler': 3.4.2(@oxc-project/types@0.152.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(unhead@3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + hookable: 6.1.2 + unhead: 3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@oxc-project/types' + - '@rsbuild/core' + - '@rspack/core' + - '@unhead/cli' + - '@vitejs/devtools-kit' + - bun-types-no-globals + - esbuild + - lightningcss + - oxc-parser + - rolldown + - rollup + - unloader + + '@vercel/nft@1.11.0(rollup@4.64.0)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.3 + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + acorn: 8.19.0 + acorn-import-attributes: 1.9.5(acorn@8.19.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 13.0.6 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.7 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vercel/oidc@3.2.0': {} + + '@vitejs/plugin-vue-jsx@5.1.6(vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@babel/core': 7.29.7 + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-typescript': 7.29.9(@babel/core@7.29.7) + '@rolldown/pluginutils': 1.0.1 + '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.7) + vite: 7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1) + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@6.0.9(vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1) + vue: 3.5.43(typescript@5.9.3) + + '@vitejs/plugin-vue@6.0.9(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vue: 3.5.43(typescript@5.9.3) + + '@volar/language-core@2.4.28': + dependencies: + '@volar/source-map': 2.4.28 + + '@volar/source-map@2.4.28': {} + + '@volar/typescript@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + path-browserify: 1.0.1 + vscode-uri: 3.2.0 + + '@vue-macros/common@3.1.4(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@vue/compiler-sfc': 3.5.43 + ast-kit: 2.2.0 + local-pkg: 1.2.1 + magic-string-ast: 1.0.3 + unplugin-utils: 0.3.2 + optionalDependencies: + vue: 3.5.43(typescript@5.9.3) + + '@vue/babel-helper-vue-transform-on@2.0.1': {} + + '@vue/babel-plugin-jsx@2.0.1(@babel/core@7.29.7)': + dependencies: + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + '@vue/babel-helper-vue-transform-on': 2.0.1 + '@vue/babel-plugin-resolve-type': 2.0.1(@babel/core@7.29.7) + '@vue/shared': 3.5.43 + optionalDependencies: + '@babel/core': 7.29.7 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@2.0.1(@babel/core@7.29.7)': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + '@babel/parser': 7.29.9 + '@vue/compiler-sfc': 3.5.43 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.43': + dependencies: + '@babel/parser': 7.29.9 + '@vue/shared': 3.5.43 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.2 + + '@vue/compiler-dom@3.5.43': + dependencies: + '@vue/compiler-core': 3.5.43 + '@vue/shared': 3.5.43 + + '@vue/compiler-sfc@3.5.43': + dependencies: + '@babel/parser': 7.29.9 + '@vue/compiler-core': 3.5.43 + '@vue/compiler-dom': 3.5.43 + '@vue/compiler-ssr': 3.5.43 + '@vue/shared': 3.5.43 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.29 + source-map-js: 1.2.2 + + '@vue/compiler-ssr@3.5.43': + dependencies: + '@vue/compiler-dom': 3.5.43 + '@vue/shared': 3.5.43 + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-api@8.2.1': + dependencies: + '@vue/devtools-kit': 8.2.1 + + '@vue/devtools-core@8.2.1(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@vue/devtools-kit': 8.2.1 + '@vue/devtools-shared': 8.2.1 + vue: 3.5.43(typescript@5.9.3) + + '@vue/devtools-kit@8.2.1': + dependencies: + '@vue/devtools-shared': 8.2.1 + birpc: 2.9.0 + hookable: 5.5.3 + perfect-debounce: 2.1.0 + + '@vue/devtools-shared@8.2.1': {} + + '@vue/language-core@3.3.12': + dependencies: + '@volar/language-core': 2.4.28 + '@vue/compiler-dom': 3.5.43 + '@vue/shared': 3.5.43 + alien-signals: 3.2.1 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.7 + + '@vue/reactivity@3.5.43': + dependencies: + '@vue/shared': 3.5.43 + + '@vue/runtime-core@3.5.43': + dependencies: + '@vue/reactivity': 3.5.43 + '@vue/shared': 3.5.43 + + '@vue/runtime-dom@3.5.43': + dependencies: + '@vue/reactivity': 3.5.43 + '@vue/runtime-core': 3.5.43 + '@vue/shared': 3.5.43 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.43': + dependencies: + '@vue/compiler-ssr': 3.5.43 + '@vue/runtime-dom': 3.5.43 + '@vue/shared': 3.5.43 + + '@vue/shared@3.5.43': {} + + '@vueuse/core@10.11.1(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.11.1 + '@vueuse/shared': 10.11.1(vue@3.5.43(typescript@5.9.3)) + vue-demi: 0.14.10(vue@3.5.43(typescript@5.9.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/core@14.4.0(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.4.0 + '@vueuse/shared': 14.4.0(vue@3.5.43(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + + '@vueuse/core@15.0.0(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 15.0.0 + '@vueuse/shared': 15.0.0(vue@3.5.43(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + + '@vueuse/integrations@14.4.0(fuse.js@7.5.0)(vue@3.5.43(typescript@5.9.3))': + dependencies: + '@vueuse/core': 14.4.0(vue@3.5.43(typescript@5.9.3)) + '@vueuse/shared': 14.4.0(vue@3.5.43(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + fuse.js: 7.5.0 + + '@vueuse/metadata@10.11.1': {} + + '@vueuse/metadata@14.4.0': {} + + '@vueuse/metadata@15.0.0': {} + + '@vueuse/shared@10.11.1(vue@3.5.43(typescript@5.9.3))': + dependencies: + vue-demi: 0.14.10(vue@3.5.43(typescript@5.9.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/shared@14.4.0(vue@3.5.43(typescript@5.9.3))': + dependencies: + vue: 3.5.43(typescript@5.9.3) + + '@vueuse/shared@15.0.0(vue@3.5.43(typescript@5.9.3))': + dependencies: + vue: 3.5.43(typescript@5.9.3) + + '@webcontainer/env@1.1.1': {} + + '@workflow/serde@4.1.0': {} + + abbrev@3.0.1: {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.1.0 + + acorn-import-attributes@1.9.5(acorn@8.19.0): + dependencies: + acorn: 8.19.0 + + acorn-jsx@5.3.2(acorn@8.19.0): + dependencies: + acorn: 8.19.0 + + acorn@7.4.1: {} + + acorn@8.19.0: {} + + agent-base@7.1.4: {} + + ai@7.0.128(zod@4.6.5): + dependencies: + '@ai-sdk/gateway': 4.0.104(zod@4.6.5) + '@ai-sdk/provider': 4.0.22 + '@ai-sdk/provider-utils': 5.0.54(zod@4.6.5) + zod: 4.6.5 + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.8 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + alien-signals@3.2.1: {} + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.4.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + ansis@4.4.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + anynum@1.0.1: {} + + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.18.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.2.2 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + array-union@2.1.0: {} + + asap@2.0.6: {} + + assert-never@1.4.0: {} + + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.29.9 + pathe: 2.0.3 + + ast-types@0.16.3: + dependencies: + tslib: 2.8.1 + + ast-walker-scope@0.9.0: + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + ast-kit: 2.2.0 + + async-lock@1.4.1: {} + + async-sema@3.1.1: {} + + async@3.2.6: {} + + autoprefixer@10.6.1(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + caniuse-lite: 1.0.30001814 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + b4a@1.9.0: {} + + babel-walk@3.0.0-canary-5: + dependencies: + '@babel/types': 7.29.8 + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + bare-events@2.9.2: {} + + bare-fs@4.8.2: + dependencies: + bare-events: 2.9.2 + bare-path: 3.1.2 + bare-stream: 2.13.4(bare-events@2.9.2) + bare-url: 2.5.4 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-path@3.1.2: {} + + bare-stream@2.13.4(bare-events@2.9.2): + dependencies: + b4a: 1.9.0 + streamx: 2.28.1 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.9.2 + transitivePeerDependencies: + - react-native-b4a + + bare-url@2.5.4: + dependencies: + bare-path: 3.1.2 + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.11.27: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + better-sqlite3@12.11.1: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + birpc@2.9.0: {} + + birpc@4.2.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.16.0 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + brace-expansion@2.1.7: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.12: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.29.3: + dependencies: + baseline-browser-mapping: 2.11.27 + caniuse-lite: 1.0.30001814 + electron-to-chromium: 1.5.445 + node-releases: 2.0.57 + update-browserslist-db: 1.3.3(browserslist@4.29.3) + + buffer-crc32@1.0.0: {} + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bundle-name@4.1.1: + dependencies: + run-applescript: 7.1.0 + + bytes@3.1.2: {} + + c12@3.3.4(magicast@0.5.5): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.4.2 + exsolve: 1.1.3 + giget: 3.3.1 + jiti: 2.7.0 + ohash: 2.0.12 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.3 + rc9: 3.1.0 + optionalDependencies: + magicast: 0.5.5 + + cac@6.7.14: {} + + cac@7.0.0: {} + + cacheable@2.5.0: + dependencies: + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.10.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caniuse-api@4.0.0: + dependencies: + browserslist: 4.29.3 + caniuse-lite: 1.0.30001814 + + caniuse-lite@1.0.30001814: {} + + ccount@2.0.1: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-parser@2.2.0: + dependencies: + is-regex: 1.2.1 + + character-reference-invalid@2.0.1: {} + + chardet@2.2.0: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + chownr@1.1.4: {} + + chownr@3.0.0: {} + + chrome-launcher@1.2.2: + dependencies: + '@types/node': 26.6.4 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 2.0.2 + transitivePeerDependencies: + - supports-color + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + citty@0.2.2: {} + + clean-git-ref@2.0.1: {} + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + cluster-key-slot@1.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colortranslator@5.0.0: {} + + comark@0.7.0(shiki@4.5.0): + dependencies: + entities: 8.1.0 + htmlparser2: 12.0.0 + js-yaml: 5.4.3 + markdown-exit: 1.1.0-beta.2 + optionalDependencies: + shiki: 4.5.0 + + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + commander@2.20.3: {} + + commondir@1.0.1: {} + + compare-versions@6.1.1: {} + + compatx@0.2.0: {} + + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + confbox@0.3.1: {} + + consola@3.4.2: {} + + constantinople@4.0.1: + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + content-type@2.1.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.3: {} + + cookie-es@2.0.1: {} + + cookie-es@3.1.1: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + core-util-is@1.0.3: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + + croner@10.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crossws@0.4.14(srvx@0.11.22): + optionalDependencies: + srvx: 0.11.22 + + css-select@6.0.0: + dependencies: + boolbase: 1.0.0 + css-what: 7.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.2 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.2 + + css-what@7.0.0: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@8.0.10(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + cssnano-utils: 6.0.4(postcss@8.5.29) + postcss: 8.5.29 + postcss-calc: 10.1.1(postcss@8.5.29) + postcss-colormin: 8.0.5(postcss@8.5.29) + postcss-convert-values: 8.0.4(postcss@8.5.29) + postcss-discard-comments: 8.0.4(postcss@8.5.29) + postcss-discard-duplicates: 8.0.4(postcss@8.5.29) + postcss-discard-empty: 8.0.5(postcss@8.5.29) + postcss-discard-overridden: 8.0.4(postcss@8.5.29) + postcss-merge-longhand: 8.0.4(postcss@8.5.29) + postcss-merge-rules: 8.0.5(postcss@8.5.29) + postcss-minify-font-values: 8.0.4(postcss@8.5.29) + postcss-minify-gradients: 8.0.6(postcss@8.5.29) + postcss-minify-params: 8.0.4(postcss@8.5.29) + postcss-minify-selectors: 8.0.5(postcss@8.5.29) + postcss-normalize-charset: 8.0.5(postcss@8.5.29) + postcss-normalize-display-values: 8.0.4(postcss@8.5.29) + postcss-normalize-positions: 8.0.4(postcss@8.5.29) + postcss-normalize-repeat-style: 8.0.4(postcss@8.5.29) + postcss-normalize-string: 8.0.4(postcss@8.5.29) + postcss-normalize-timing-functions: 8.0.4(postcss@8.5.29) + postcss-normalize-unicode: 8.0.4(postcss@8.5.29) + postcss-normalize-url: 8.0.4(postcss@8.5.29) + postcss-normalize-whitespace: 8.0.5(postcss@8.5.29) + postcss-ordered-values: 8.0.5(postcss@8.5.29) + postcss-reduce-initial: 8.0.5(postcss@8.5.29) + postcss-reduce-transforms: 8.0.4(postcss@8.5.29) + postcss-svgo: 8.0.6(postcss@8.5.29) + postcss-unique-selectors: 8.0.4(postcss@8.5.29) + + cssnano-utils@6.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + + cssnano@8.0.10(postcss@8.5.29): + dependencies: + cssnano-preset-default: 8.0.10(postcss@8.5.29) + lilconfig: 3.1.3 + postcss: 8.5.29 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.2.3: {} + + db0@0.3.4(better-sqlite3@12.11.1): + optionalDependencies: + better-sqlite3: 12.11.1 + + db0@0.4.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.1: + dependencies: + bundle-name: 4.1.1 + default-browser-id: 5.0.1 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@3.0.0: {} + + defu@6.1.7: {} + + denque@2.1.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + detab@3.0.2: {} + + detect-indent@6.1.0: {} + + detect-libc@2.1.2: {} + + devalue@5.9.4: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff3@0.0.3: {} + + diff@8.0.4: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctypes@1.1.0: {} + + docus@5.14.0(ef3cbfd5a7d4098d77feeb53de29bbf8): + dependencies: + '@ai-sdk/gateway': 4.0.104(zod@4.6.5) + '@ai-sdk/mcp': 2.0.67(zod@4.6.5) + '@ai-sdk/vue': 4.0.128(vue@3.5.43(typescript@5.9.3))(zod@4.6.5) + '@comark/vue': 0.7.0(shiki@4.5.0)(vue@3.5.43(typescript@5.9.3)) + '@iconify-json/lucide': 1.2.140 + '@iconify-json/simple-icons': 1.2.99 + '@iconify-json/vscode-icons': 1.2.85 + '@nuxt/content': 3.16.1(@nuxt/schema@4.6.0)(@oxc-project/types@0.152.0)(better-sqlite3@12.11.1)(confbox@0.2.4)(dotenv@17.4.2)(esbuild@0.28.2)(giget@3.3.1)(magic-string@0.30.21)(magicast@0.5.5)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/image': 2.1.0(@nuxt/schema@4.6.0)(@types/node@26.6.4)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(unstorage@1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxt/ui': 4.11.3(52dc97e73ae1b4e2a4688c82dbaae761) + '@nuxtjs/i18n': 10.6.0(@nuxt/schema@4.6.0)(@vue/compiler-dom@3.5.43)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(jiti@2.7.0)(rolldown@1.2.12)(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + '@nuxtjs/mcp-toolkit': 0.22.0(@nuxt/schema@4.6.0)(@vue/compiler-sfc@3.5.43)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(h3@1.15.11)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))(zod@4.6.5) + '@nuxtjs/mdc': 0.23.2(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxtjs/robots': 6.2.4(f3894709c99f9419e33f31d22c529704) + '@nuxtjs/sitemap': 8.6.1(0a52acb8d92efb1ee145a4ff7aa49f49) + '@shikijs/core': 4.5.0 + '@shikijs/engine-javascript': 4.5.0 + '@shikijs/langs': 4.5.0 + '@shikijs/stream': 4.5.0(vue@3.5.43(typescript@5.9.3)) + '@shikijs/themes': 4.5.0 + '@takumi-rs/core': 2.14.0(csstype@3.2.3) + '@vueuse/core': 15.0.0(vue@3.5.43(typescript@5.9.3)) + ai: 7.0.128(zod@4.6.5) + better-sqlite3: 12.11.1 + defu: 6.1.7 + exsolve: 1.1.3 + git-url-parse: 16.1.0 + h3: 1.15.11 + motion-v: 2.6.0(@vueuse/core@15.0.0(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)) + nuxt: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + nuxt-agent-discovery: 0.7.0(f03f9a34309c736a5b8a3eab6e0e231a) + nuxt-llms: 0.2.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + nuxt-og-image: 6.9.1(4d4ae61e1e311321182181cefb0fa99a) + nuxt-schema-org: 6.4.3(c9675c078509484a16a69afafcee58d4) + pathe: 2.0.3 + pkg-types: 2.3.3 + scule: 1.3.0 + tailwindcss: 4.3.3 + ufo: 1.6.4 + zod: 4.6.5 + zod-to-json-schema: 3.25.2(zod@4.6.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@cfworker/json-schema' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@inertiajs/vue3' + - '@internationalized/date' + - '@internationalized/number' + - '@libsql/client' + - '@netlify/blobs' + - '@nuxt/schema' + - '@oxc-project/types' + - '@pinia/colada' + - '@planetscale/database' + - '@resvg/resvg-js' + - '@resvg/resvg-wasm' + - '@rsbuild/core' + - '@rspack/core' + - '@takumi-rs/wasm' + - '@tiptap/core' + - '@tiptap/extension-bubble-menu' + - '@tiptap/extension-code' + - '@tiptap/extension-collaboration' + - '@tiptap/extension-drag-handle' + - '@tiptap/extension-drag-handle-vue-3' + - '@tiptap/extension-floating-menu' + - '@tiptap/extension-horizontal-rule' + - '@tiptap/extension-image' + - '@tiptap/extension-mention' + - '@tiptap/extension-node-range' + - '@tiptap/extension-placeholder' + - '@tiptap/markdown' + - '@tiptap/pm' + - '@tiptap/starter-kit' + - '@tiptap/suggestion' + - '@tiptap/vue-3' + - '@types/node' + - '@unhead/cli' + - '@unhead/vue' + - '@unocss/config' + - '@unocss/core' + - '@upstash/redis' + - '@valibot/to-json-schema' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools-kit' + - '@vue/compiler-dom' + - '@vue/compiler-sfc' + - '@vue/composition-api' + - '@vue/test-utils' + - agents + - async-validator + - aws4fetch + - axios + - beautiful-mermaid + - bufferutil + - bun-types-no-globals + - change-case + - comark + - confbox + - csstype + - db0 + - dotenv + - drauu + - embla-carousel + - esbuild + - eslint + - focus-trap + - fontless + - giget + - idb-keyval + - ioredis + - jiti + - joi + - jwt-decode + - katex + - lightningcss + - magic-string + - magicast + - mlly + - nitropack + - nprogress + - oxc-parser + - petite-vue-i18n + - pinia + - playwright-core + - preact + - qrcode + - rangi + - react + - react-dom + - rolldown + - rollup + - satori + - secure-exec + - sharp + - shiki + - solid-js + - sortablejs + - sqlite3 + - superstruct + - supports-color + - svelte + - typescript + - unhead + - unifont + - universal-cookie + - unloader + - unplugin + - unstorage + - uploadthing + - utf-8-validate + - valibot + - vite + - vue + - vue-router + - webpack + - yup + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + dom-serializer@3.1.1: + dependencies: + domelementtype: 3.0.0 + domhandler: 6.0.1 + entities: 8.1.0 + + domelementtype@2.3.0: {} + + domelementtype@3.0.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domhandler@6.0.1: + dependencies: + domelementtype: 3.0.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + domutils@4.0.2: + dependencies: + dom-serializer: 3.1.1 + domelementtype: 3.0.0 + domhandler: 6.0.1 + + dot-prop@10.2.0: + dependencies: + type-fest: 5.10.0 + + dotenv@17.4.2: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.445: {} + + embla-carousel-auto-height@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-auto-scroll@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-autoplay@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-class-names@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-fade@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-vue@8.6.0(vue@3.5.43(typescript@5.9.3)): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + vue: 3.5.43(typescript@5.9.3) + + embla-carousel-wheel-gestures@8.1.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + wheel-gestures: 2.3.0 + + embla-carousel@8.6.0: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojilib@2.4.0: {} + + emoticon@4.1.0: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + engine.io-client@6.6.7: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3 + engine.io-parser: 5.2.3 + ws: 8.21.3 + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.3: {} + + enhanced-resolve@5.26.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + entities@6.0.1: {} + + entities@7.0.1: {} + + entities@8.1.0: {} + + error-stack-parser-es@1.0.5: {} + + error-stack-parser-es@2.0.1: {} + + errx@0.1.2: {} + + errx@0.2.2: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.3.2: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.12.0(jiti@2.7.0): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.7.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.3 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 11.1.5 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.6 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + esm-resolve@1.0.11: {} + + espree@11.2.0: + dependencies: + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) + eslint-visitor-keys: 5.0.1 + + espree@9.6.1: + dependencies: + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.9.2 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: {} + + eventsource-parser@3.1.1: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.1.1 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + expand-template@2.0.3: {} + + express-rate-limit@8.7.1(express@5.2.1): + dependencies: + debug: 4.4.3 + express: 5.2.1 + ip-address: 10.7.3 + transitivePeerDependencies: + - supports-color + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.0 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + exsolve@1.1.3: {} + + extend@3.0.2: {} + + extendable-error@0.1.7: {} + + fast-deep-equal@3.1.3: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-npm-meta@2.2.0: + dependencies: + cac: 7.0.0 + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-uri@3.1.8: {} + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + + fast-xml-builder@1.3.1: + dependencies: + path-expression-matcher: 1.6.2 + xml-naming: 0.3.0 + + fast-xml-parser@5.11.2: + dependencies: + '@nodable/entities': 3.1.0 + fast-xml-builder: 1.3.1 + is-unsafe: 2.0.2 + path-expression-matcher: 1.6.2 + strnum: 2.4.2 + xml-naming: 0.3.0 + + fastq@1.20.3: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + file-entry-cache@11.1.5: + dependencies: + flat-cache: 6.1.23 + + file-uri-to-path@1.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@6.1.23: + dependencies: + cacheable: 2.5.0 + flatted: 3.4.4 + hookified: 1.15.1 + + flat@6.0.1: {} + + flatted@3.4.4: {} + + fnv1a-64@0.1.2: {} + + fontaine@0.8.0: + dependencies: + '@capsizecss/unpack': 4.0.1 + css-tree: 3.2.1 + magic-regexp: 0.10.0 + magic-string: 0.30.21 + pathe: 2.0.3 + ufo: 1.6.4 + unplugin: 2.3.11 + + fontkitten@1.0.3: + dependencies: + tiny-inflate: 1.0.3 + + fontless@0.2.1(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + consola: 3.4.2 + css-tree: 3.2.1 + defu: 6.1.7 + esbuild: 0.27.7 + fontaine: 0.8.0 + jiti: 2.7.0 + lightningcss: 1.33.0 + magic-string: 0.30.21 + ohash: 2.0.12 + pathe: 2.0.3 + ufo: 1.6.4 + unifont: 0.7.5 + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + optionalDependencies: + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - uploadthing + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + forwarded@0.2.0: {} + + fraction.js@5.3.4: {} + + framer-motion@14.0.0: + dependencies: + motion-dom: 14.0.0 + motion-utils: 14.0.0 + tslib: 2.8.1 + + fresh@2.0.0: {} + + fs-constants@1.0.0: {} + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + fuse.js@7.5.0: {} + + fzf@0.5.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.7.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-port-please@3.2.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + get-stream@8.0.1: {} + + giget@3.3.1: {} + + git-up@8.1.1: + dependencies: + is-ssh: 1.4.1 + parse-url: 9.2.0 + + git-url-parse@16.1.0: + dependencies: + git-up: 8.1.1 + + github-from-package@0.0.0: {} + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@13.0.6: + dependencies: + minimatch: 10.2.6 + minipass: 7.1.3 + path-scurry: 2.0.2 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@16.2.4: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.12 + is-path-inside: 4.0.0 + micromatch: 4.0.8 + slash: 5.1.0 + unicorn-magic: 0.4.1 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + gzip-size@7.0.0: + dependencies: + duplexer: 0.1.2 + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.5 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hash-sum@2.0.0: {} + + hashery@1.5.1: + dependencies: + hookified: 1.15.1 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hast-util-embedded@3.0.0: + dependencies: + '@types/hast': 3.0.5 + hast-util-is-element: 3.0.0 + + hast-util-format@1.1.0: + dependencies: + '@types/hast': 3.0.5 + hast-util-embedded: 3.0.0 + hast-util-minify-whitespace: 1.0.1 + hast-util-phrasing: 3.0.1 + hast-util-whitespace: 3.0.0 + html-whitespace-sensitive-tag-names: 3.0.1 + unist-util-visit-parents: 6.0.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.2.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.5 + + hast-util-heading-rank@3.0.0: + dependencies: + '@types/hast': 3.0.5 + + hast-util-is-body-ok-link@3.0.1: + dependencies: + '@types/hast': 3.0.5 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.5 + + hast-util-minify-whitespace@1.0.1: + dependencies: + '@types/hast': 3.0.5 + hast-util-embedded: 3.0.0 + hast-util-is-element: 3.0.0 + hast-util-whitespace: 3.0.0 + unist-util-is: 6.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.5 + + hast-util-phrasing@3.0.1: + dependencies: + '@types/hast': 3.0.5 + hast-util-embedded: 3.0.0 + hast-util-has-property: 3.0.0 + hast-util-is-body-ok-link: 3.0.1 + hast-util-is-element: 3.0.0 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.4.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-mdast@10.1.2: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.4.0 + hast-util-phrasing: 3.0.1 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hast-util-whitespace: 3.0.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-hast: 13.2.1 + mdast-util-to-string: 4.0.0 + rehype-minify-whitespace: 6.0.2 + trim-trailing-lines: 2.1.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.5 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.5 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.5 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.5 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + + hey-listen@1.0.8: {} + + hono@4.13.13: {} + + hookable@5.5.3: {} + + hookable@6.1.2: {} + + hookified@1.15.1: {} + + hookified@2.2.0: {} + + html-void-elements@3.0.0: {} + + html-whitespace-sensitive-tag-names@3.0.1: {} + + htmlparser2@12.0.0: + dependencies: + domelementtype: 3.0.0 + domhandler: 6.0.1 + domutils: 4.0.2 + entities: 8.1.0 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-shutdown@1.2.2: {} + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + httpxy@0.5.5: {} + + human-id@4.2.2: {} + + human-signals@5.0.0: {} + + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.12: {} + + image-meta@0.2.2: {} + + import-meta-resolve@4.2.0: {} + + impound@1.2.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + es-module-lexer: 2.3.2 + pathe: 2.0.3 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-utils: 0.3.2 + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - vite + - webpack + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + ioredis@5.11.1: + dependencies: + '@ioredis/commands': 1.10.0 + cluster-key-slot: 1.1.1 + debug: 4.4.3 + denque: 2.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + + ip-address@10.7.3: {} + + ipaddr.js@1.9.1: {} + + ipx@4.0.0-beta.1(@types/node@26.6.4)(unstorage@1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1)): + dependencies: + sharp: 0.35.5(@types/node@26.6.4) + srvx: 0.12.8 + optionalDependencies: + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + transitivePeerDependencies: + - '@types/node' + optional: true + + iron-webcrypto@1.2.1: {} + + is-absolute-url@4.0.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-callable@1.2.7: {} + + is-core-module@2.17.0: + dependencies: + hasown: 2.0.4 + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-expression@4.0.0: + dependencies: + acorn: 7.4.1 + object-assign: 4.1.1 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@1.0.1: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-module@1.0.0: {} + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + is-plain-obj@4.1.0: {} + + is-promise@2.2.2: {} + + is-promise@4.0.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.9 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + is-ssh@1.4.1: + dependencies: + protocols: 2.0.2 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.24 + + is-unsafe@2.0.2: {} + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isexe@4.0.0: {} + + isomorphic-git@1.43.1: + dependencies: + async-lock: 1.4.1 + clean-git-ref: 2.0.1 + crc-32: 1.2.2 + diff3: 0.0.3 + ignore: 5.3.2 + minimisted: 2.0.1 + pako: 1.0.11 + pify: 4.0.1 + readable-stream: 4.7.0 + sha.js: 2.4.12 + simple-get: 4.0.1 + + isomorphic.js@0.2.5: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@2.7.0: {} + + jose@6.2.12: {} + + js-stringify@1.0.2: {} + + js-tokens@10.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.15.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.3.2: + dependencies: + argparse: 2.0.1 + + js-yaml@5.4.3: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-schema-to-typescript-lite@15.0.0: + dependencies: + '@apidevtools/json-schema-ref-parser': 14.2.1(@types/json-schema@7.0.15) + '@types/json-schema': 7.0.15 + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json-schema@0.4.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonc-eslint-parser@2.4.2: + dependencies: + acorn: 8.19.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.8.5 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jstransformer@1.0.0: + dependencies: + is-promise: 2.2.2 + promise: 7.3.1 + + keyv@5.6.0: + dependencies: + '@keyv/serialize': 1.1.1 + + kleur@4.1.5: {} + + klona@2.0.6: {} + + knitwork@1.3.0: {} + + kolorist@1.8.0: {} + + launch-editor@2.14.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.12.0 + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lib0@0.2.119: + dependencies: + isomorphic.js: 0.2.5 + + lighthouse-logger@2.0.2: + dependencies: + debug: 4.4.3 + marky: 1.3.0 + transitivePeerDependencies: + - supports-color + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + lilconfig@3.1.3: {} + + linkify-it@5.0.2: + dependencies: + uc.micro: 2.1.0 + + linkifyjs@4.3.3: {} + + listhen@1.10.1(srvx@0.11.22): + dependencies: + '@parcel/watcher-wasm': 2.6.0 + citty: 0.2.2 + consola: 3.4.2 + crossws: 0.4.14(srvx@0.11.22) + defu: 6.1.7 + get-port-please: 3.2.0 + h3: 1.15.11 + http-shutdown: 1.2.2 + jiti: 2.7.0 + node-forge: 1.4.0 + pathe: 2.0.3 + std-env: 4.3.0 + tinyclip: 0.1.15 + ufo: 1.6.4 + untun: 0.2.2 + uqr: 0.1.3 + transitivePeerDependencies: + - srvx + + local-pkg@1.2.1: + dependencies: + mlly: 1.8.2 + pkg-types: 2.3.3 + quansync: 0.2.11 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.startcase@4.4.0: {} + + lodash@4.18.1: {} + + longest-streak@3.1.0: {} + + lru-cache@10.4.3: {} + + lru-cache@11.5.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@8.0.5: {} + + magic-regexp@0.10.0: + dependencies: + estree-walker: 3.0.3 + magic-string: 0.30.21 + mlly: 1.8.2 + regexp-tree: 0.1.27 + type-level-regexp: 0.1.17 + ufo: 1.6.4 + unplugin: 2.3.11 + + magic-string-ast@1.0.3: + dependencies: + magic-string: 0.30.21 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + magic-string@1.4.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + magicast@0.5.5: + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + source-map-js: 1.2.2 + + markdown-exit@1.1.0-beta.2: + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + entities: 7.0.1 + linkify-it: 5.0.2 + mdurl: 2.1.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdown-table@3.0.4: {} + + marked@17.0.6: {} + + marky@1.3.0: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.3: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.3 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.3 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.1.0 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.1 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.4.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.2.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-character: 2.1.1 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.27.1: {} + + mdurl@2.1.0: {} + + media-typer@1.1.1: {} + + merge-descriptors@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + microdiff@1.6.0: {} + + micromark-core-commonmark@2.0.4: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.1.0 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-edit-map: 1.0.0 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-table@2.1.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.3 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.2 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-space@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.3 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-edit-map@1.0.0: + dependencies: + micromark-util-types: 2.0.3 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.3 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.3: {} + + micromark@4.0.3: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-edit-map: 1.0.0 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@4.1.0: {} + + mimic-fn@4.0.0: {} + + mimic-response@3.1.0: {} + + minimark@0.2.0: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.7 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.7 + + minimist@1.2.8: {} + + minimisted@2.0.1: + dependencies: + minimist: 1.2.8 + + minipass@7.1.3: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + + mkdirp-classic@0.5.3: {} + + mlly@1.8.2: + dependencies: + acorn: 8.19.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + + mocked-exports@0.1.1: {} + + motion-dom@14.0.0: + dependencies: + motion-utils: 14.0.0 + + motion-utils@14.0.0: {} + + motion-v@2.6.0(@vueuse/core@14.4.0(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@vueuse/core': 14.4.0(vue@3.5.43(typescript@5.9.3)) + framer-motion: 14.0.0 + hey-listen: 1.0.8 + motion-dom: 14.0.0 + motion-utils: 14.0.0 + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - react + - react-dom + + motion-v@2.6.0(@vueuse/core@15.0.0(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@vueuse/core': 15.0.0(vue@3.5.43(typescript@5.9.3)) + framer-motion: 14.0.0 + hey-listen: 1.0.8 + motion-dom: 14.0.0 + motion-utils: 14.0.0 + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - react + - react-dom + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.20: {} + + nanotar@0.3.0: {} + + napi-build-utils@2.0.0: {} + + natural-compare@1.4.0: {} + + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 + + nitropack@2.13.4(better-sqlite3@12.11.1)(oxc-parser@0.133.0)(rolldown@1.2.12)(srvx@0.11.22)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.2 + '@rollup/plugin-alias': 6.0.0(rollup@4.64.0) + '@rollup/plugin-commonjs': 29.0.3(rollup@4.64.0) + '@rollup/plugin-inject': 5.0.5(rollup@4.64.0) + '@rollup/plugin-json': 6.1.0(rollup@4.64.0) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.64.0) + '@rollup/plugin-replace': 6.0.3(rollup@4.64.0) + '@rollup/plugin-terser': 1.0.0(rollup@4.64.0) + '@vercel/nft': 1.11.0(rollup@4.64.0) + archiver: 7.0.1 + c12: 3.3.4(magicast@0.5.5) + chokidar: 5.0.0 + citty: 0.2.2 + compatx: 0.2.0 + confbox: 0.2.4 + consola: 3.4.2 + cookie-es: 2.0.1 + croner: 10.0.1 + crossws: 0.3.5 + db0: 0.3.4(better-sqlite3@12.11.1) + defu: 6.1.7 + destr: 2.0.5 + dot-prop: 10.2.0 + esbuild: 0.28.2 + escape-string-regexp: 5.0.0 + etag: 1.8.1 + exsolve: 1.1.3 + globby: 16.2.4 + gzip-size: 7.0.0 + h3: 1.15.11 + hookable: 5.5.3 + httpxy: 0.5.5 + ioredis: 5.11.1 + jiti: 2.7.0 + klona: 2.0.6 + knitwork: 1.3.0 + listhen: 1.10.1(srvx@0.11.22) + magic-string: 0.30.21 + magicast: 0.5.5 + mime: 4.1.0 + mlly: 1.8.2 + node-fetch-native: 1.6.7 + node-mock-http: 1.0.5 + ofetch: 1.5.1 + ohash: 2.0.12 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.3 + pretty-bytes: 7.2.0 + radix3: 1.1.2 + rollup: 4.64.0 + rollup-plugin-visualizer: 7.1.1(rolldown@1.2.12)(rollup@4.64.0) + scule: 1.3.0 + semver: 7.8.5 + serve-placeholder: 2.0.2 + serve-static: 2.2.1 + source-map: 0.7.6 + std-env: 4.3.0 + ufo: 1.6.4 + ultrahtml: 1.7.0 + uncrypto: 0.1.3 + unctx: 2.5.0 + unenv: 2.0.0-rc.24 + unimport: 6.5.0(esbuild@0.28.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-utils: 0.3.2 + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + untyped: 2.0.0 + unwasm: 0.5.3 + youch: 4.1.1 + youch-core: 0.3.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@libsql/client' + - '@netlify/blobs' + - '@parcel/watcher' + - '@planetscale/database' + - '@rsbuild/core' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bare-abort-controller + - bare-buffer + - better-sqlite3 + - bun-types-no-globals + - drizzle-orm + - encoding + - idb-keyval + - mysql2 + - oxc-parser + - react-native-b4a + - rolldown + - sqlite3 + - srvx + - supports-color + - unloader + - uploadthing + - vite + - webpack + + node-abi@3.97.0: + dependencies: + semver: 7.8.5 + + node-emoji@2.2.0: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-fetch-native@1.6.7: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-forge@1.4.0: {} + + node-gyp-build@4.8.4: {} + + node-mock-http@1.0.5: {} + + node-releases@2.0.57: {} + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + normalize-path@3.0.0: {} + + nostics@1.3.0: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nuxt-agent-discovery@0.7.0(f03f9a34309c736a5b8a3eab6e0e231a): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + defu: 6.1.7 + pathe: 2.0.3 + ufo: 1.6.4 + yaml: 2.9.1 + optionalDependencies: + '@nuxt/content': 3.16.1(@nuxt/schema@4.6.0)(@oxc-project/types@0.152.0)(better-sqlite3@12.11.1)(confbox@0.2.4)(dotenv@17.4.2)(esbuild@0.28.2)(giget@3.3.1)(magic-string@0.30.21)(magicast@0.5.5)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxtjs/mcp-toolkit': 0.22.0(@nuxt/schema@4.6.0)(@vue/compiler-sfc@3.5.43)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(h3@1.15.11)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3))(zod@4.6.5) + '@nuxtjs/robots': 6.2.4(f3894709c99f9419e33f31d22c529704) + '@nuxtjs/sitemap': 8.6.1(0a52acb8d92efb1ee145a4ff7aa49f49) + nuxt-llms: 0.2.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + nuxt-component-meta@0.18.0(@nuxt/schema@4.6.0)(@oxc-project/types@0.152.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(rolldown@1.2.12): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.139.0)(rolldown@1.2.12)(unplugin@2.3.11) + citty: 0.2.2 + defu: 6.1.7 + jiti: 2.7.0 + magic-string: 0.30.21 + mlly: 1.8.2 + ohash: 2.0.12 + oxc-parser: 0.139.0 + oxc-walker: 1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.139.0)(rolldown@1.2.12) + pathe: 2.0.3 + scule: 1.3.0 + typescript: 5.9.3 + ufo: 1.6.4 + unplugin: 2.3.11 + vue-component-meta: 3.3.12(typescript@5.9.3) + transitivePeerDependencies: + - '@nuxt/schema' + - '@oxc-project/types' + - confbox + - dotenv + - giget + - rolldown + + nuxt-define@1.0.0: {} + + nuxt-llms@0.2.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + + nuxt-og-image@6.9.1(4d4ae61e1e311321182181cefb0fa99a): + dependencies: + '@clack/prompts': 1.8.1 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@unhead/vue': 3.4.2(@oxc-project/types@0.152.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + '@vue/compiler-sfc': 3.5.43 + chrome-launcher: 1.2.2 + consola: 3.4.2 + defu: 6.1.7 + devalue: 5.9.4 + exsolve: 1.1.3 + fnv1a-64: 0.1.2 + lightningcss: 1.33.0 + magic-string: 1.4.3 + magicast: 0.5.5 + mocked-exports: 0.1.1 + nuxt-site-config: 4.2.3(e9b125e2f704f4152b5a916a131eaee1) + nuxtseo-shared: 5.3.16(c53d4cf534757bd847435dfb73d28953) + nypm: 0.6.10 + object-identity: 0.2.3 + ofetch: 1.5.1 + ohash: 2.0.12 + oxc-parser: 0.151.0 + oxc-walker: 1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.151.0)(rolldown@1.2.12) + pathe: 2.0.3 + pkg-types: 2.3.3 + radix3: 1.1.2 + std-env: 4.3.0 + strip-literal: 4.0.0 + tinyexec: 1.3.1 + ufo: 1.6.4 + ultrahtml: 1.7.0 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unstorage: 1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1) + optionalDependencies: + '@takumi-rs/core': 2.14.0(csstype@3.2.3) + fontless: 0.2.1(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + nitropack: 2.13.4(better-sqlite3@12.11.1)(oxc-parser@0.133.0)(rolldown@1.2.12)(srvx@0.11.22)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + sharp: 0.35.5(@types/node@26.6.4) + tailwindcss: 4.3.3 + unifont: 0.7.5 + zod: 4.6.5 + transitivePeerDependencies: + - '@farmfe/core' + - '@nuxt/schema' + - '@oxc-project/types' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - confbox + - dotenv + - esbuild + - giget + - jiti + - mlly + - nuxt + - rolldown + - rollup + - supports-color + - unloader + - vite + - vue + - webpack + + nuxt-schema-org@6.4.3(c9675c078509484a16a69afafcee58d4): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + defu: 6.1.7 + nuxt-site-config: 4.2.3(f3894709c99f9419e33f31d22c529704) + nuxtseo-shared: 5.3.16(b97a8e7b967e68b693fa07cffe2a3a62) + pkg-types: 2.3.3 + ufo: 1.6.4 + optionalDependencies: + '@unhead/vue': 3.4.2(@oxc-project/types@0.152.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + unhead: 3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + zod: 4.6.5 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - nuxt + - oxc-parser + - rolldown + - unplugin + - vite + - vue + + nuxt-site-config-kit@4.2.3(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + site-config-stack: 4.2.3(vue@3.5.43(typescript@5.9.3)) + std-env: 4.3.0 + ufo: 1.6.4 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - vue + + nuxt-site-config-kit@4.2.3(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + site-config-stack: 4.2.3(vue@3.5.43(typescript@5.9.3)) + std-env: 4.3.0 + ufo: 1.6.4 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - vue + + nuxt-site-config-kit@4.2.3(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + site-config-stack: 4.2.3(vue@3.5.43(typescript@5.9.3)) + std-env: 4.3.0 + ufo: 1.6.4 + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - vue + + nuxt-site-config@4.2.3(d8ea7552347a2867d6807977194af270): + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + defu: 6.1.7 + h3: 1.15.11 + nuxt-site-config-kit: 4.2.3(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vue@3.5.43(typescript@5.9.3)) + nuxtseo-shared: 5.3.16(feeb53ea913f9923d52180f5bfa646b9) + pathe: 2.0.3 + pkg-types: 2.3.3 + site-config-stack: 4.2.3(vue@3.5.43(typescript@5.9.3)) + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - nuxt + - oxc-parser + - rolldown + - unplugin + - vite + - zod + + nuxt-site-config@4.2.3(e9b125e2f704f4152b5a916a131eaee1): + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + defu: 6.1.7 + h3: 1.15.11 + nuxt-site-config-kit: 4.2.3(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vue@3.5.43(typescript@5.9.3)) + nuxtseo-shared: 5.3.16(c53d4cf534757bd847435dfb73d28953) + pathe: 2.0.3 + pkg-types: 2.3.3 + site-config-stack: 4.2.3(vue@3.5.43(typescript@5.9.3)) + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - nuxt + - oxc-parser + - rolldown + - unplugin + - vite + - zod + + nuxt-site-config@4.2.3(f3894709c99f9419e33f31d22c529704): + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + consola: 3.4.2 + defu: 6.1.7 + h3: 1.15.11 + nuxt-site-config-kit: 4.2.3(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vue@3.5.43(typescript@5.9.3)) + nuxtseo-shared: 5.3.16(b97a8e7b967e68b693fa07cffe2a3a62) + pathe: 2.0.3 + pkg-types: 2.3.3 + site-config-stack: 4.2.3(vue@3.5.43(typescript@5.9.3)) + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@nuxt/schema' + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - nuxt + - oxc-parser + - rolldown + - unplugin + - vite + - zod + + nuxt@4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1): + dependencies: + '@dxup/nuxt': 0.4.1(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(typescript@5.9.3)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxt/cli': 3.37.0(@nuxt/schema@4.4.8)(cac@6.7.14)(magicast@0.5.5) + '@nuxt/devtools': 3.4.2(@nuxt/schema@4.4.8)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(giget@3.3.1)(ioredis@5.11.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + '@nuxt/kit': 4.4.8(magicast@0.5.5) + '@nuxt/nitro-server': 4.4.8(48a86a4ff7055e06671b0a1a877d44c0) + '@nuxt/schema': 4.4.8 + '@nuxt/telemetry': 2.9.1(@nuxt/kit@4.4.8(magicast@0.5.5)) + '@nuxt/vite-builder': 4.4.8(cd1fd25ac58f65e1d415a14637c7c918) + '@unhead/vue': 2.1.17(vue@3.5.43(typescript@5.9.3)) + '@vue/shared': 3.5.43 + chokidar: 5.0.0 + compatx: 0.2.0 + consola: 3.4.2 + cookie-es: 3.1.1 + defu: 6.1.7 + devalue: 5.9.4 + errx: 0.1.2 + escape-string-regexp: 5.0.0 + exsolve: 1.1.3 + hookable: 6.1.2 + ignore: 7.0.12 + impound: 1.2.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + jiti: 2.7.0 + klona: 2.0.6 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.2 + nanotar: 0.3.0 + nypm: 0.6.10 + ofetch: 1.5.1 + ohash: 2.0.12 + on-change: 6.0.2 + oxc-minify: 0.133.0 + oxc-parser: 0.133.0 + oxc-transform: 0.133.0 + oxc-walker: 1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.133.0)(rolldown@1.2.12) + pathe: 2.0.3 + perfect-debounce: 2.1.0 + picomatch: 4.0.7 + pkg-types: 2.3.3 + rou3: 0.8.1 + scule: 1.3.0 + semver: 7.8.5 + std-env: 4.3.0 + tinyglobby: 0.2.17 + ufo: 1.6.4 + ultrahtml: 1.7.0 + uncrypto: 0.1.3 + unctx: 2.5.0 + unhead: 2.1.17 + unimport: 6.5.0(esbuild@0.28.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unrouting: 0.1.7 + untyped: 2.0.0 + vue: 3.5.43(typescript@5.9.3) + vue-router: 5.3.1(@vue/compiler-sfc@3.5.43)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)) + optionalDependencies: + '@types/node': 26.6.4 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@babel/plugin-proposal-decorators' + - '@babel/plugin-syntax-jsx' + - '@babel/plugin-syntax-typescript' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@farmfe/core' + - '@libsql/client' + - '@netlify/blobs' + - '@oxc-project/types' + - '@pinia/colada' + - '@planetscale/database' + - '@rollup/plugin-babel' + - '@rsbuild/core' + - '@rspack/core' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools' + - '@vue/compiler-sfc' + - aws4fetch + - bare-abort-controller + - bare-buffer + - better-sqlite3 + - bufferutil + - bun-types-no-globals + - cac + - commander + - confbox + - db0 + - dotenv + - drizzle-orm + - encoding + - esbuild + - eslint + - giget + - idb-keyval + - ioredis + - less + - lightningcss + - magicast + - meow + - mysql2 + - optionator + - oxlint + - pinia + - react-native-b4a + - rolldown + - rollup + - rollup-plugin-visualizer + - sass + - sass-embedded + - sqlite3 + - srvx + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - unloader + - uploadthing + - utf-8-validate + - vite + - vue-tsc + - webpack + - xml2js + - yaml + + nuxtseo-shared@5.3.16(b97a8e7b967e68b693fa07cffe2a3a62): + dependencies: + '@clack/prompts': 1.8.1 + '@nuxt/devtools-kit': 4.0.0-alpha.7(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxt/schema': 4.6.0 + birpc: 4.2.0 + consola: 3.4.2 + defu: 6.1.7 + nuxt: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + nypm: 0.6.10 + ofetch: 1.5.1 + pathe: 2.0.3 + pkg-types: 2.3.3 + radix3: 1.1.2 + sirv: 3.0.2 + std-env: 4.3.0 + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + nuxt-site-config: 4.2.3(f3894709c99f9419e33f31d22c529704) + zod: 4.6.5 + transitivePeerDependencies: + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - vite + + nuxtseo-shared@5.3.16(c53d4cf534757bd847435dfb73d28953): + dependencies: + '@clack/prompts': 1.8.1 + '@nuxt/devtools-kit': 4.0.0-alpha.7(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@1.4.3)(mlly@1.8.2)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxt/schema': 4.6.0 + birpc: 4.2.0 + consola: 3.4.2 + defu: 6.1.7 + nuxt: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + nypm: 0.6.10 + ofetch: 1.5.1 + pathe: 2.0.3 + pkg-types: 2.3.3 + radix3: 1.1.2 + sirv: 3.0.2 + std-env: 4.3.0 + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + nuxt-site-config: 4.2.3(f3894709c99f9419e33f31d22c529704) + zod: 4.6.5 + transitivePeerDependencies: + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - vite + + nuxtseo-shared@5.3.16(feeb53ea913f9923d52180f5bfa646b9): + dependencies: + '@clack/prompts': 1.8.1 + '@nuxt/devtools-kit': 4.0.0-alpha.7(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@nuxt/schema': 4.6.0 + birpc: 4.2.0 + consola: 3.4.2 + defu: 6.1.7 + nuxt: 4.4.8(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7))(@oxc-project/types@0.152.0)(@types/node@26.6.4)(@vue/compiler-sfc@3.5.43)(better-sqlite3@12.11.1)(cac@6.7.14)(confbox@0.2.4)(db0@0.3.4(better-sqlite3@12.11.1))(dotenv@17.4.2)(esbuild@0.28.2)(eslint@10.12.0(jiti@2.7.0))(giget@3.3.1)(ioredis@5.11.1)(lightningcss@1.33.0)(magicast@0.5.5)(optionator@0.9.4)(rolldown@1.2.12)(rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0))(rollup@4.64.0)(srvx@0.11.22)(terser@5.51.2)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3))(yaml@2.9.1) + nypm: 0.6.10 + ofetch: 1.5.1 + pathe: 2.0.3 + pkg-types: 2.3.3 + radix3: 1.1.2 + sirv: 3.0.2 + std-env: 4.3.0 + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + nuxt-site-config: 4.2.3(f3894709c99f9419e33f31d22c529704) + zod: 4.6.5 + transitivePeerDependencies: + - confbox + - dotenv + - giget + - jiti + - magic-string + - mlly + - oxc-parser + - rolldown + - unplugin + - vite + + nypm@0.6.10: + dependencies: + citty: 0.2.2 + pathe: 2.0.3 + tinyexec: 1.3.1 + + object-assign@4.1.1: {} + + object-identity@0.2.3: {} + + object-inspect@1.13.4: {} + + obug@2.2.1: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + ohash@2.0.12: {} + + on-change@6.0.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + + open@11.0.4: + dependencies: + default-browser: 5.5.1 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.2.1 + wsl-utils: 1.0.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + orderedmap@2.1.1: {} + + outdent@0.5.0: {} + + oxc-minify@0.133.0: + optionalDependencies: + '@oxc-minify/binding-android-arm-eabi': 0.133.0 + '@oxc-minify/binding-android-arm64': 0.133.0 + '@oxc-minify/binding-darwin-arm64': 0.133.0 + '@oxc-minify/binding-darwin-x64': 0.133.0 + '@oxc-minify/binding-freebsd-x64': 0.133.0 + '@oxc-minify/binding-linux-arm-gnueabihf': 0.133.0 + '@oxc-minify/binding-linux-arm-musleabihf': 0.133.0 + '@oxc-minify/binding-linux-arm64-gnu': 0.133.0 + '@oxc-minify/binding-linux-arm64-musl': 0.133.0 + '@oxc-minify/binding-linux-ppc64-gnu': 0.133.0 + '@oxc-minify/binding-linux-riscv64-gnu': 0.133.0 + '@oxc-minify/binding-linux-riscv64-musl': 0.133.0 + '@oxc-minify/binding-linux-s390x-gnu': 0.133.0 + '@oxc-minify/binding-linux-x64-gnu': 0.133.0 + '@oxc-minify/binding-linux-x64-musl': 0.133.0 + '@oxc-minify/binding-openharmony-arm64': 0.133.0 + '@oxc-minify/binding-wasm32-wasi': 0.133.0 + '@oxc-minify/binding-win32-arm64-msvc': 0.133.0 + '@oxc-minify/binding-win32-ia32-msvc': 0.133.0 + '@oxc-minify/binding-win32-x64-msvc': 0.133.0 + + oxc-parser@0.133.0: + dependencies: + '@oxc-project/types': 0.133.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.133.0 + '@oxc-parser/binding-android-arm64': 0.133.0 + '@oxc-parser/binding-darwin-arm64': 0.133.0 + '@oxc-parser/binding-darwin-x64': 0.133.0 + '@oxc-parser/binding-freebsd-x64': 0.133.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.133.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.133.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.133.0 + '@oxc-parser/binding-linux-arm64-musl': 0.133.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.133.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.133.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.133.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.133.0 + '@oxc-parser/binding-linux-x64-gnu': 0.133.0 + '@oxc-parser/binding-linux-x64-musl': 0.133.0 + '@oxc-parser/binding-openharmony-arm64': 0.133.0 + '@oxc-parser/binding-wasm32-wasi': 0.133.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.133.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.133.0 + '@oxc-parser/binding-win32-x64-msvc': 0.133.0 + + oxc-parser@0.139.0: + dependencies: + '@oxc-project/types': 0.139.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.139.0 + '@oxc-parser/binding-android-arm64': 0.139.0 + '@oxc-parser/binding-darwin-arm64': 0.139.0 + '@oxc-parser/binding-darwin-x64': 0.139.0 + '@oxc-parser/binding-freebsd-x64': 0.139.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.139.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.139.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.139.0 + '@oxc-parser/binding-linux-arm64-musl': 0.139.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.139.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.139.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.139.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.139.0 + '@oxc-parser/binding-linux-x64-gnu': 0.139.0 + '@oxc-parser/binding-linux-x64-musl': 0.139.0 + '@oxc-parser/binding-openharmony-arm64': 0.139.0 + '@oxc-parser/binding-wasm32-wasi': 0.139.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.139.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.139.0 + '@oxc-parser/binding-win32-x64-msvc': 0.139.0 + + oxc-parser@0.141.0: + dependencies: + '@oxc-project/types': 0.141.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.141.0 + '@oxc-parser/binding-android-arm64': 0.141.0 + '@oxc-parser/binding-darwin-arm64': 0.141.0 + '@oxc-parser/binding-darwin-x64': 0.141.0 + '@oxc-parser/binding-freebsd-x64': 0.141.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.141.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.141.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.141.0 + '@oxc-parser/binding-linux-arm64-musl': 0.141.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.141.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.141.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.141.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.141.0 + '@oxc-parser/binding-linux-x64-gnu': 0.141.0 + '@oxc-parser/binding-linux-x64-musl': 0.141.0 + '@oxc-parser/binding-openharmony-arm64': 0.141.0 + '@oxc-parser/binding-wasm32-wasi': 0.141.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.141.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.141.0 + '@oxc-parser/binding-win32-x64-msvc': 0.141.0 + + oxc-parser@0.151.0: + dependencies: + '@oxc-project/types': 0.151.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.151.0 + '@oxc-parser/binding-android-arm64': 0.151.0 + '@oxc-parser/binding-darwin-arm64': 0.151.0 + '@oxc-parser/binding-darwin-x64': 0.151.0 + '@oxc-parser/binding-freebsd-x64': 0.151.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.151.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.151.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.151.0 + '@oxc-parser/binding-linux-arm64-musl': 0.151.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.151.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.151.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.151.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.151.0 + '@oxc-parser/binding-linux-x64-gnu': 0.151.0 + '@oxc-parser/binding-linux-x64-musl': 0.151.0 + '@oxc-parser/binding-openharmony-arm64': 0.151.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.151.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.151.0 + '@oxc-parser/binding-win32-x64-msvc': 0.151.0 + + oxc-transform@0.133.0: + optionalDependencies: + '@oxc-transform/binding-android-arm-eabi': 0.133.0 + '@oxc-transform/binding-android-arm64': 0.133.0 + '@oxc-transform/binding-darwin-arm64': 0.133.0 + '@oxc-transform/binding-darwin-x64': 0.133.0 + '@oxc-transform/binding-freebsd-x64': 0.133.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.133.0 + '@oxc-transform/binding-linux-arm-musleabihf': 0.133.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.133.0 + '@oxc-transform/binding-linux-arm64-musl': 0.133.0 + '@oxc-transform/binding-linux-ppc64-gnu': 0.133.0 + '@oxc-transform/binding-linux-riscv64-gnu': 0.133.0 + '@oxc-transform/binding-linux-riscv64-musl': 0.133.0 + '@oxc-transform/binding-linux-s390x-gnu': 0.133.0 + '@oxc-transform/binding-linux-x64-gnu': 0.133.0 + '@oxc-transform/binding-linux-x64-musl': 0.133.0 + '@oxc-transform/binding-openharmony-arm64': 0.133.0 + '@oxc-transform/binding-wasm32-wasi': 0.133.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.133.0 + '@oxc-transform/binding-win32-ia32-msvc': 0.133.0 + '@oxc-transform/binding-win32-x64-msvc': 0.133.0 + + oxc-transform@0.141.0: + optionalDependencies: + '@oxc-transform/binding-android-arm-eabi': 0.141.0 + '@oxc-transform/binding-android-arm64': 0.141.0 + '@oxc-transform/binding-darwin-arm64': 0.141.0 + '@oxc-transform/binding-darwin-x64': 0.141.0 + '@oxc-transform/binding-freebsd-x64': 0.141.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.141.0 + '@oxc-transform/binding-linux-arm-musleabihf': 0.141.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.141.0 + '@oxc-transform/binding-linux-arm64-musl': 0.141.0 + '@oxc-transform/binding-linux-ppc64-gnu': 0.141.0 + '@oxc-transform/binding-linux-riscv64-gnu': 0.141.0 + '@oxc-transform/binding-linux-riscv64-musl': 0.141.0 + '@oxc-transform/binding-linux-s390x-gnu': 0.141.0 + '@oxc-transform/binding-linux-x64-gnu': 0.141.0 + '@oxc-transform/binding-linux-x64-musl': 0.141.0 + '@oxc-transform/binding-openharmony-arm64': 0.141.0 + '@oxc-transform/binding-wasm32-wasi': 0.141.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.141.0 + '@oxc-transform/binding-win32-ia32-msvc': 0.141.0 + '@oxc-transform/binding-win32-x64-msvc': 0.141.0 + + oxc-walker@0.7.0(oxc-parser@0.141.0): + dependencies: + magic-regexp: 0.10.0 + oxc-parser: 0.141.0 + + oxc-walker@1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.133.0)(rolldown@1.2.12): + optionalDependencies: + '@oxc-project/types': 0.152.0 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + + oxc-walker@1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.139.0)(rolldown@1.2.12): + optionalDependencies: + '@oxc-project/types': 0.152.0 + oxc-parser: 0.139.0 + rolldown: 1.2.12 + + oxc-walker@1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.141.0)(rolldown@1.2.12): + optionalDependencies: + '@oxc-project/types': 0.152.0 + oxc-parser: 0.141.0 + rolldown: 1.2.12 + + oxc-walker@1.1.1(@oxc-project/types@0.152.0)(oxc-parser@0.151.0)(rolldown@1.2.12): + optionalDependencies: + '@oxc-project/types': 0.152.0 + oxc-parser: 0.151.0 + rolldown: 1.2.12 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + package-manager-detector@1.9.0: {} + + pako@1.0.11: {} + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-path@7.1.0: + dependencies: + protocols: 2.0.2 + + parse-url@9.2.0: + dependencies: + '@types/parse-path': 7.1.0 + parse-path: 7.1.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + parse5@8.0.1: + dependencies: + entities: 8.1.0 + + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-expression-matcher@1.6.2: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-scurry@2.0.2: + dependencies: + lru-cache: 11.5.3 + minipass: 7.1.3 + + path-to-regexp@8.4.2: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + perfect-debounce@2.1.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.7: {} + + pify@4.0.1: {} + + pkce-challenge@5.0.1: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + pkg-types@2.3.3: + dependencies: + confbox: 0.3.1 + exsolve: 1.1.3 + pathe: 2.0.3 + + possible-typed-array-names@1.1.0: {} + + postcss-calc@10.1.1(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-selector-parser: 7.1.6 + postcss-value-parser: 4.2.0 + + postcss-colormin@8.0.5(postcss@8.5.29): + dependencies: + '@colordx/core': 5.8.0 + browserslist: 4.29.3 + caniuse-api: 4.0.0 + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-convert-values@8.0.4(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-selector-parser: 7.1.6 + + postcss-discard-duplicates@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + + postcss-discard-empty@8.0.5(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + + postcss-discard-overridden@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + + postcss-merge-longhand@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + stylehacks: 8.0.4(postcss@8.5.29) + + postcss-merge-rules@8.0.5(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + caniuse-api: 4.0.0 + cssnano-utils: 6.0.4(postcss@8.5.29) + postcss: 8.5.29 + postcss-selector-parser: 7.1.6 + + postcss-minify-font-values@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@8.0.6(postcss@8.5.29): + dependencies: + '@colordx/core': 5.8.0 + cssnano-utils: 6.0.4(postcss@8.5.29) + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-minify-params@8.0.4(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + cssnano-utils: 6.0.4(postcss@8.5.29) + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@8.0.5(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + caniuse-api: 4.0.0 + cssesc: 3.0.0 + postcss: 8.5.29 + postcss-selector-parser: 7.1.6 + + postcss-normalize-charset@8.0.5(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + + postcss-normalize-display-values@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@8.0.4(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@8.0.5(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@8.0.5(postcss@8.5.29): + dependencies: + cssnano-utils: 6.0.4(postcss@8.5.29) + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@8.0.5(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + caniuse-api: 4.0.0 + postcss: 8.5.29 + + postcss-reduce-transforms@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@7.1.6: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@8.0.6(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-value-parser: 4.2.0 + svgo: 4.1.0 + + postcss-unique-selectors@8.0.4(postcss@8.5.29): + dependencies: + postcss: 8.5.29 + postcss-selector-parser: 7.1.6 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.29: + dependencies: + nanoid: 3.3.20 + picocolors: 1.1.1 + source-map-js: 1.2.2 + + powershell-utils@0.2.1: {} + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.97.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.5 + tunnel-agent: 0.6.0 + + prelude-ls@1.2.1: {} + + prettier@2.8.8: {} + + pretty-bytes@7.2.0: {} + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + promise@7.3.1: + dependencies: + asap: 2.0.6 + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + property-information@7.2.0: {} + + prosemirror-changeset@2.4.4: + dependencies: + prosemirror-transform: 1.12.2 + + prosemirror-commands@1.7.2: + dependencies: + prosemirror-model: 1.25.12 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + + prosemirror-dropcursor@1.8.4: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + prosemirror-view: 1.42.6 + + prosemirror-gapcursor@1.4.1: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.12 + prosemirror-state: 1.4.4 + prosemirror-view: 1.42.6 + + prosemirror-history@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + prosemirror-view: 1.42.6 + rope-sequence: 1.3.4 + + prosemirror-inputrules@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.4 + w3c-keyname: 2.2.8 + + prosemirror-model@1.25.12: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.12 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + + prosemirror-state@1.4.4: + dependencies: + prosemirror-model: 1.25.12 + prosemirror-transform: 1.12.2 + prosemirror-view: 1.42.6 + + prosemirror-tables@1.8.5: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.12 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + prosemirror-view: 1.42.6 + + prosemirror-transform@1.12.2: + dependencies: + prosemirror-model: 1.25.12 + + prosemirror-view@1.42.6: + dependencies: + prosemirror-model: 1.25.12 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.2 + + protocols@2.0.2: {} + + proxy-addr@2.0.8: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + publint@0.3.25: + dependencies: + '@publint/pack': 0.1.7 + package-manager-detector: 1.9.0 + picocolors: 1.1.1 + sade: 1.8.1 + + pug-attrs@3.0.0: + dependencies: + constantinople: 4.0.1 + js-stringify: 1.0.2 + pug-runtime: 3.0.1 + + pug-code-gen@3.0.4: + dependencies: + constantinople: 4.0.1 + doctypes: 1.1.0 + js-stringify: 1.0.2 + pug-attrs: 3.0.0 + pug-error: 2.1.0 + pug-runtime: 3.0.1 + void-elements: 3.1.0 + with: 7.0.2 + + pug-error@2.1.0: {} + + pug-filters@4.0.0: + dependencies: + constantinople: 4.0.1 + jstransformer: 1.0.0 + pug-error: 2.1.0 + pug-walk: 2.0.0 + resolve: 1.22.12 + + pug-lexer@5.0.1: + dependencies: + character-parser: 2.2.0 + is-expression: 4.0.0 + pug-error: 2.1.0 + + pug-linker@4.0.0: + dependencies: + pug-error: 2.1.0 + pug-walk: 2.0.0 + + pug-load@3.0.0: + dependencies: + object-assign: 4.1.1 + pug-walk: 2.0.0 + + pug-parser@6.0.0: + dependencies: + pug-error: 2.1.0 + token-stream: 1.0.0 + + pug-runtime@3.0.1: {} + + pug-strip-comments@2.0.0: + dependencies: + pug-error: 2.1.0 + + pug-walk@2.0.0: {} + + pug@3.0.4: + dependencies: + pug-code-gen: 3.0.4 + pug-filters: 4.0.0 + pug-lexer: 5.0.1 + pug-linker: 4.0.0 + pug-load: 3.0.0 + pug-parser: 6.0.0 + pug-runtime: 3.0.1 + pug-strip-comments: 2.0.0 + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + qified@0.10.1: + dependencies: + hookified: 2.2.0 + + qs@6.16.0: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + radix3@1.1.2: {} + + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + rc9@3.1.0: + dependencies: + defu: 6.1.7 + destr: 2.0.5 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.15.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + + readdirp@5.1.1: {} + + recast@0.23.21: + dependencies: + ast-types: 0.16.3 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + regexp-tree@0.1.27: {} + + rehype-external-links@3.0.0: + dependencies: + '@types/hast': 3.0.5 + '@ungap/structured-clone': 1.4.0 + hast-util-is-element: 3.0.0 + is-absolute-url: 4.0.1 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.1.0 + + rehype-minify-whitespace@6.0.2: + dependencies: + '@types/hast': 3.0.5 + hast-util-minify-whitespace: 1.0.1 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.5 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-remark@10.0.1: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + hast-util-to-mdast: 10.1.2 + unified: 11.0.5 + vfile: 6.0.3 + + rehype-slug@6.0.0: + dependencies: + '@types/hast': 3.0.5 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.1 + unist-util-visit: 5.1.0 + + rehype-sort-attribute-values@5.0.1: + dependencies: + '@types/hast': 3.0.5 + hast-util-is-element: 3.0.0 + unist-util-visit: 5.1.0 + + rehype-sort-attributes@5.0.1: + dependencies: + '@types/hast': 3.0.5 + unist-util-visit: 5.1.0 + + reka-ui@2.10.5(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@floating-ui/dom': 1.8.0 + '@floating-ui/vue': 1.1.11(vue@3.5.43(typescript@5.9.3)) + '@internationalized/date': 3.12.4 + '@internationalized/number': 3.6.8 + '@tanstack/vue-virtual': 3.13.39(vue@3.5.43(typescript@5.9.3)) + '@vueuse/core': 14.4.0(vue@3.5.43(typescript@5.9.3)) + '@vueuse/shared': 14.4.0(vue@3.5.43(typescript@5.9.3)) + aria-hidden: 1.2.6 + defu: 6.1.7 + ohash: 2.0.12 + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@vue/composition-api' + + remark-emoji@5.0.2: + dependencies: + '@types/mdast': 4.0.4 + emoticon: 4.1.0 + mdast-util-find-and-replace: 3.0.3 + node-emoji: 2.2.0 + unified: 11.0.5 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdc@3.11.1: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + flat: 6.0.1 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + micromark: 4.0.3 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.3 + parse-entities: 4.0.2 + scule: 1.3.0 + stringify-entities: 4.0.4 + unified: 11.0.5 + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + yaml: 2.9.1 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.1.0 + micromark-util-types: 2.0.3 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.2.0 + unified: 11.0.5 + + require-from-string@2.0.2: {} + + resolve-from@5.0.0: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.17.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + retry@0.12.0: {} + + reusify@1.1.0: {} + + rolldown@1.2.12: + dependencies: + '@oxc-project/types': 0.152.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.12 + '@rolldown/binding-android-arm64': 1.2.12 + '@rolldown/binding-darwin-arm64': 1.2.12 + '@rolldown/binding-darwin-x64': 1.2.12 + '@rolldown/binding-freebsd-x64': 1.2.12 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.12 + '@rolldown/binding-linux-arm64-gnu': 1.2.12 + '@rolldown/binding-linux-arm64-musl': 1.2.12 + '@rolldown/binding-linux-ppc64-gnu': 1.2.12 + '@rolldown/binding-linux-s390x-gnu': 1.2.12 + '@rolldown/binding-linux-x64-gnu': 1.2.12 + '@rolldown/binding-linux-x64-musl': 1.2.12 + '@rolldown/binding-openharmony-arm64': 1.2.12 + '@rolldown/binding-win32-arm64-msvc': 1.2.12 + '@rolldown/binding-win32-x64-msvc': 1.2.12 + + rollup-plugin-visualizer@7.1.1(rolldown@1.2.12)(rollup@4.64.0): + dependencies: + open: 11.0.4 + picomatch: 4.0.7 + source-map: 0.8.0 + yargs: 18.2.0 + optionalDependencies: + rolldown: 1.2.12 + rollup: 4.64.0 + + rollup@4.64.0: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@napi-rs/lzma-linux-x64-gnu': 1.5.1 + '@rollup/rollup-android-arm-eabi': 4.64.0 + '@rollup/rollup-android-arm64': 4.64.0 + '@rollup/rollup-darwin-arm64': 4.64.0 + '@rollup/rollup-darwin-x64': 4.64.0 + '@rollup/rollup-freebsd-arm64': 4.64.0 + '@rollup/rollup-freebsd-x64': 4.64.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.0 + '@rollup/rollup-linux-arm-musleabihf': 4.64.0 + '@rollup/rollup-linux-arm64-gnu': 4.64.0 + '@rollup/rollup-linux-arm64-musl': 4.64.0 + '@rollup/rollup-linux-loong64-gnu': 4.64.0 + '@rollup/rollup-linux-loong64-musl': 4.64.0 + '@rollup/rollup-linux-ppc64-gnu': 4.64.0 + '@rollup/rollup-linux-ppc64-musl': 4.64.0 + '@rollup/rollup-linux-riscv64-gnu': 4.64.0 + '@rollup/rollup-linux-riscv64-musl': 4.64.0 + '@rollup/rollup-linux-s390x-gnu': 4.64.0 + '@rollup/rollup-linux-x64-gnu': 4.64.0 + '@rollup/rollup-linux-x64-musl': 4.64.0 + '@rollup/rollup-openbsd-x64': 4.64.0 + '@rollup/rollup-openharmony-arm64': 4.64.0 + '@rollup/rollup-win32-arm64-msvc': 4.64.0 + '@rollup/rollup-win32-ia32-msvc': 4.64.0 + '@rollup/rollup-win32-x64-gnu': 4.64.0 + '@rollup/rollup-win32-x64-msvc': 4.64.0 + fsevents: 2.3.3 + + rope-sequence@1.3.4: {} + + rou3@0.8.1: {} + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + sax@1.6.1: {} + + scule@1.3.0: {} + + semver@6.3.1: {} + + semver@7.8.5: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@7.1.2: {} + + seroval@1.6.8: {} + + serve-placeholder@2.0.2: + dependencies: + defu: 6.1.7 + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + sharp@0.35.5(@types/node@26.6.4): + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.5 + '@img/sharp-darwin-x64': 0.35.5 + '@img/sharp-freebsd-wasm32': 0.35.5 + '@img/sharp-libvips-darwin-arm64': 1.3.4 + '@img/sharp-libvips-darwin-x64': 1.3.4 + '@img/sharp-libvips-linux-arm': 1.3.4 + '@img/sharp-libvips-linux-arm64': 1.3.4 + '@img/sharp-libvips-linux-ppc64': 1.3.4 + '@img/sharp-libvips-linux-riscv64': 1.3.4 + '@img/sharp-libvips-linux-s390x': 1.3.4 + '@img/sharp-libvips-linux-x64': 1.3.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + '@img/sharp-linux-arm': 0.35.5 + '@img/sharp-linux-arm64': 0.35.5 + '@img/sharp-linux-ppc64': 0.35.5 + '@img/sharp-linux-riscv64': 0.35.5 + '@img/sharp-linux-s390x': 0.35.5 + '@img/sharp-linux-x64': 0.35.5 + '@img/sharp-linuxmusl-arm64': 0.35.5 + '@img/sharp-linuxmusl-x64': 0.35.5 + '@img/sharp-webcontainers-wasm32': 0.35.5 + '@img/sharp-win32-arm64': 0.35.5 + '@img/sharp-win32-ia32': 0.35.5 + '@img/sharp-win32-x64': 0.35.5 + '@types/node': 26.6.4 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.12.0: {} + + shiki@4.5.0: + dependencies: + '@shikijs/core': 4.5.0 + '@shikijs/engine-javascript': 4.5.0 + '@shikijs/engine-oniguruma': 4.5.0 + '@shikijs/langs': 4.5.0 + '@shikijs/themes': 4.5.0 + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + simple-git@3.36.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + '@simple-git/args-pathspec': 1.0.4 + '@simple-git/argv-parser': 1.1.1 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + site-config-stack@4.2.3(vue@3.5.43(typescript@5.9.3)): + dependencies: + ufo: 1.6.4 + vue: 3.5.43(typescript@5.9.3) + + sitemapd@0.2.2: + dependencies: + fast-xml-parser: 5.11.2 + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@3.0.0: {} + + slash@5.1.0: {} + + slugify@1.6.9: {} + + smob@1.6.2: {} + + socket.io-client@4.8.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3 + engine.io-client: 6.6.7 + socket.io-parser: 4.2.7 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.7: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + source-map-js@1.2.2: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + source-map@0.8.0: {} + + space-separated-tokens@2.0.2: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + srvx@0.11.22: {} + + srvx@0.12.8: + optional: true + + standard-as-callback@2.1.0: {} + + statuses@2.0.2: {} + + std-env@4.3.0: {} + + streamx@2.28.1: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string-width@8.3.0: + dependencies: + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.4.0 + + strip-bom@3.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-literal@4.0.0: + dependencies: + js-tokens: 10.0.0 + + strnum@2.4.2: + dependencies: + anynum: 1.0.1 + + structured-clone-es@2.0.1: {} + + stylehacks@8.0.4(postcss@8.5.29): + dependencies: + browserslist: 4.29.3 + postcss: 8.5.29 + postcss-selector-parser: 7.1.6 + + supports-color@10.2.2: {} + + supports-preserve-symlinks-flag@1.0.0: {} + + svgo@4.1.0: + dependencies: + commander: 11.1.0 + css-select: 6.0.0 + css-tree: 3.2.1 + css-what: 7.0.0 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.1 + + swrv@1.3.0(vue@3.5.43(typescript@5.9.3)): + dependencies: + vue: 3.5.43(typescript@5.9.3) + + tagged-tag@1.0.0: {} + + tailwind-merge@3.7.0: {} + + tailwind-variants@3.3.1(tailwind-merge@3.7.0)(tailwindcss@4.3.3): + optionalDependencies: + tailwind-merge: 3.7.0 + tailwindcss: 4.3.3 + + tailwindcss@4.3.3: {} + + tapable@2.3.3: {} + + tar-fs@2.1.5: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar-stream@3.2.2: + dependencies: + b4a: 1.9.0 + bare-fs: 4.8.2 + fast-fifo: 1.3.2 + streamx: 2.28.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + tar@7.5.22: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + + teex@1.0.1: + dependencies: + streamx: 2.28.1 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + term-size@2.2.1: {} + + terser@5.51.2: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.19.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + text-decoder@1.2.7: + dependencies: + b4a: 1.9.0 + transitivePeerDependencies: + - react-native-b4a + + tiny-inflate@1.0.3: {} + + tiny-invariant@1.3.3: {} + + tinyclip@0.1.15: {} + + tinyexec@1.3.1: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + token-stream@1.0.0: {} + + tosource@2.0.0-alpha.3: {} + + totalist@3.0.1: {} + + tr46@0.0.3: {} + + trim-lines@3.0.1: {} + + trim-trailing-lines@2.1.0: {} + + trough@2.2.0: {} + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-map@1.0.3: {} + + tslib@2.8.1: {} + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@5.10.0: + dependencies: + tagged-tag: 1.0.0 + + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + + type-level-regexp@0.1.17: {} + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typescript@5.9.3: {} + + uc.micro@2.1.0: {} + + ufo@1.6.4: {} + + ultrahtml@1.7.0: {} + + uncrypto@0.1.3: {} + + unctx@2.5.0: + dependencies: + acorn: 8.19.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + unplugin: 2.3.11 + + unctx@3.0.1(magic-string@0.30.21)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))): + optionalDependencies: + magic-string: 0.30.21 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + + unctx@3.0.1(magic-string@0.30.21)(oxc-parser@0.139.0)(rolldown@1.2.12)(unplugin@2.3.11): + optionalDependencies: + magic-string: 0.30.21 + oxc-parser: 0.139.0 + rolldown: 1.2.12 + unplugin: 2.3.11 + + unctx@3.0.1(magic-string@0.30.21)(oxc-parser@0.141.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))): + optionalDependencies: + magic-string: 0.30.21 + oxc-parser: 0.141.0 + rolldown: 1.2.12 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + + unctx@3.0.1(magic-string@1.4.3)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))): + optionalDependencies: + magic-string: 1.4.3 + oxc-parser: 0.133.0 + rolldown: 1.2.12 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + + unctx@3.0.1(magic-string@1.4.3)(oxc-parser@0.151.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))): + optionalDependencies: + magic-string: 1.4.3 + oxc-parser: 0.151.0 + rolldown: 1.2.12 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + + undici-types@8.9.0: {} + + undici@7.30.0: {} + + undici@8.11.2: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unhead@2.1.17: + dependencies: + hookable: 6.1.2 + + unhead@3.4.2(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + hookable: 6.1.2 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + optionalDependencies: + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - webpack + + unicode-emoji-modifier-base@1.0.0: {} + + unicorn-magic@0.3.0: {} + + unicorn-magic@0.4.1: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unifont@0.7.5: + dependencies: + css-tree: 3.2.1 + ohash: 2.0.12 + undici: 8.11.2 + + unimport@6.5.0(esbuild@0.28.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + acorn: 8.19.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.2.1 + magic-string: 1.4.3 + mlly: 1.8.2 + pathe: 2.0.3 + picomatch: 4.0.7 + pkg-types: 2.3.3 + scule: 1.3.0 + strip-literal: 4.0.0 + tinyglobby: 0.2.17 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-utils: 0.3.2 + optionalDependencies: + oxc-parser: 0.133.0 + rolldown: 1.2.12 + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rollup + - unloader + - vite + - webpack + + unist-builder@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universalify@0.1.2: {} + + unpipe@1.0.0: {} + + unplugin-auto-import@21.1.0(@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))))(@vueuse/core@14.4.0(vue@3.5.43(typescript@5.9.3)))(esbuild@0.28.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + local-pkg: 1.2.1 + magic-string: 1.4.3 + picomatch: 4.0.7 + unimport: 6.5.0(esbuild@0.28.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-utils: 0.3.2 + optionalDependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + '@vueuse/core': 14.4.0(vue@3.5.43(typescript@5.9.3)) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - oxc-parser + - rolldown + - rollup + - unloader + - vite + - webpack + + unplugin-dts@1.1.2(@vue/language-core@3.3.12)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.64.0) + '@volar/typescript': 2.4.28 + compare-versions: 6.1.1 + debug: 4.4.3 + glob-to-regexp: 0.4.1 + kolorist: 1.8.0 + local-pkg: 1.2.1 + magic-string: 0.30.21 + typescript: 5.9.3 + unplugin: 2.3.11 + optionalDependencies: + '@vue/language-core': 3.3.12 + esbuild: 0.28.2 + rolldown: 1.2.12 + rollup: 4.64.0 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - supports-color + + unplugin-utils@0.3.2: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.7 + + unplugin-vue-components@32.1.0(@nuxt/kit@4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))))(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)): + dependencies: + chokidar: 5.0.0 + local-pkg: 1.2.1 + magic-string: 0.30.21 + mlly: 1.8.2 + obug: 2.2.1 + picomatch: 4.0.7 + tinyglobby: 0.2.17 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-utils: 0.3.2 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.6.0)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - vite + - webpack + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.19.0 + picomatch: 4.0.7 + webpack-virtual-modules: 0.6.2 + + unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.7 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.28.2 + rolldown: 1.2.12 + rollup: 4.64.0 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + + unrouting@0.1.7: + dependencies: + escape-string-regexp: 5.0.0 + ufo: 1.6.4 + + unrouting@0.2.3: + dependencies: + escape-string-regexp: 5.0.0 + ufo: 1.6.4 + + unstorage@1.17.5(db0@0.3.4(better-sqlite3@12.11.1))(ioredis@5.11.1): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.3 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + db0: 0.3.4(better-sqlite3@12.11.1) + ioredis: 5.11.1 + + untun@0.2.2: {} + + untyped@2.0.0: + dependencies: + citty: 0.1.6 + defu: 6.1.7 + jiti: 2.7.0 + knitwork: 1.3.0 + scule: 1.3.0 + + unwasm@0.5.3: + dependencies: + exsolve: 1.1.3 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.2 + pathe: 2.0.3 + pkg-types: 2.3.3 + + update-browserslist-db@1.3.3(browserslist@4.29.3): + dependencies: + browserslist: 4.29.3 + escalade: 3.2.0 + picocolors: 1.1.1 + + uqr@0.1.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vary@1.1.2: {} + + vaul-vue@0.4.1(reka-ui@2.10.5(vue@3.5.43(typescript@5.9.3)))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@vueuse/core': 10.11.1(vue@3.5.43(typescript@5.9.3)) + reka-ui: 2.10.5(vue@3.5.43(typescript@5.9.3)) + vue: 3.5.43(typescript@5.9.3) + transitivePeerDependencies: + - '@vue/composition-api' + + verkit@0.5.0: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-dev-rpc@2.0.0(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + birpc: 4.2.0 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vite-hot-client: 2.2.0(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + + vite-hot-client@2.2.0(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + + vite-node@5.3.0(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1): + dependencies: + cac: 6.7.14 + es-module-lexer: 2.3.2 + obug: 2.2.1 + pathe: 2.0.3 + vite: 7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vite-plugin-checker@0.14.5(eslint@10.12.0(jiti@2.7.0))(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1))(vue-tsc@3.3.12(typescript@5.9.3)): + dependencies: + '@babel/code-frame': 7.29.7 + chokidar: 5.0.0 + npm-run-path: 6.0.0 + picocolors: 1.1.1 + picomatch: 4.0.7 + proper-lockfile: 4.1.2 + tiny-invariant: 1.3.3 + vite: 7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1) + optionalDependencies: + eslint: 10.12.0(jiti@2.7.0) + optionator: 0.9.4 + typescript: 5.9.3 + vue-tsc: 3.3.12(typescript@5.9.3) + + vite-plugin-dts@5.1.2(@vue/language-core@3.3.12)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + unplugin-dts: 1.1.2(@vue/language-core@3.3.12)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(typescript@5.9.3)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + optionalDependencies: + rollup: 4.64.0 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@rspack/core' + - '@vue/language-core' + - esbuild + - rolldown + - supports-color + - typescript + - webpack + + vite-plugin-inspect@11.4.1(@nuxt/kit@4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))))(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + ansis: 4.4.0 + error-stack-parser-es: 1.0.5 + obug: 2.2.1 + ohash: 2.0.12 + open: 11.0.4 + perfect-debounce: 2.1.0 + sirv: 3.0.2 + unplugin-utils: 0.3.2 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vite-dev-rpc: 2.0.0(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + optionalDependencies: + '@nuxt/kit': 4.6.0(@nuxt/schema@4.4.8)(confbox@0.2.4)(dotenv@17.4.2)(giget@3.3.1)(jiti@2.7.0)(magic-string@0.30.21)(mlly@1.8.2)(oxc-parser@0.133.0)(rolldown@1.2.12)(unplugin@3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))) + + vite-plugin-singlefile@2.3.3(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)): + dependencies: + micromatch: 4.0.8 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + optionalDependencies: + rollup: 4.64.0 + + vite-plugin-vue-tracer@1.5.0(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)): + dependencies: + estree-walker: 3.0.3 + exsolve: 1.1.3 + magic-string: 1.4.3 + pathe: 2.0.3 + source-map-js: 1.2.2 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + vue: 3.5.43(typescript@5.9.3) + + vite@7.3.7(@types/node@26.6.4)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(yaml@2.9.1): + dependencies: + esbuild: 0.28.2 + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + postcss: 8.5.29 + rollup: 4.64.0 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.6.4 + fsevents: 2.3.3 + jiti: 2.7.0 + lightningcss: 1.33.0 + terser: 5.51.2 + yaml: 2.9.1 + + vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.29 + rolldown: 1.2.12 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.6.4 + esbuild: 0.28.2 + fsevents: 2.3.3 + jiti: 2.7.0 + terser: 5.51.2 + yaml: 2.9.1 + + void-elements@3.1.0: {} + + vscode-uri@3.2.0: {} + + vue-bundle-renderer@2.4.0: + dependencies: + ufo: 1.6.4 + + vue-component-meta@3.3.12(typescript@5.9.3): + dependencies: + '@volar/typescript': 2.4.28 + '@vue/language-core': 3.3.12 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.9.3 + + vue-component-type-helpers@3.3.12: {} + + vue-demi@0.14.10(vue@3.5.43(typescript@5.9.3)): + dependencies: + vue: 3.5.43(typescript@5.9.3) + + vue-devtools-stub@0.1.0: {} + + vue-docgen-api@4.79.2(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + '@vue/compiler-dom': 3.5.43 + '@vue/compiler-sfc': 3.5.43 + ast-types: 0.16.3 + esm-resolve: 1.0.11 + hash-sum: 2.0.0 + lru-cache: 8.0.5 + pug: 3.0.4 + recast: 0.23.21 + ts-map: 1.0.3 + vue: 3.5.43(typescript@5.9.3) + vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.5.43(typescript@5.9.3)) + + vue-i18n@11.4.13(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@intlify/core-base': 11.4.13 + '@intlify/devtools-types': 11.4.13 + '@intlify/shared': 11.4.13 + '@vue/devtools-api': 6.6.4 + vue: 3.5.43(typescript@5.9.3) + + vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.5.43(typescript@5.9.3)): + dependencies: + vue: 3.5.43(typescript@5.9.3) + + vue-router@5.3.1(@vue/compiler-sfc@3.5.43)(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1))(vue@3.5.43(typescript@5.9.3)): + dependencies: + '@vue-macros/common': 3.1.4(vue@3.5.43(typescript@5.9.3)) + '@vue/devtools-api': 8.2.1 + ast-walker-scope: 0.9.0 + chokidar: 5.0.0 + confbox: 0.2.4 + local-pkg: 1.2.1 + magic-string: 0.30.21 + mlly: 1.8.2 + muggle-string: 0.4.1 + nostics: 1.3.0 + pathe: 2.0.3 + picomatch: 4.0.7 + scule: 1.3.0 + tinyglobby: 0.2.17 + unplugin: 3.4.0(esbuild@0.28.2)(rolldown@1.2.12)(rollup@4.64.0)(vite@8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1)) + unplugin-utils: 0.3.2 + vue: 3.5.43(typescript@5.9.3) + optionalDependencies: + '@vue/compiler-sfc': 3.5.43 + vite: 8.3.3(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - unloader + - webpack + + vue-tsc@3.3.12(typescript@5.9.3): + dependencies: + '@volar/typescript': 2.4.28 + '@vue/language-core': 3.3.12 + typescript: 5.9.3 + + vue@3.5.43(typescript@5.9.3): + dependencies: + '@vue/compiler-dom': 3.5.43 + '@vue/compiler-sfc': 3.5.43 + '@vue/runtime-dom': 3.5.43 + '@vue/server-renderer': 3.5.43 + '@vue/shared': 3.5.43 + optionalDependencies: + typescript: 5.9.3 + + w3c-keyname@2.2.8: {} + + web-namespaces@2.0.1: {} + + webidl-conversions@3.0.1: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + wheel-gestures@2.3.0: {} + + which-typed-array@1.1.24: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@6.0.1: + dependencies: + isexe: 4.0.0 + + with@7.0.2: + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + assert-never: 1.4.0 + babel-walk: 3.0.0-canary-5 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + ws@8.21.3: {} + + ws@8.22.0: {} + + wsl-utils@1.0.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.2.1 + + xml-naming@0.3.0: {} + + xmlhttprequest-ssl@2.1.2: {} + + y-protocols@1.0.7(yjs@13.6.33): + dependencies: + lib0: 0.2.119 + yjs: 13.6.33 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@5.0.0: {} + + yaml-eslint-parser@1.3.2: + dependencies: + eslint-visitor-keys: 3.4.3 + yaml: 2.9.1 + + yaml@2.9.1: {} + + yargs-parser@22.0.0: {} + + yargs@18.2.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.3.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + yjs@13.6.33: + dependencies: + lib0: 0.2.119 + + yocto-queue@0.1.0: {} + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.1: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.7.0 + '@speed-highlight/core': 1.2.24 + cookie-es: 3.1.1 + youch-core: 0.3.3 + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-to-json-schema@3.25.2(zod@4.6.5): + dependencies: + zod: 4.6.5 + + zod@3.25.76: {} + + zod@4.6.5: {} + + zwitch@2.0.4: {} diff --git a/code/g3soft-libs/pnpm-workspace.yaml b/code/g3soft-libs/pnpm-workspace.yaml new file mode 100644 index 00000000..f1dee7c8 --- /dev/null +++ b/code/g3soft-libs/pnpm-workspace.yaml @@ -0,0 +1,30 @@ +packages: + - packages/* + - docs + +# 统一 vue / typescript 版本:各包写 "vue": "catalog:",避免多版本漂移。 +catalog: + vue: ^3.5.41 + typescript: ^5.9.0 + +# pnpm 11 的构建脚本白名单(map 形式;v10 的 onlyBuiltDependencies 数组写法在 v11 已失效)。 +# better-sqlite3 —— Docus 全文搜索(FTS5)依赖的原生模块,必须放行才能下载/编译二进制 +# vue-demi —— vue-docgen-api 的传递依赖,安装时要跑脚本切换 Vue 版本 shim +# esbuild —— Nuxt / Vite 底层 +allowBuilds: + esbuild: true + better-sqlite3: true + vue-demi: true + +# 依赖严格隔离(不开启 shamefully-hoist / nodeLinker: hoisted)。 +# +# 重要:docs 包把 nuxt 精确锁在 4.4.8,不要放宽到 ^4.4.8 或升级到 4.5+。 +# 原因见下表(@nuxt/vite-builder 是决定实际 Vite 版本的那个包): +# 4.4.8 → vite ^7.3.3 (Rollup 引擎,可用) +# 4.5.0 → vite ^8.1.4 (Rolldown) +# 4.6.0 → vite ^8.3.2 (Rolldown) +# Vite 8 换成 Rolldown 后,在 Windows 下无法解析 Nitro 生成的 +# "file:///D:/..." 虚拟模块 import,会把 #nitro-internal-virtual/* 误判为外部依赖, +# 导致 Nuxt 的 internal/manifest 与 internal/precomputed 都拿不到值,页面一律 500 +# (报错:Either manifest or precomputed data must be provided)。 +# Docus 官方 starter 声明的正是 nuxt ^4.4.8,所以锁 4.4.8 与 Docus 完全兼容。 diff --git a/code/g3soft-libs/scripts/gen-api.mjs b/code/g3soft-libs/scripts/gen-api.mjs new file mode 100644 index 00000000..6a9e44a6 --- /dev/null +++ b/code/g3soft-libs/scripts/gen-api.mjs @@ -0,0 +1,95 @@ +#!/usr/bin/env node +/** + * 从组件源码生成 API 数据。 + * + * 用 vue-docgen-api 解析 packages/ui/src 下的 .vue 文件, + * 提取 props / events / slots 及其 JSDoc 注释,输出到 docs/data/api/<组件名>.json, + * 由文档站的 组件读取渲染。 + * + * 这样 API 表格永远与源码一致,禁止手写。 + * 源码改动后执行:pnpm gen:api + */ +import { mkdir, readdir, writeFile } from 'node:fs/promises' +import { basename, dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { parse } from 'vue-docgen-api' + +const root = fileURLToPath(new URL('..', import.meta.url)) +const uiSrc = join(root, 'packages/ui/src') +const outDir = join(root, 'docs/data/api') + +/** 递归收集所有 .vue 组件文件 */ +async function findComponents(dir) { + const found = [] + for (const entry of await readdir(dir, { withFileTypes: true })) { + const full = join(dir, entry.name) + if (entry.isDirectory()) { + found.push(...(await findComponents(full))) + } else if (entry.name.endsWith('.vue')) { + found.push(full) + } + } + return found +} + +/** packages/ui/src/button/Button.vue -> button */ +function toKey(file) { + return basename(dirname(file)) +} + +/** docgen 给出的值可能带引号,统一剥掉 */ +function clean(text = '') { + return String(text).replace(/^['"]|['"]$/g, '') +} + +/** 把说明文字压成单行,避免表格里出现换行 */ +function oneLine(text = '') { + return String(text).replace(/\s+/g, ' ').trim() +} + +function mapMember(item) { + return { + name: item.name, + description: oneLine(item.description), + type: item.type?.name ?? '', + defaultValue: item.defaultValue ? clean(item.defaultValue.value) : '', + } +} + +async function main() { + const files = await findComponents(uiSrc) + const results = [] + + for (const file of files) { + const info = await parse(file) + const key = toKey(file) + + results.push([ + key, + { + displayName: info.displayName || key, + description: oneLine(info.description), + props: (info.props ?? []).map(mapMember), + events: (info.events ?? []).map(mapMember), + slots: (info.slots ?? []).map((slot) => ({ + name: slot.name, + description: oneLine(slot.description), + })), + }, + ]) + } + + await mkdir(outDir, { recursive: true }) + + for (const [key, doc] of results) { + await writeFile(join(outDir, `${key}.json`), `${JSON.stringify(doc, null, 2)}\n`, 'utf-8') + console.log( + `✓ ${key.padEnd(12)} props=${doc.props.length} events=${doc.events.length} slots=${doc.slots.length}`, + ) + } +} + +main().catch((error) => { + console.error('[gen-api] 失败:', error) + process.exit(1) +}) diff --git a/code/g3soft-libs/shot-btn.png b/code/g3soft-libs/shot-btn.png new file mode 100644 index 00000000..bf6b1540 Binary files /dev/null and b/code/g3soft-libs/shot-btn.png differ diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/SKILL.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/SKILL.md deleted file mode 100644 index 2ce6e71f..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/SKILL.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -name: nuxt-ui -description: Build UIs with @nuxt/ui v4 — 125+ accessible Vue components with Tailwind CSS theming. Use when creating interfaces, customizing themes to match a brand, building forms, or composing layouts like dashboards, docs sites, and chat interfaces. ---- - -# Nuxt UI - -Vue component library built on [Reka UI](https://reka-ui.com/) + [Tailwind CSS](https://tailwindcss.com/) + [Tailwind Variants](https://www.tailwind-variants.org/). Works with Nuxt, Vue (Vite), Laravel (Vite + Inertia), and AdonisJS (Vite + Inertia). - -## MCP Server - -For component API details (props, slots, events, full documentation, examples), use the [Nuxt UI MCP server](https://ui.nuxt.com/docs/getting-started/ai/mcp). If not already configured, add it: - -**Cursor** — `.cursor/mcp.json`: - -```json -{ "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nuxt.com/mcp" } } } -``` - -**Claude Code**: - -```bash -claude mcp add --transport http nuxt-ui https://ui.nuxt.com/mcp -``` - -Key MCP tools: -- `search-components` — find components by name, category, or intent (no params = list all) -- `search-composables` — find composables by name or description (no params = list all) -- `search-icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names -- `get-component` — full component documentation with usage examples -- `get-component-metadata` — props, slots, events (lightweight, no docs content) -- `get-example` — real-world code examples - -When you need to know **what a component accepts** or **how its API works**, use the MCP. This skill teaches you **when to use which component** and **how to build well**. - -## Core rules (always apply) - -1. **Always wrap the app in `UApp`** — required for toasts, tooltips, and programmatic overlays. Accepts a `locale` prop for i18n. -2. **Always use semantic colors** — `text-default`, `bg-elevated`, `border-muted`, etc. Never use raw Tailwind palette colors like `text-gray-500`. -3. **Read generated theme files for slot names** — Nuxt: `.nuxt/ui/.ts`, Vue: `node_modules/.nuxt-ui/ui/.ts`. These show every slot, variant, and default class for any component. -4. **Override priority** (highest wins): `ui` prop / `class` prop → global config → theme defaults. -5. **Icons use `i-{collection}-{name}` format** — `lucide` is the default collection. Use the MCP `search-icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org). - -## How to use this skill - -Based on the task, load the relevant reference files **before writing any code**. Don't load everything — only what's needed. - -### Reference files - -**Guidelines** — design decisions and conventions: -- [design-system](references/guidelines/design-system.md) — semantic colors, theming, brand customization, variants, the `ui` prop -- [component-selection](references/guidelines/component-selection.md) — decision matrices: when to use Modal vs Slideover, Select vs SelectMenu, Toast vs Alert, etc. -- [conventions](references/guidelines/conventions.md) — coding patterns, slot naming, items arrays, composables, keyboard shortcuts -- [forms](references/guidelines/forms.md) — form validation, field layout, error handling, Standard Schema - -**Layouts** — full page structure patterns: -- [landing](references/layouts/landing.md) — landing pages, blog, changelog, pricing -- [dashboard](references/layouts/dashboard.md) — admin UI with sidebar and panels -- [docs](references/layouts/docs.md) — documentation sites with navigation and TOC -- [chat](references/layouts/chat.md) — AI chat with Vercel AI SDK -- [editor](references/layouts/editor.md) — rich text editor with toolbars - -**Recipes** — complete patterns for common tasks: -- [data-tables](references/recipes/data-tables.md) — tables with filters, pagination, sorting, selection -- [auth](references/recipes/auth.md) — login, signup, forgot password forms -- [overlays](references/recipes/overlays.md) — modals, slideovers, drawers, command palette -- [navigation](references/recipes/navigation.md) — headers, sidebars, breadcrumbs, tabs - -**Quick reference:** -- [components](references/components.md) — categorized component index for finding the right component name - -### Routing table - -| Task | Load these references | -|---|---| -| Build a landing page | design-system, conventions, landing | -| Build a dashboard / admin UI | conventions, component-selection, dashboard | -| Add a settings page | conventions, forms | -| Create a login / signup form | conventions, forms, auth | -| Display data in a table | conventions, component-selection, data-tables | -| Customize theme / brand colors | design-system | -| Add a chat interface | conventions, chat | -| Add a modal, slideover, or drawer | conventions, component-selection, overlays | -| Build site navigation | conventions, component-selection, navigation | -| Build a documentation site | conventions, docs | -| Render markdown | component-selection, components, docs | -| Add a rich text editor | conventions, editor | -| General UI work | conventions, component-selection | - -## Installation - -### Nuxt - -```bash -pnpm add @nuxt/ui tailwindcss -``` - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui'], - css: ['~/assets/css/main.css'] -}) -``` - -```css -/* app/assets/css/main.css */ -@import "tailwindcss"; -@import "@nuxt/ui"; -``` - -```vue - - -``` - -### Vue (Vite) - -```bash -pnpm add @nuxt/ui tailwindcss -``` - -```ts -// vite.config.ts -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import ui from '@nuxt/ui/vite' - -export default defineConfig({ - plugins: [ - vue(), - ui() - ] -}) -``` - -```ts -// src/main.ts -import './assets/css/main.css' -import { createApp } from 'vue' -import { createRouter, createWebHistory } from 'vue-router' -import ui from '@nuxt/ui/vue-plugin' -import App from './App.vue' - -const app = createApp(App) -const router = createRouter({ - routes: [], - history: createWebHistory() -}) - -app.use(router) -app.use(ui) -app.mount('#app') -``` - -```css -/* src/assets/css/main.css */ -@import "tailwindcss"; -@import "@nuxt/ui"; -``` - -```vue - - -``` - -> Add `class="isolate"` to your root `
` in `index.html`. -> For Inertia: use `ui({ router: 'inertia' })` in `vite.config.ts`. diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/components.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/components.md deleted file mode 100644 index 6f108bda..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/components.md +++ /dev/null @@ -1,245 +0,0 @@ -# Components - -Quick-reference index of all 125+ components. For full API docs (props, slots, events, examples), use the MCP `get-component` or `get-component-metadata` tools. - -## Layout - -| Component | Purpose | -|---|---| -| `UApp` | **Required** root wrapper — toasts, tooltips, overlays, i18n | -| `UHeader` | Responsive header with mobile menu | -| `UFooter` | Footer with left/right/top/bottom slots | -| `UFooterColumns` | Multi-column footer with link groups | -| `UMain` | Main content area | -| `UContainer` | Centered max-width container | -| `USplitter` | Resizable panels separated by draggable handles | -| `ULink` | Enhanced link — NuxtLink/RouterLink with active states | - -## Element - -| Component | Purpose | -|---|---| -| `UButton` | Buttons — links, actions, icons, loading states | -| `UBadge` | Labels, tags, status indicators | -| `UAvatar` | User photos, initials, icons | -| `UAvatarGroup` | Stacked avatars with `max` limit | -| `UIcon` | Iconify icons (`i-{collection}-{name}`) | -| `UCard` | Bordered container with header/body/footer | -| `UAlert` | Inline messages — info, warning, error, success | -| `UBanner` | App-wide sticky announcement bar | -| `UChip` | Notification dot overlay on children | -| `UKbd` | Keyboard key display | -| `USeparator` | Divider line with optional label | -| `USkeleton` | Loading placeholder | -| `UProgress` | Progress bar | -| `UProgressGroup` | Segmented progress bar with a list of items | -| `UToast` | Toast notification (shown via `useToast`) | -| `UCalendar` | Date calendar (single, range, multiple) | -| `UCollapsible` | Animated expand/collapse | -| `UFieldGroup` | Group form inputs horizontally | -| `UMarquee` | Scrolling content ticker | -| `UCarousel` | Image/content carousel with autoplay | -| `UEmpty` | Empty state placeholder with icon, title, actions | -| `UError` | Error display with retry action | -| `UScrollArea` | Scrollable area with custom scrollbar | -| `UTimeline` | Timeline display for events and activity | -| `UUser` | User display — avatar + name + description | -| `UTheme` | Theme provider — scoped color overrides for children | - -## Form - -| Component | Purpose | -|---|---| -| `UAuthForm` | Pre-built auth form with social providers | -| `UInput` | Text input — text, email, password, search | -| `UTextarea` | Multi-line text with autoresize | -| `USelect` | Native-like dropdown for small lists | -| `USelectMenu` | Rich searchable dropdown, multi-select, groups | -| `UInputMenu` | Autocomplete / combobox | -| `UInputNumber` | Numeric input with +/- controls | -| `UInputDate` | Date picker with calendar | -| `UInputTime` | Time picker (12/24h) | -| `UInputTags` | Tag/chip input | -| `UPinInput` | Verification code input | -| `UCheckbox` | Single boolean checkbox | -| `UCheckboxGroup` | Multiple checkboxes | -| `URadioGroup` | Radio button group | -| `USwitch` | Toggle switch | -| `USlider` | Range slider | -| `UColorPicker` | Color picker (hex/rgb/hsl) | -| `UFileUpload` | File upload (button or drop area) | -| `UForm` | Validation wrapper with Standard Schema | -| `UFormField` | Field wrapper with label, hint, errors | - -## Overlay - -| Component | Purpose | -|---|---| -| `UModal` | Centered dialog — confirmations, forms | -| `USlideover` | Side panel — details, editing | -| `UDrawer` | Bottom sheet — mobile actions | -| `UPopover` | Contextual popup attached to trigger | -| `UTooltip` | Hover/focus hint (non-interactive) | -| `UContextMenu` | Right-click menu | -| `UCommandPalette` | Search + keyboard navigation (Cmd+K) | - -## Navigation - -| Component | Purpose | -|---|---| -| `USidebar` | Standalone sidebar with header/body/footer | -| `UNavigationMenu` | Primary nav — horizontal or vertical | -| `UTabs` | Tab switcher within a page | -| `UBreadcrumb` | Location hierarchy | -| `UDropdownMenu` | Action menu on a trigger | -| `UPagination` | Page navigation | -| `UStepper` | Multi-step wizard | -| `UAccordion` | Collapsible sections | - -## Data - -| Component | Purpose | -|---|---| -| `UTable` | Data table (TanStack Table) with sorting, selection, pinning | -| `UTree` | Hierarchical tree view | - -## Dashboard - -| Component | Purpose | -|---|---| -| `UDashboardGroup` | Root dashboard wrapper | -| `UDashboardSidebar` | Resizable, collapsible sidebar | -| `UDashboardPanel` | Content panel with header/body/footer | -| `UDashboardNavbar` | Panel header bar | -| `UDashboardToolbar` | Filter/action bar below navbar | -| `UDashboardResizeHandle` | Resize handle between panels | -| `UDashboardSidebarToggle` | Mobile sidebar toggle button | -| `UDashboardSearchButton` | Search button for sidebar | -| `UDashboardSearch` | Dashboard-level search overlay | -| `UDashboardSidebarCollapse` | Collapse button for sidebar | - -## Page (marketing) - -| Component | Purpose | -|---|---| -| `UPage` | Multi-column layout with left/right sidebars | -| `UPageHero` | Hero section — title, description, links, media | -| `UPageSection` | Content section with features grid | -| `UPageCTA` | Call to action block | -| `UPageHeader` | Page title and description | -| `UPageBody` | Main content area | -| `UPageGrid` | Card grid layout | -| `UPageColumns` | Multi-column layout | -| `UPageCard` | Content card for grids | -| `UPageFeature` | Feature item | -| `UPageLogos` | Logo cloud | -| `UPageAside` | Sticky sidebar wrapper | -| `UPageAnchors` | Simple anchor links | -| `UPageLinks` | Related resource links | -| `UPageList` | List layout for page items | - -## Blog & Changelog - -| Component | Purpose | -|---|---| -| `UBlogPosts` | Blog post grid | -| `UBlogPost` | Individual post card | -| `UChangelogVersions` | Changelog list | -| `UChangelogVersion` | Individual changelog entry | - -## Pricing - -| Component | Purpose | -|---|---| -| `UPricingPlans` | Pricing plan cards | -| `UPricingPlan` | Individual pricing plan card | -| `UPricingTable` | Feature comparison table | - -## Prose — Base Typography - -Standard Markdown elements auto-resolved by Comark/Content/MDC. No `::` prefix needed — they map directly from markdown syntax (`# Heading` → `ProseH1`, `**bold**` → `ProseStrong`, etc.). Themed via `appConfig.ui.prose.`. - -| Component | Renders | Notable | -|---|---|---| -| `H1` `H2` `H3` `H4` | Headings | H1–H3 get anchor links + TOC entries | -| `P` | Paragraph | | -| `A` | Link | External links get target/rel handling | -| `Strong` | Bold | | -| `Em` | Italic | | -| `Blockquote` | Blockquote | | -| `Hr` | Horizontal rule | | -| `Ul` `Ol` `Li` | Lists | Supports nesting and mixed lists | -| `Table` `Thead` `Tbody` `Tr` `Th` `Td` | Tables | | -| `Img` | Image | Zoom on click (`:zoom="false"` to disable), `@nuxt/image` support | -| `Pre` | Code block | Copy button, filename + icon, line highlighting (`{2,4-6}`), diff | -| `Code` | Inline code | `color` and `lang` props | - -## Prose — Feature Components - -Nuxt UI-specific Prose components. In markdown files they are used **without the `Prose` prefix** (e.g. `::callout`, `::steps`). In Vue they are referenced as `ProseCallout`, `ProseSteps`, etc. Comark resolves them automatically when `@nuxt/ui` is installed. - -Nuxt UI also registers shorthand aliases for `Callout`: `::note`, `::tip`, `::warning`, `::caution` (preset `color` + `icon`). - -| Component | Purpose | -|---|---| -| `Callout` | Highlighted note/warning/tip (`color`, `icon`, `to`) | -| `Badge` | Inline badge/tag | -| `Kbd` | Keyboard key | -| `Icon` | Inline Iconify icon | -| `Prompt` | Terminal prompt block | -| `Card` `CardGroup` | Content card and card grid | -| `Steps` | Numbered step list (`level` prop sets heading depth) | -| `Tabs` `TabsItem` | Tabbed content (`sync` for localStorage, `hash` for scroll-on-change) | -| `Accordion` `AccordionItem` | Collapsible accordion sections | -| `Collapsible` | Single collapsible section | -| `Field` `FieldGroup` | Form field display | -| `CodeGroup` | Tabbed code blocks | -| `CodeCollapse` | Collapsible code block | -| `CodeIcon` | File-type icon in code headers | -| `CodePreview` | Code + live rendered preview side by side | -| `CodeTree` | File tree display | -| `Script` | Script injection | - -## Content (Nuxt Content) - -| Component | Purpose | -|---|---| -| `UContentNavigation` | Sidebar navigation from content | -| `UContentToc` | Table of contents | -| `UContentSurround` | Prev/next navigation | -| `UContentSearch` | Search command palette | -| `UContentSearchButton` | Trigger for content search | - -## Chat (AI) - -| Component | Purpose | -|---|---| -| `UChatMessages` | Scrollable message list | -| `UChatMessage` | Individual message bubble | -| `UChatReasoning` | Collapsible AI reasoning block | -| `UChatTool` | Tool invocation status | -| `UChatShimmer` | Streaming text animation | -| `UChatPrompt` | Enhanced textarea for prompts | -| `UChatPromptSubmit` | Submit button with status | -| `UChatPalette` | Chat layout for overlays | - -## Editor - -| Component | Purpose | -|---|---| -| `UEditor` | Rich text editor (JSON/HTML/Markdown) | -| `UEditorToolbar` | Toolbar (fixed/bubble/floating) | -| `UEditorDragHandle` | Block drag-and-drop | -| `UEditorSuggestionMenu` | Slash command menu | -| `UEditorMentionMenu` | @ mention menu | -| `UEditorEmojiMenu` | Emoji picker | - -## Color Mode - -| Component | Purpose | -|---|---| -| `UColorModeButton` | Toggle button (light/dark) | -| `UColorModeSwitch` | Toggle switch (light/dark) | -| `UColorModeSelect` | Dropdown (light/dark/system) | -| `UColorModeAvatar` | Avatar that changes with color mode | -| `UColorModeImage` | Image that changes with color mode | diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/component-selection.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/component-selection.md deleted file mode 100644 index c2d1ce14..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/component-selection.md +++ /dev/null @@ -1,124 +0,0 @@ -# Component Selection - -Decision matrices for choosing the right component. When in doubt, use the MCP `search-components` tool. - -## Overlays - -| Need | Component | Why | -|---|---|---| -| Confirmation dialog, focused task, form | `UModal` | Blocks page interaction, centered, draws focus | -| Detail panel, settings, secondary content | `USlideover` | Slides from edge, doesn't feel as interruptive as modal | -| Mobile-first bottom sheet | `UDrawer` | Natural mobile pattern, swipe to dismiss | -| Contextual info attached to a trigger | `UPopover` | No backdrop, positioned relative to trigger | -| Simple hover hint | `UTooltip` | Non-interactive, hover/focus only | - -### Rules -- Use `UModal` for destructive confirmations ("Are you sure you want to delete?") -- Use `USlideover` for detail views in dashboards (email preview, user profile) -- Use `UDrawer` for mobile navigation or action sheets -- Modal and Slideover support `mode="drawer"` for automatic mobile drawer behavior -- For programmatic overlays, use `useOverlay()` instead of `v-model:open` -- Never put interactive content (buttons, links) inside `UTooltip` - -## Navigation - -| Need | Component | Why | -|---|---|---| -| Primary site/app navigation | `UNavigationMenu` | Horizontal (header) or vertical (sidebar) | -| Switch between views on same page | `UTabs` | Content stays on page, no route change needed | -| Show current location in hierarchy | `UBreadcrumb` | Nested page structures | -| Search + keyboard-driven navigation | `UCommandPalette` | Power users, global search | -| Contextual actions on a trigger element | `UDropdownMenu` | Right-click menus, action buttons | -| Step-by-step process | `UStepper` | Multi-step forms, wizards | - -### Rules -- Use `UNavigationMenu` with `orientation="vertical"` in sidebars, default horizontal in headers -- Use `UTabs` when switching views that don't need their own URL -- Use route-based navigation (`to` prop) when views should have shareable URLs -- `UCommandPalette` is typically opened via `Cmd+K` shortcut — use `defineShortcuts` to wire it up - -## Inputs - -| Need | Component | Why | -|---|---|---| -| Small fixed list (< 10 items) | `USelect` | Native-like, simple, lightweight | -| Searchable list, multiple selection, groups | `USelectMenu` | Rich dropdown with search, multi-select, grouped items | -| Autocomplete / combobox (type + select) | `UInputMenu` | User can type freely AND pick from suggestions | -| Free text entry | `UInput` | Plain text, email, password, search | -| Multi-line text | `UTextarea` | With `autoresize` and `maxrows` | -| Numeric value with +/- controls | `UInputNumber` | Min/max/step constraints | -| Date selection | `UInputDate` | Calendar dropdown, supports ranges | -| Time selection | `UInputTime` | Hour/minute picker, 12/24 hour | -| Tags / multi-value free text | `UInputTags` | Chip-style input with max limit | -| Verification code | `UPinInput` | Fixed-length code entry | -| Boolean toggle | `USwitch` | On/off, enable/disable | -| Boolean checkbox | `UCheckbox` | Single option with label | -| Multiple choices from a list | `UCheckboxGroup` | Multiple selection, vertical or horizontal | -| Single choice from a list (visible) | `URadioGroup` | All options visible, one selected | -| Range value | `USlider` | Min/max with visual track | -| Color value | `UColorPicker` | Hex/RGB/HSL picker | -| File upload | `UFileUpload` | Button or drop area variants | - -### Rules -- Use `UAuthForm` for login/signup pages — handles fields, social providers, validation, and layout out of the box -- Use `USelect` for short, known lists (country, status, role) -- Use `USelectMenu` when the list is long or needs search -- Use `UInputMenu` when the user might want to type a value that's not in the list -- Wrap all form inputs in `UFormField` for labels, descriptions, hints, and validation errors -- Group related inline inputs with `UFieldGroup` - -## Feedback - -| Need | Component | Why | -|---|---|---| -| Ephemeral notification after action | `useToast()` | Auto-dismisses, stacks, non-blocking | -| Inline persistent message | `UAlert` | Stays visible, in-page context | -| App-wide announcement | `UBanner` | Sticky top bar, dismissible | -| Loading state | `USkeleton` | Placeholder shimmer while loading | -| Progress indicator | `UProgress` | Determinate or indeterminate progress | -| Breakdown of a total | `UProgressGroup` | One bar split into colored segments that add up to `max` | - -### Rules -- Use `useToast()` for action feedback: "Item saved", "Email sent", "Error occurred" -- Use `UAlert` for contextual warnings in forms or sections -- Use `UBanner` for site-wide messages (maintenance, new feature) -- Never use a toast for information the user needs to act on — use an alert or modal instead - -## Markdown - -When rendering Markdown (for instance with Comark), **prefer Prose components** — they are styled and tuned for Markdown contexts. Generic Nuxt UI components can also be used. `` (or ``) auto-resolves `ProseX` components when `@nuxt/ui` is installed. In Markdown, the `Prose` prefix can be omitted (`::callout`, `::steps`, etc.). - -| Need | Use | Not | -|---|---|---| -| Note / warning / tip | `Callout` | `UAlert` | -| Tabbed content | `Tabs` + `TabsItem` | `UTabs` | -| Step-by-step list | `Steps` | custom list | -| Content card grid | `Card` + `CardGroup` | `UCard` | -| Collapsible section | `Collapsible` / `Accordion` | `UCollapsible` / `UAccordion` | -| Tabbed code blocks | `CodeGroup` | manual tabs | - -### Rules -- Prose components use native Vue slots — Comark maps named `#slot` blocks directly to `` -- Theme via `appConfig.ui.prose.` using the same override pattern as other Nuxt UI components -- `Callout` colors: `neutral` (default), `primary`, `secondary`, `info`, `success`, `warning`, `error` - -## Layout containers - -| Need | Component | Why | -|---|---|---| -| Grouped content with header/body/footer | `UCard` | Bordered/shadow container with slots | -| Rich content card with icon, badge, links | `UPageCard` | Extended card for grids — supports icon, badge, highlight, links | -| Marketing page section | `UPageSection` | Full-width section with headline, title, features | -| Page hero | `UPageHero` | Title + description + links + optional media | -| Call to action | `UPageCTA` | Highlighted section with action links | -| Feature grid | `UPageGrid` + `UPageCard` | Multi-column card grid | -| Centered content wrapper | `UContainer` | Max-width container | -| Collapsible section | `UCollapsible` | Animated expand/collapse | -| Accordion (multiple collapsibles) | `UAccordion` | FAQ, grouped collapsible content | -| Resizable side-by-side panes | `USplitter` | IDE-style layouts, resizable sidebars | - -### Rules -- Don't overuse `UCard` — plain content with spacing is often better than wrapping everything in cards -- Use `UPageCard` instead of `UCard` when you need icon, badge, highlight, or links — it's designed for feature grids and landing pages -- Use `UPageSection` for marketing/landing page sections, not for app UI -- Use `UContainer` inside `UDashboardPanel` body for consistent content width diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/conventions.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/conventions.md deleted file mode 100644 index c1aa29eb..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/conventions.md +++ /dev/null @@ -1,376 +0,0 @@ -# Conventions - -Coding patterns specific to Nuxt UI. - -## Auto-registered modules - -Nuxt UI automatically registers `@nuxt/icon`, `@nuxt/fonts`, and `@nuxtjs/color-mode`. Do **not** add them to your `modules` array. Configure them via root-level keys in `nuxt.config.ts`: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui'], - icon: { /* @nuxt/icon options */ }, - fonts: { /* @nuxt/fonts options */ }, - colorMode: { /* @nuxtjs/color-mode options */ } -}) -``` - -Disable any of them: `ui: { fonts: false }`, `ui: { colorMode: false }`. - -## Content module integration - -When using `@nuxt/content`, it **must** come after `@nuxt/ui` in the `modules` array — otherwise prose components won't be available: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui', '@nuxt/content'] -}) -``` - -Add `@source` in your CSS so Tailwind generates classes used in markdown/MDC: - -```css -/* app/assets/css/main.css */ -@import "tailwindcss"; -@import "@nuxt/ui"; - -@source "../../../content/**/*"; -``` - -Use `mapContentNavigation` to transform content navigation for components like `UBreadcrumb`: - -```ts -import { mapContentNavigation } from '@nuxt/ui/utils/content' -import { findPageBreadcrumb } from '@nuxt/content/utils' - -const breadcrumb = computed(() => - mapContentNavigation(findPageBreadcrumb(navigation.value, page.value?.path)) -) -``` - -## IDE setup - -Recommended `.vscode/settings.json` for Tailwind IntelliSense autocomplete with Nuxt UI: - -```json -{ - "files.associations": { "*.css": "tailwindcss" }, - "editor.quickSuggestions": { "strings": "on" }, - "tailwindCSS.classAttributes": ["class", "ui"], - "tailwindCSS.classFunctions": ["defineAppConfig"] -} -``` - -## UApp wrapper - -Always wrap your app in `UApp` — it provides: -- Toast container (`useToast`) -- Tooltip provider -- Programmatic overlay context (`useOverlay`) -- i18n locale support - -```vue - - - -``` - -## Icons - -Nuxt UI registers `@nuxt/icon` automatically. Format: `i-{collection}-{name}`. Prefer `lucide` collection. - -```vue - - - -``` - -Install collections locally for reliable SSR and best performance: - -```bash -pnpm i @iconify-json/lucide -pnpm i @iconify-json/simple-icons -``` - -Custom local collections (Nuxt only): - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - icon: { - customCollections: [{ - prefix: 'custom', - dir: './app/assets/icons' - }] - } -}) -``` - -### Default icon overrides - -Components like `Modal`, `Select`, `Accordion`, etc. use default icons from `appConfig.ui.icons`. Override them globally: - -```ts -// app.config.ts -export default defineAppConfig({ - ui: { - icons: { - loading: 'i-lucide-refresh-cw', - close: 'i-lucide-x', - check: 'i-lucide-check', - chevronDown: 'i-lucide-chevron-down', - chevronRight: 'i-lucide-chevron-right', - arrowLeft: 'i-lucide-arrow-left', - arrowRight: 'i-lucide-arrow-right' - } - } -}) -``` - -## Slot patterns - -Most components follow consistent slot naming: - -| Slot | Used by | Purpose | -|---|---|---| -| `#header` | Card, Modal, Slideover, DashboardPanel | Top section | -| `#body` | DashboardPanel | Scrollable content area | -| `#footer` | Card, Modal, Slideover, DashboardPanel | Bottom section | -| `#left` | Page, DashboardNavbar | Left sidebar or content | -| `#right` | Page, DashboardNavbar, Header | Right sidebar or content | -| `#leading` | Input, Button, Alert | Before main content (icon area) | -| `#trailing` | Input, Button | After main content (icon area) | -| `#content` | Modal, Slideover, Popover, Tooltip | Full content override | -| `#default` | Most components | Main content area | - -## Items arrays - -Many components accept an `items` prop. Two patterns: - -**Flat array** — plain list: - -```ts -const items = [ - { label: 'Edit', icon: 'i-lucide-pencil' }, - { label: 'Delete', icon: 'i-lucide-trash', color: 'error' } -] -``` - -**Nested array** — groups with automatic separators between them: - -```ts -const items = [ - [ - { label: 'Edit', icon: 'i-lucide-pencil' }, - { label: 'Duplicate', icon: 'i-lucide-copy' } - ], - [ - { label: 'Delete', icon: 'i-lucide-trash', color: 'error' } - ] -] -``` - -Components supporting nested arrays: `UDropdownMenu`, `UContextMenu`, `UCommandPalette`, `UNavigationMenu`. - -## Composables - -### useToast - -```ts -const toast = useToast() - -toast.add({ - title: 'Success', - description: 'Item saved', - color: 'success', - icon: 'i-lucide-check-circle', - duration: 5000, - actions: [{ label: 'Undo', onClick: () => {} }] -}) - -toast.remove('toast-id') -toast.clear() -``` - -### useOverlay - -Programmatic modals, slideovers, drawers — no template `v-model` needed. See [overlays recipe](../recipes/overlays.md) for full patterns. - -```ts -const overlay = useOverlay() -const modal = overlay.create(MyComponent) -const instance = modal.open({ title: 'Confirm?' }) -if (await instance.result) { /* confirmed */ } -``` - -### defineShortcuts - -```ts -defineShortcuts({ - meta_k: () => openSearch(), - escape: () => close(), - meta_enter: { - handler: () => submit(), - whenever: [isFormValid] - } -}) -``` - -Keys: `meta` (Cmd/Ctrl), `ctrl`, `alt`, `shift`. Separator: `_`. - -### extractShortcuts - -Wire up keyboard shortcuts from menu items: - -```ts -const items = [ - { label: 'New file', kbds: ['meta', 'n'], onSelect: () => newFile() }, - { label: 'Save', kbds: ['meta', 's'], onSelect: () => save() } -] - -defineShortcuts(extractShortcuts(items)) -``` - -### Internationalization (i18n) - -Nuxt UI supports 50+ locales. Set the locale on `UApp` — all components inherit it. - -#### Static locale - -```vue - - - -``` - -#### Extend a built-in locale - -`extendLocale` is auto-imported. Override specific messages or the `code` (affects date/time formatting in Calendar, InputDate, InputTime): - -```ts -import { en } from '@nuxt/ui/locale' - -const locale = extendLocale(en, { - code: 'en-AU', - messages: { - commandPalette: { placeholder: 'Search a component...' } - } -}) -``` - -#### Custom locale from scratch - -```ts -import type { Messages } from '@nuxt/ui' - -const locale = defineLocale({ - name: 'My locale', - code: 'en', - dir: 'ltr', - messages: { - // all component message keys - } -}) -``` - -#### Dynamic locale with @nuxtjs/i18n - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui', '@nuxtjs/i18n'], - i18n: { - locales: [ - { code: 'en', name: 'English' }, - { code: 'fr', name: 'Français' }, - { code: 'ar', name: 'العربية' } - ] - } -}) -``` - -```vue - - - -``` - -Each locale has a `dir` property (`'ltr'` or `'rtl'`). `UApp` uses it to set directionality on all components. Use `useHead` to propagate `lang` and `dir` to the `` element. - -## Color mode - -Nuxt UI registers `@nuxtjs/color-mode` automatically. Built-in components for switching: -- `UColorModeButton` — single button toggle (light/dark) -- `UColorModeSwitch` — toggle switch -- `UColorModeSelect` — dropdown with system/light/dark options -- `UColorModeAvatar` — displays different avatar per mode -- `UColorModeImage` — displays different image per mode - -For custom color mode UI, use `useColorMode` with `ClientOnly` to avoid hydration mismatch: - -```vue - - - -``` - -## Official templates - -Bootstrap a project from a template instead of starting from scratch: - -```bash -npx nuxi@latest init -t ui # Starter -npx nuxi@latest init -t ui/dashboard # Dashboard -npx nuxi@latest init -t ui/docs # Docs (Nuxt Content) -npx nuxi@latest init -t ui/landing # Landing page -npx nuxi@latest init -t ui/saas # SaaS (landing + pricing + docs + blog) -npx nuxi@latest init -t ui/chat # AI chat (Vercel AI SDK) -npx nuxi@latest init -t ui/editor # Rich text editor -npx nuxi@latest init -t ui/portfolio # Portfolio -npx nuxi@latest init -t ui/changelog # Changelog -npx nuxi@latest init -t ui/calendar # Calendar -``` - -## Responsive patterns - -- Dashboard sidebar hides on mobile, shows a slideover/drawer via `UDashboardSidebar` `mode` prop -- `UHeader` body slot is the mobile menu content (shown when hamburger is tapped) -- Most components handle responsiveness automatically — avoid manual breakpoint classes unless needed -- Use `UPageAside` for sidebars that should hide below `lg` breakpoint diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/design-system.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/design-system.md deleted file mode 100644 index 561dc411..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/design-system.md +++ /dev/null @@ -1,378 +0,0 @@ -# Design System - -## Semantic colors - -Nuxt UI uses 7 semantic colors. Never use raw Tailwind palette colors in components — always use these semantic names. - -| Color | Default | When to use | -|---|---|---| -| `primary` | green | CTAs, active states, brand accent, links | -| `secondary` | blue | Secondary actions, complementary highlights | -| `success` | green | Success messages, confirmations, positive states | -| `info` | blue | Informational alerts, tips, neutral highlights | -| `warning` | yellow | Warnings, caution states, pending actions | -| `error` | red | Errors, destructive actions, validation failures | -| `neutral` | slate | Text, borders, backgrounds, disabled states, chrome | - -### Choosing colors for components - -- **Primary action** on a page (submit, save, confirm) → `color="primary"` -- **Secondary actions** (cancel, back, alternative) → `color="neutral"` with `variant="outline"` or `"ghost"` -- **Destructive actions** (delete, remove) → `color="error"` -- **Status indicators** → match the semantic meaning: `success`, `warning`, `error`, `info` -- **Navigation and chrome** → `color="neutral"` - -### Configuring colors - -```ts -// Nuxt — app.config.ts -export default defineAppConfig({ - ui: { - colors: { - primary: 'indigo', - secondary: 'violet', - success: 'emerald', - error: 'rose', - neutral: 'zinc' - } - } -}) -``` - -```ts -// Vue — vite.config.ts -ui({ - ui: { - colors: { primary: 'indigo', secondary: 'violet', neutral: 'zinc' } - } -}) -``` - -Only colors that exist in your theme work — either Tailwind's defaults or custom colors defined with `@theme`. - -Available color palettes: -- **Standard Tailwind**: red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose -- **Neutral palettes** (for `neutral` key — pick one that matches the aesthetic): - - `slate` — cool blue-gray, professional (default) - - `gray` — true neutral, clean - - `zinc` — slightly cool, modern, techy - - `neutral` — perfectly balanced - - `stone` — warm gray, earthy - - `taupe` — warm brown-gray, sophisticated - - `mauve` — purple-tinted gray, elegant - - `mist` — soft blue-gray, airy - - `olive` — green-tinted gray, natural - -### Adding custom brand colors - -1. Define all 11 shades in CSS: - -```css -/* app/assets/css/main.css */ -@theme static { - --color-brand-50: #fef2f2; - --color-brand-100: #fee2e2; - --color-brand-200: #fecaca; - --color-brand-300: #fca5a5; - --color-brand-400: #f87171; - --color-brand-500: #ef4444; - --color-brand-600: #dc2626; - --color-brand-700: #b91c1c; - --color-brand-800: #991b1b; - --color-brand-900: #7f1d1d; - --color-brand-950: #450a0a; -} -``` - -2. Assign it: `ui: { colors: { primary: 'brand' } }` - -### Extending with new semantic color names - -To add a color beyond the 7 defaults (e.g., `tertiary`), register it in `theme.colors`: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - theme: { - colors: ['primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error'] - } - } -}) -``` - -## Semantic utility classes - -Use these everywhere instead of raw palette colors: - -### Text -- `text-default` — primary body text -- `text-muted` — secondary text (descriptions, hints) -- `text-toned` — medium-emphasis text (between muted and default) -- `text-dimmed` — tertiary text (placeholders, disabled) -- `text-highlighted` — emphasized text (headings, important labels) -- `text-inverted` — text on inverted backgrounds (pair with `bg-inverted`) - -### Backgrounds -- `bg-default` — page background -- `bg-muted` — subtle backgrounds (hover states, alternating rows) -- `bg-elevated` — raised surfaces (cards, dropdowns) -- `bg-accented` — accent backgrounds (active states, selected items) -- `bg-inverted` — inverse background (dark on light, light on dark) - -### Borders -- `border-default` — standard borders -- `border-muted` — subtle borders (dividers, separators) -- `border-accented` — accent borders (active states) -- `border-inverted` — inverse borders - -## Variants - -Most components accept a `variant` prop. Choose based on visual weight: - -| Variant | Weight | When to use | -|---|---|---| -| `solid` | Highest | Primary actions, main CTAs | -| `outline` | Medium | Secondary actions, form fields | -| `soft` | Medium-low | Tags, badges, subtle buttons | -| `subtle` | Low | Background highlights, less prominent actions | -| `ghost` | Lowest | Inline actions, icon buttons, navigation items | -| `link` | Lowest | Text-only links inside content | - -### Rules - -- **One solid primary button per view** — everything else should be lower weight -- **Destructive buttons** use `color="error"` but not necessarily `variant="solid"` — use `variant="soft"` or `"outline"` unless it's the primary action on a confirmation dialog -- **Button groups** should use consistent variants — don't mix `solid` and `outline` siblings - -## Customizing components - -### `ui` prop - -Override theme **slots** on a single instance — wins over global config and variants. - -```vue - - -``` - -Rules for `ui` overrides: -- **Prefer `defaultVariants`** over slot class overrides when possible (e.g., changing default button variant/size). -- **Don't duplicate default classes** — check the generated theme file first to see what's already there. -- Border radius defaults come from `--ui-radius`, but you can override with `rounded-*` classes in `ui` or `class` when you need a specific radius on a component. - -### `class` prop - -Override the **root** (or `base`) slot only — simpler than `ui` for single-slot changes. - -```vue - -``` - -### Finding slot names - -Read the generated theme file for any component: -- **Nuxt**: `.nuxt/ui/.ts` -- **Vue**: `node_modules/.nuxt-ui/ui/.ts` - -These files show every available slot name, variant combination, and default class. - -### Global config - -Override `slots`, `variants`, `compoundVariants`, and `defaultVariants` globally in `app.config.ts` (Nuxt) or `vite.config.ts` (Vue): - -```ts -// Nuxt — app.config.ts -export default defineAppConfig({ - ui: { - button: { - slots: { - base: 'font-bold' - }, - compoundVariants: [{ - color: 'neutral', - variant: 'outline', - class: 'ring-default hover:bg-accented' - }], - defaultVariants: { - color: 'neutral', - variant: 'outline' - } - } - } -}) -``` - -Tailwind Variants uses `tailwind-merge` under the hood — conflicting classes are resolved automatically. - -### Replace instead of merge - -Classes from the `ui` prop, the `class` prop, and global config are merged onto the component defaults. To replace them instead, set the slot to a function, which receives the default classes as its argument so you can reuse part of them. - -In global config it replaces the slot's own classes, so `variants` and `compoundVariants` still apply on top. In the `ui` and `class` props it runs after the variants, so it replaces the resolved classes, variants included. - -```vue - -``` - -```ts -// app.config.ts, applies to every instance -export default defineAppConfig({ - ui: { - button: { - slots: { - label: () => 'text-base font-bold' - } - } - } -}) -``` - -### Theme component - -Override theme for a section of the component tree without affecting the rest of the app. Renders no DOM element — uses `provide`/`inject`: - -```vue - - - - -``` - -### Global `defaultVariants` - -Override default `size` and `color` for **all** components at once: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - theme: { - defaultVariants: { - size: 'lg', - color: 'neutral' - } - } - } -}) -``` - -### `theme.transitions` - -Controls whether interactive components get `transition-colors`. Enabled by default. - -```ts -// nuxt.config.ts — disable transitions -export default defineNuxtConfig({ - ui: { - theme: { - transitions: false - } - } -}) -``` - -### `theme.prefix` - -When using Tailwind CSS with a prefix, configure the same prefix in Nuxt UI so component classes match: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - theme: { - prefix: 'tw' - } - } -}) -``` - -```css -/* app/assets/css/main.css */ -@import "tailwindcss" prefix(tw); -@import "@nuxt/ui"; -``` - -### Tree-shaking with `experimental.componentDetection` - -Enable automatic component detection to only generate CSS for components you actually use: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - experimental: { - componentDetection: true - } - } -}) -``` - -For dynamic components (e.g., ``), pass an array of component names to guarantee they're included: - -```ts -componentDetection: ['Modal', 'Dropdown', 'Popover'] -``` - -## CSS `@theme` customization - -Customize Tailwind design tokens in `main.css`: - -### Fonts - -```css -@theme { - --font-sans: 'Public Sans', system-ui, sans-serif; - --font-mono: 'JetBrains Mono', monospace; -} -``` - -In Nuxt, fonts defined here are automatically loaded by `@nuxt/fonts`. - -### Breakpoints - -```css -@theme { - --breakpoint-3xl: 1920px; -} -``` - -## CSS variables - -Nuxt UI exposes CSS variables you can override in `main.css`: - -```css -:root { - --ui-radius: 0.25rem; - --ui-container: 80rem; - --ui-header-height: 4rem; -} -``` - -### Color shade overrides - -Each semantic color defaults to shade 500 in light mode, 400 in dark mode. Override per-mode: - -```css -:root { - --ui-primary: var(--ui-color-primary-700); -} -.dark { - --ui-primary: var(--ui-color-primary-200); -} -``` - -You can use `var(--ui-color--)` to reference shades from the active palette (e.g., `var(--ui-color-neutral-800)` maps to whichever neutral palette is configured). - -### Black/white as primary - -`black` and `white` have no shades, so they can't be used in config. Set them directly: - -```css -:root { - --ui-primary: black; -} -.dark { - --ui-primary: white; -} -``` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/forms.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/forms.md deleted file mode 100644 index 2a3eda14..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/guidelines/forms.md +++ /dev/null @@ -1,233 +0,0 @@ -# Forms - -## Basic pattern - -Nuxt UI forms use `UForm` + `UFormField` + Standard Schema validation (Zod, Valibot, Yup, or Joi). - -```vue - - - -``` - -## Key rules - -- Always use `UFormField` around inputs — it connects validation errors via the `name` prop -- The `name` prop on `UFormField` must match the schema field name exactly -- Use `reactive>({})` for state — `Partial` allows empty initial values -- `@submit` only fires when validation passes -- For nested objects, use dot notation: `name="address.city"` - -## UFormField props - -| Prop | Purpose | -|---|---| -| `name` | Links to schema field for validation errors | -| `label` | Visible label text | -| `description` | Help text below the input | -| `hint` | Right-aligned hint text (e.g., "Optional") | -| `required` | Shows required indicator | -| `size` | Inherits to child input | - -## Field layout patterns - -### Vertical stack (default) - -```vue - - - - - - - - -``` - -### Inline fields with UFieldGroup - -```vue - - - - - - - - -``` - -### Grid layout - -```vue - - - - - - - - - - - -``` - -## Common field patterns - -### Select - -```vue - - - -``` - -### Checkbox - -```vue - - - -``` - -### Radio group - -```vue - - - -``` - -### Switch - -```vue - - - -``` - -### Textarea - -```vue - - - -``` - -### File upload - -```vue - - - - - - - - -``` - -### Date - -```vue - - - - - - - - -``` - -## Programmatic validation - -```vue - - - -``` - -## Form in a modal - -Use `#footer="{ close }"` scoped slot for cancel/submit actions. Wrap the modal body in `UForm` with a `type="submit"` button in the footer so validation runs on submit. - -```vue - - - - -``` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/chat.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/chat.md deleted file mode 100644 index 5ba3b6c8..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/chat.md +++ /dev/null @@ -1,263 +0,0 @@ -# Chat Layout - -Build AI chat interfaces with message streams, reasoning, tool calling, and Vercel AI SDK integration. - -## When to use - -- AI chatbot interfaces -- Customer support chat -- Any conversational UI with streaming responses - -## Setup - -### Install dependencies - -**Nuxt:** - -```bash -pnpm add ai @ai-sdk/gateway @ai-sdk/vue @comark/nuxt -``` - -**Vue (Vite):** - -```bash -pnpm add ai @ai-sdk/gateway @ai-sdk/vue @comark/vue -``` - -### Register Comark module - -**Nuxt:** - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - modules: [ - '@nuxt/ui', - '@comark/nuxt' - ] -}) -``` - -**Vue (Vite):** No module registration needed, import directly from `@comark/vue`. - -> `@comark/nuxt` (or `@comark/vue` for Vue projects) provides the `Comark` component used to render AI responses as streaming Markdown, it incrementally renders tokens as they arrive and automatically enables Nuxt UI's prose components. - -### Dark mode for syntax highlighting - -When using the `highlight` plugin, add the following CSS to your stylesheet: - -```css [main.css] -html.dark .shiki span { - color: var(--shiki-dark) !important; - background-color: var(--shiki-dark-bg) !important; - font-style: var(--shiki-dark-font-style) !important; - font-weight: var(--shiki-dark-font-weight) !important; - text-decoration: var(--shiki-dark-text-decoration) !important; -} -``` - -### Server endpoint - -Using [Vercel AI Gateway](https://vercel.com/ai-gateway) (recommended): - -```ts [server/api/chat.post.ts] -import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai' -import { gateway } from '@ai-sdk/gateway' - -export default defineEventHandler(async (event) => { - const { messages } = await readBody(event) - - const result = streamText({ - model: gateway('anthropic/claude-sonnet-5'), - instructions: 'You are a helpful assistant.', - messages: await convertToModelMessages(messages) - }) - - const stream = toUIMessageStream({ stream: result.stream }) - return createUIMessageStreamResponse({ stream }) -}) -``` - -Or with a direct provider (e.g., `pnpm add @ai-sdk/openai`): - -```ts [server/api/chat.post.ts] -import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai' -import { openai } from '@ai-sdk/openai' - -export default defineEventHandler(async (event) => { - const { messages } = await readBody(event) - - const result = streamText({ - model: openai('gpt-5-nano'), - instructions: 'You are a helpful assistant.', - messages: await convertToModelMessages(messages) - }) - - const stream = toUIMessageStream({ stream: result.stream }) - return createUIMessageStreamResponse({ stream }) -}) -``` - -## Component tree - -``` -UDashboardPanel -├── #header → UDashboardNavbar -├── #body → UContainer → UChatMessages -│ ├── #content → UChatReasoning, UChatTool, Comark -│ └── #indicator (loading) -└── #footer → UContainer → UChatPrompt - └── UChatPromptSubmit -``` - -## Full page chat - -```vue [pages/chat/[id].vue] - - - -``` - -## Key components - -- `UChatMessages` — scrollable message list with auto-scroll. Props: `messages`, `status`. Slots: `#content` (per message), `#actions`, `#indicator`. -- `UChatMessage` — individual bubble. Props: `message`, `side` (`'left'`/`'right'`). -- `UChatReasoning` — collapsible reasoning block. Auto-opens during streaming, auto-closes when done. Use `isPartStreaming(part)` from `@nuxt/ui/utils/ai`. -- `UChatTool` — tool invocation status. Use `isToolStreaming(part)`. Variants: `'inline'` (default), `'card'`. -- `UChatPrompt` — enhanced textarea. Accepts all Textarea props + `error` prop. -- `UChatPromptSubmit` — submit button with automatic status handling (send/stop/reload). -- `UChatPalette` — layout wrapper for chat inside overlays. - -## Chat in a modal - -```vue - - - -``` - -## With model selector - -```vue - - - - - -``` - -## Conversation sidebar - -Combine with dashboard layout for a ChatGPT-like interface: - -```vue [layouts/dashboard.vue] - -``` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/dashboard.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/dashboard.md deleted file mode 100644 index 10d99548..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/dashboard.md +++ /dev/null @@ -1,233 +0,0 @@ -# Dashboard Layout - -Build admin interfaces with resizable sidebars, multi-panel layouts, and toolbars. - -## When to use - -- Admin panels, back-office UIs -- Email clients, project management tools -- Any app with a persistent sidebar and content panels -- Combine with chat or editor layouts for specialized dashboards - -## Component tree - -``` -UApp -└── NuxtLayout (dashboard) - └── UDashboardGroup - ├── UDashboardSidebar - │ ├── #header (logo, search button) - │ ├── #default (navigation) — receives { collapsed } slot prop - │ └── #footer (user menu) - └── NuxtPage - └── UDashboardPanel - ├── #header → UDashboardNavbar + UDashboardToolbar - ├── #body (scrollable content) - └── #footer (optional) -``` - -## Layout - -```vue [layouts/dashboard.vue] - - - -``` - -## Page - -```vue [pages/dashboard/index.vue] - - - -``` - -### Common mistakes - -- Forgetting `definePageMeta({ layout: 'dashboard' })` — the page won't use the dashboard layout without it. -- Putting content directly in `UDashboardPanel` without using `#body` slot — content won't scroll properly. -- Not handling the `collapsed` slot prop — sidebar content should adapt when collapsed (hide labels, center icons). - -## Key components - -### DashboardGroup - -Root wrapper. Manages sidebar state and persistence. - -| Prop | Default | Purpose | -|---|---|---| -| `storage` | `'cookie'` | `'cookie'`, `'localStorage'`, `false` | -| `storage-key` | `'dashboard'` | Storage key name | - -### DashboardSidebar - -Resizable, collapsible sidebar. Must be inside `DashboardGroup`. - -| Prop | Default | Purpose | -|---|---|---| -| `resizable` | `false` | Drag to resize | -| `collapsible` | `false` | Collapse when dragged to edge | -| `side` | `'left'` | `'left'` or `'right'` | -| `mode` | `'slideover'` | Mobile: `'modal'`, `'slideover'`, `'drawer'` | - -All slots receive `{ collapsed, collapse }` — `collapsed` is the boolean state, `collapse(value)` toggles it programmatically. Use `v-model:collapsed` and `v-model:open` (mobile) for state control. - -### DashboardPanel - -Content panel with `#header`, `#body` (scrollable), `#footer`, and `#default` (raw, no scroll) slots. - -### DashboardNavbar / DashboardToolbar - -Navbar: `#leading`, `#left`, `#default`, `#right` slots + `title` prop. Use `UDashboardSidebarCollapse` in `#leading` to toggle sidebar on mobile. -Toolbar: same slots, sits below navbar for filters/actions. - -### UNavigationMenu in sidebar - -Always pass `:collapsed="collapsed"` to `UNavigationMenu` inside a collapsible sidebar — it auto-hides labels and centers icons. Use `NavigationMenuItem[][]` (array of arrays) for separate groups (main nav + footer links). - -## Multi-panel (list-detail) - -```vue [pages/dashboard/inbox.vue] - - - -``` - -## With toolbar - -```vue - - - -``` - -## With search - -```vue [layouts/dashboard.vue] - -``` - -## Right sidebar - -```vue - - - - - - - - - - - -``` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/docs.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/docs.md deleted file mode 100644 index e539897e..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/docs.md +++ /dev/null @@ -1,152 +0,0 @@ -# Docs Layout - -Build documentation sites with sidebar navigation, table of contents, and surround links. - -## When to use - -- Technical documentation sites -- Knowledge bases, help centers -- Any content-heavy site with hierarchical navigation - -> Requires `@nuxt/content` — see [conventions](../guidelines/conventions.md#content-module-integration) for setup (module order + `@source`). - -## Component tree - -``` -UApp -├── UHeader -├── UMain -│ └── NuxtLayout (docs) -│ └── UPage -│ ├── #left → UPageAside → UContentNavigation -│ └── NuxtPage -│ ├── UPageHeader -│ ├── UPageBody → ContentRenderer + UContentSurround -│ └── #right → UContentToc -└── UFooter -``` - -## App shell - -```vue [app.vue] - - - -``` - -## Layout - -```vue [layouts/docs.vue] - - - -``` - -## Page - -```vue [pages/docs/[...slug].vue] - - - -``` - -### How nesting works - -The outer `UPage` in the layout handles the **left sidebar**. The inner `UPage` in the page handles the **right sidebar**. They nest correctly — this is intentional. - -### Common mistakes - -- Not providing navigation via `provide`/`inject` — the layout needs it from the app shell. -- Forgetting `UContentSearch` in app.vue — search won't work without it. -- Using `UContentSearchButton` without `UContentSearch` — the button opens search, but the search component must exist. - -## Key components - -- `UPage` — multi-column grid with `#left`, `#default`, `#right` slots -- `UPageAside` — sticky sidebar wrapper (visible from `lg` breakpoint) -- `UContentNavigation` — sidebar navigation tree from Nuxt Content -- `UContentToc` — table of contents from page headings -- `UContentSurround` — prev/next links -- `UContentSearch` / `UContentSearchButton` — search command palette -- `UPageAnchors` — simpler alternative to full TOC diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/editor.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/editor.md deleted file mode 100644 index eb224a66..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/editor.md +++ /dev/null @@ -1,153 +0,0 @@ -# Editor Layout - -Build a rich text editor with toolbars, slash commands, mentions, and drag-and-drop. - -## When to use - -- Note-taking apps, CMS editors -- Collaborative editing interfaces -- Any rich text editing need (supports JSON, HTML, and Markdown) - -## Component tree - -``` -UEditor -├── UEditorToolbar (fixed / bubble / floating) -├── UEditorDragHandle -├── UEditorSuggestionMenu -├── UEditorMentionMenu -└── UEditorEmojiMenu -``` - -## Basic editor - -```vue - - - -``` - -> If you encounter prosemirror-related errors, add prosemirror packages to `vite.optimizeDeps.include` in `nuxt.config.ts`. - -## Key components - -- `UEditor` — rich text editor. `v-model` accepts JSON (default), HTML, or Markdown via `content-type` prop. Default slot provides `{ editor, handlers }` — `editor` is the Tiptap instance, `handlers` contains action functions for toolbar/menus. -- `UEditorToolbar` — toolbar with `layout`: `'fixed'` (default), `'bubble'` (on selection), `'floating'` (on empty lines). -- `UEditorDragHandle` — block drag-and-drop handle. -- `UEditorSuggestionMenu` — slash command menu (type `/` to open). -- `UEditorMentionMenu` — `@` mention menu. -- `UEditorEmojiMenu` — emoji picker (type `:` to open). - -## Toolbar modes - -```vue - - - - - - - - -``` - -## Content types - -```vue - - - - - - - - -``` - -## With document sidebar - -Combine with Dashboard layout for a multi-document editor: - -```vue [layouts/editor.vue] - -``` - -```vue [pages/editor/[id].vue] - - - -``` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/landing.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/landing.md deleted file mode 100644 index a0d231ad..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/layouts/landing.md +++ /dev/null @@ -1,185 +0,0 @@ -# Landing Page Layout - -Build public-facing pages — landing, blog, changelog, pricing — using the Header + Main + Footer shell with Page components. - -## When to use - -- Marketing sites, product pages, company sites -- Blog and content pages -- Pricing, changelog, portfolio pages -- Any public-facing page that isn't a dashboard or documentation - -## App shell - -```vue [app.vue] - - - -``` - -### Common mistakes - -- Forgetting the `#body` slot on `UHeader` — this is the mobile menu content. Without it, mobile users have no navigation. -- Using `variant="solid"` for both header and hero buttons — the header button should be lower weight than the hero CTA. - -## Landing page - -```vue [pages/index.vue] - -``` - -## Key components - -- `UPageHero` — hero with title, description, links, and optional media. Use `orientation="horizontal"` for side-by-side layout. -- `UPageSection` — content section with headline, title, description, and `features` grid. Use `id` for anchor links. -- `UPageCTA` — call to action block. -- `UPageGrid` / `UPageCard` — card grid for features, testimonials, etc. -- `UPageFeature` — individual feature item. -- `UPageLogos` — logo wall for social proof. -- `UPricingPlans` / `UPricingTable` — pricing cards and comparison tables. -- `UFooterColumns` — multi-column footer with link groups (used inside `UFooter`). - -## Variations - -### Alternating feature sections - -```vue - - - - - - - -``` - -### Blog listing - -```vue [pages/blog/index.vue] - - - -``` - -### Changelog - -```vue [pages/changelog.vue] - - - -``` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/auth.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/auth.md deleted file mode 100644 index 57d2bdc0..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/auth.md +++ /dev/null @@ -1,162 +0,0 @@ -# Auth Forms - -## UAuthForm (recommended) - -`UAuthForm` provides a complete auth form with fields, providers, validation, and submit — no manual `UForm` + `UFormField` wiring needed. Wrap it in `UPageCard` for a polished look. - -```vue [pages/login.vue] - - - -``` - -### UAuthForm key props - -| Prop | Purpose | -|---|---| -| `title`, `description`, `icon` | Header content | -| `fields` | `AuthFormField[]` — each has `name`, `type`, `label`, `placeholder`, `required` | -| `providers` | `ButtonProps[]` — social login buttons shown above/below the form | -| `schema` | Zod/Valibot schema for validation | -| `submit` | Customize submit button: `{ label: 'Sign in', block: true }` | -| `separator` | Text between providers and fields (default: `'or'`) | - -### UAuthForm key slots - -| Slot | Purpose | -|---|---| -| `#description` | Override description (e.g., add sign-up link) | -| `#password-hint` | "Forgot password?" link on password field | -| `#validation` | Custom error display (e.g., `UAlert`) | -| `#footer` | Terms of service, sign-up link | -| `#-field` | Override a specific field's rendering | - -## Custom auth layout - -For layouts where `UAuthForm` is too opinionated, use `UCard` + `UForm` + `UFormField` directly. - -```vue [pages/login.vue] - - - -``` - -## Tips - -- Prefer `UAuthForm` with `UPageCard` for standard auth pages — handles layout, providers, validation, and submit -- Use `import * as z from 'zod'` and `z.email()` (Zod 4 syntax) -- Type the submit handler: `function onSubmit(event: FormSubmitEvent)` — access validated data via `event.data` -- Center auth forms with `flex min-h-dvh items-center justify-center` -- Place "Forgot password?" link as `#password-hint` slot on `UAuthForm`, or `#hint` slot on `UFormField` -- Social login buttons: use `providers` prop on `UAuthForm`, or add manually with `` diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/data-tables.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/data-tables.md deleted file mode 100644 index f5c81f86..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/data-tables.md +++ /dev/null @@ -1,225 +0,0 @@ -# Data Tables - -Complete patterns for displaying and managing tabular data. - -## Basic table - -```vue - - - -``` - -## With search and filters (dashboard) - -```vue - - - -``` - -## With row selection - -Row selection uses TanStack Table's `rowSelection` state — a `Record` keyed by row index. - -```vue - - - -``` - -Add a checkbox column using the `h` function. Use tri-state `modelValue` (`true`, `false`, or `'indeterminate'`) for the "select all" header: - -```ts -import { h } from 'vue' - -const UCheckbox = resolveComponent('UCheckbox') - -const columns: TableColumn[] = [{ - id: 'select', - header: ({ table }) => h(UCheckbox, { - 'modelValue': table.getIsSomePageRowsSelected() ? 'indeterminate' : table.getIsAllPageRowsSelected(), - 'onUpdate:modelValue': (value: boolean | 'indeterminate') => table.toggleAllPageRowsSelected(!!value), - 'aria-label': 'Select all' - }), - cell: ({ row }) => h(UCheckbox, { - 'modelValue': row.getIsSelected(), - 'onUpdate:modelValue': (value: boolean | 'indeterminate') => row.toggleSelected(!!value), - 'aria-label': 'Select row' - }) -}, -// ... other columns -] -``` - -## With pagination - -Use `v-model:pagination` on `UTable` with TanStack's `getPaginationRowModel`, then wire `UPagination` to the table API. `UPagination`'s `total` is total **items** (not pages) — it calculates page count from `total / items-per-page`. - -```vue - - - -``` - -## With async data (Nuxt) - -Use `status === 'pending' || status === 'idle'` for loading state — `idle` covers the initial render before `useLazyFetch` starts. - -```vue - - - -``` - -For server-side pagination: - -```vue - - - -``` - -## Tips - -- Table is built on [TanStack Table v8](https://tanstack.com/table/v8) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` -- Use `#-cell` and `#-header` template slots to customize rendering with Vue templates -- Alternatively, use the `h` function inside `header` and `cell` column properties for inline rendering -- Row data in slots is accessed via `row.original` (not `row` directly) -- Use `v-model:row-selection` for selection, `v-model:sorting` for sort state -- Wrap tables in `UDashboardPanel` with `#header` toolbar for the dashboard pattern -- For empty states, use the `#empty` slot diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/navigation.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/navigation.md deleted file mode 100644 index ef71a988..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/navigation.md +++ /dev/null @@ -1,90 +0,0 @@ -# Navigation - -Patterns for headers, sidebars, breadcrumbs, and tab navigation. - -## Header with mobile menu - -`UHeader` default slot is desktop nav, `#body` is the mobile menu. Without `#body`, mobile users have no navigation. - -```vue - - - - - - - - - -``` - -> Full app shell example in [landing layout](../layouts/landing.md). - -## Sidebar navigation (dashboard) - -See [dashboard layout](../layouts/dashboard.md) for the full sidebar pattern with `UDashboardSidebar` + `UNavigationMenu`. Key points: -- Pass `:collapsed="collapsed"` to `UNavigationMenu` inside collapsible sidebars -- Use `NavigationMenuItem[][]` (nested arrays) for separate nav groups -- Use `#footer` slot for user menu with `UDropdownMenu` - -## Breadcrumbs - -```vue - - - -``` - -## Tab navigation (within a page) - -```vue - - - -``` - diff --git a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/overlays.md b/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/overlays.md deleted file mode 100644 index 597def75..00000000 --- a/code/link-site/link-nuxt/.agents/skills/nuxt-ui/references/recipes/overlays.md +++ /dev/null @@ -1,173 +0,0 @@ -# Overlays - -Patterns for modals, slideovers, drawers, and command palettes. - -## Confirmation dialog - -```vue - - - -``` - -## Programmatic confirmation (useOverlay) - -Reusable pattern — no template state needed at the call site. - -```vue [components/ConfirmModal.vue] - - - -``` - -```ts -// Usage anywhere -const overlay = useOverlay() -const confirm = overlay.create(ConfirmModal) - -async function deleteItem(item) { - const instance = confirm.open({ - title: 'Delete item', - description: `Are you sure you want to delete "${item.name}"?` - }) - - if (await instance.result) { - // user confirmed - } -} -``` - -## Form in a slideover - -```vue - - - -``` - -## Command palette - -```vue - - - -``` - -## Drawer (bottom sheet) - -```vue - - - -``` - diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/SKILL.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/SKILL.md deleted file mode 100644 index 2ce6e71f..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/SKILL.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -name: nuxt-ui -description: Build UIs with @nuxt/ui v4 — 125+ accessible Vue components with Tailwind CSS theming. Use when creating interfaces, customizing themes to match a brand, building forms, or composing layouts like dashboards, docs sites, and chat interfaces. ---- - -# Nuxt UI - -Vue component library built on [Reka UI](https://reka-ui.com/) + [Tailwind CSS](https://tailwindcss.com/) + [Tailwind Variants](https://www.tailwind-variants.org/). Works with Nuxt, Vue (Vite), Laravel (Vite + Inertia), and AdonisJS (Vite + Inertia). - -## MCP Server - -For component API details (props, slots, events, full documentation, examples), use the [Nuxt UI MCP server](https://ui.nuxt.com/docs/getting-started/ai/mcp). If not already configured, add it: - -**Cursor** — `.cursor/mcp.json`: - -```json -{ "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nuxt.com/mcp" } } } -``` - -**Claude Code**: - -```bash -claude mcp add --transport http nuxt-ui https://ui.nuxt.com/mcp -``` - -Key MCP tools: -- `search-components` — find components by name, category, or intent (no params = list all) -- `search-composables` — find composables by name or description (no params = list all) -- `search-icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names -- `get-component` — full component documentation with usage examples -- `get-component-metadata` — props, slots, events (lightweight, no docs content) -- `get-example` — real-world code examples - -When you need to know **what a component accepts** or **how its API works**, use the MCP. This skill teaches you **when to use which component** and **how to build well**. - -## Core rules (always apply) - -1. **Always wrap the app in `UApp`** — required for toasts, tooltips, and programmatic overlays. Accepts a `locale` prop for i18n. -2. **Always use semantic colors** — `text-default`, `bg-elevated`, `border-muted`, etc. Never use raw Tailwind palette colors like `text-gray-500`. -3. **Read generated theme files for slot names** — Nuxt: `.nuxt/ui/.ts`, Vue: `node_modules/.nuxt-ui/ui/.ts`. These show every slot, variant, and default class for any component. -4. **Override priority** (highest wins): `ui` prop / `class` prop → global config → theme defaults. -5. **Icons use `i-{collection}-{name}` format** — `lucide` is the default collection. Use the MCP `search-icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org). - -## How to use this skill - -Based on the task, load the relevant reference files **before writing any code**. Don't load everything — only what's needed. - -### Reference files - -**Guidelines** — design decisions and conventions: -- [design-system](references/guidelines/design-system.md) — semantic colors, theming, brand customization, variants, the `ui` prop -- [component-selection](references/guidelines/component-selection.md) — decision matrices: when to use Modal vs Slideover, Select vs SelectMenu, Toast vs Alert, etc. -- [conventions](references/guidelines/conventions.md) — coding patterns, slot naming, items arrays, composables, keyboard shortcuts -- [forms](references/guidelines/forms.md) — form validation, field layout, error handling, Standard Schema - -**Layouts** — full page structure patterns: -- [landing](references/layouts/landing.md) — landing pages, blog, changelog, pricing -- [dashboard](references/layouts/dashboard.md) — admin UI with sidebar and panels -- [docs](references/layouts/docs.md) — documentation sites with navigation and TOC -- [chat](references/layouts/chat.md) — AI chat with Vercel AI SDK -- [editor](references/layouts/editor.md) — rich text editor with toolbars - -**Recipes** — complete patterns for common tasks: -- [data-tables](references/recipes/data-tables.md) — tables with filters, pagination, sorting, selection -- [auth](references/recipes/auth.md) — login, signup, forgot password forms -- [overlays](references/recipes/overlays.md) — modals, slideovers, drawers, command palette -- [navigation](references/recipes/navigation.md) — headers, sidebars, breadcrumbs, tabs - -**Quick reference:** -- [components](references/components.md) — categorized component index for finding the right component name - -### Routing table - -| Task | Load these references | -|---|---| -| Build a landing page | design-system, conventions, landing | -| Build a dashboard / admin UI | conventions, component-selection, dashboard | -| Add a settings page | conventions, forms | -| Create a login / signup form | conventions, forms, auth | -| Display data in a table | conventions, component-selection, data-tables | -| Customize theme / brand colors | design-system | -| Add a chat interface | conventions, chat | -| Add a modal, slideover, or drawer | conventions, component-selection, overlays | -| Build site navigation | conventions, component-selection, navigation | -| Build a documentation site | conventions, docs | -| Render markdown | component-selection, components, docs | -| Add a rich text editor | conventions, editor | -| General UI work | conventions, component-selection | - -## Installation - -### Nuxt - -```bash -pnpm add @nuxt/ui tailwindcss -``` - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui'], - css: ['~/assets/css/main.css'] -}) -``` - -```css -/* app/assets/css/main.css */ -@import "tailwindcss"; -@import "@nuxt/ui"; -``` - -```vue - - -``` - -### Vue (Vite) - -```bash -pnpm add @nuxt/ui tailwindcss -``` - -```ts -// vite.config.ts -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import ui from '@nuxt/ui/vite' - -export default defineConfig({ - plugins: [ - vue(), - ui() - ] -}) -``` - -```ts -// src/main.ts -import './assets/css/main.css' -import { createApp } from 'vue' -import { createRouter, createWebHistory } from 'vue-router' -import ui from '@nuxt/ui/vue-plugin' -import App from './App.vue' - -const app = createApp(App) -const router = createRouter({ - routes: [], - history: createWebHistory() -}) - -app.use(router) -app.use(ui) -app.mount('#app') -``` - -```css -/* src/assets/css/main.css */ -@import "tailwindcss"; -@import "@nuxt/ui"; -``` - -```vue - - -``` - -> Add `class="isolate"` to your root `
` in `index.html`. -> For Inertia: use `ui({ router: 'inertia' })` in `vite.config.ts`. diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/components.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/components.md deleted file mode 100644 index 6f108bda..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/components.md +++ /dev/null @@ -1,245 +0,0 @@ -# Components - -Quick-reference index of all 125+ components. For full API docs (props, slots, events, examples), use the MCP `get-component` or `get-component-metadata` tools. - -## Layout - -| Component | Purpose | -|---|---| -| `UApp` | **Required** root wrapper — toasts, tooltips, overlays, i18n | -| `UHeader` | Responsive header with mobile menu | -| `UFooter` | Footer with left/right/top/bottom slots | -| `UFooterColumns` | Multi-column footer with link groups | -| `UMain` | Main content area | -| `UContainer` | Centered max-width container | -| `USplitter` | Resizable panels separated by draggable handles | -| `ULink` | Enhanced link — NuxtLink/RouterLink with active states | - -## Element - -| Component | Purpose | -|---|---| -| `UButton` | Buttons — links, actions, icons, loading states | -| `UBadge` | Labels, tags, status indicators | -| `UAvatar` | User photos, initials, icons | -| `UAvatarGroup` | Stacked avatars with `max` limit | -| `UIcon` | Iconify icons (`i-{collection}-{name}`) | -| `UCard` | Bordered container with header/body/footer | -| `UAlert` | Inline messages — info, warning, error, success | -| `UBanner` | App-wide sticky announcement bar | -| `UChip` | Notification dot overlay on children | -| `UKbd` | Keyboard key display | -| `USeparator` | Divider line with optional label | -| `USkeleton` | Loading placeholder | -| `UProgress` | Progress bar | -| `UProgressGroup` | Segmented progress bar with a list of items | -| `UToast` | Toast notification (shown via `useToast`) | -| `UCalendar` | Date calendar (single, range, multiple) | -| `UCollapsible` | Animated expand/collapse | -| `UFieldGroup` | Group form inputs horizontally | -| `UMarquee` | Scrolling content ticker | -| `UCarousel` | Image/content carousel with autoplay | -| `UEmpty` | Empty state placeholder with icon, title, actions | -| `UError` | Error display with retry action | -| `UScrollArea` | Scrollable area with custom scrollbar | -| `UTimeline` | Timeline display for events and activity | -| `UUser` | User display — avatar + name + description | -| `UTheme` | Theme provider — scoped color overrides for children | - -## Form - -| Component | Purpose | -|---|---| -| `UAuthForm` | Pre-built auth form with social providers | -| `UInput` | Text input — text, email, password, search | -| `UTextarea` | Multi-line text with autoresize | -| `USelect` | Native-like dropdown for small lists | -| `USelectMenu` | Rich searchable dropdown, multi-select, groups | -| `UInputMenu` | Autocomplete / combobox | -| `UInputNumber` | Numeric input with +/- controls | -| `UInputDate` | Date picker with calendar | -| `UInputTime` | Time picker (12/24h) | -| `UInputTags` | Tag/chip input | -| `UPinInput` | Verification code input | -| `UCheckbox` | Single boolean checkbox | -| `UCheckboxGroup` | Multiple checkboxes | -| `URadioGroup` | Radio button group | -| `USwitch` | Toggle switch | -| `USlider` | Range slider | -| `UColorPicker` | Color picker (hex/rgb/hsl) | -| `UFileUpload` | File upload (button or drop area) | -| `UForm` | Validation wrapper with Standard Schema | -| `UFormField` | Field wrapper with label, hint, errors | - -## Overlay - -| Component | Purpose | -|---|---| -| `UModal` | Centered dialog — confirmations, forms | -| `USlideover` | Side panel — details, editing | -| `UDrawer` | Bottom sheet — mobile actions | -| `UPopover` | Contextual popup attached to trigger | -| `UTooltip` | Hover/focus hint (non-interactive) | -| `UContextMenu` | Right-click menu | -| `UCommandPalette` | Search + keyboard navigation (Cmd+K) | - -## Navigation - -| Component | Purpose | -|---|---| -| `USidebar` | Standalone sidebar with header/body/footer | -| `UNavigationMenu` | Primary nav — horizontal or vertical | -| `UTabs` | Tab switcher within a page | -| `UBreadcrumb` | Location hierarchy | -| `UDropdownMenu` | Action menu on a trigger | -| `UPagination` | Page navigation | -| `UStepper` | Multi-step wizard | -| `UAccordion` | Collapsible sections | - -## Data - -| Component | Purpose | -|---|---| -| `UTable` | Data table (TanStack Table) with sorting, selection, pinning | -| `UTree` | Hierarchical tree view | - -## Dashboard - -| Component | Purpose | -|---|---| -| `UDashboardGroup` | Root dashboard wrapper | -| `UDashboardSidebar` | Resizable, collapsible sidebar | -| `UDashboardPanel` | Content panel with header/body/footer | -| `UDashboardNavbar` | Panel header bar | -| `UDashboardToolbar` | Filter/action bar below navbar | -| `UDashboardResizeHandle` | Resize handle between panels | -| `UDashboardSidebarToggle` | Mobile sidebar toggle button | -| `UDashboardSearchButton` | Search button for sidebar | -| `UDashboardSearch` | Dashboard-level search overlay | -| `UDashboardSidebarCollapse` | Collapse button for sidebar | - -## Page (marketing) - -| Component | Purpose | -|---|---| -| `UPage` | Multi-column layout with left/right sidebars | -| `UPageHero` | Hero section — title, description, links, media | -| `UPageSection` | Content section with features grid | -| `UPageCTA` | Call to action block | -| `UPageHeader` | Page title and description | -| `UPageBody` | Main content area | -| `UPageGrid` | Card grid layout | -| `UPageColumns` | Multi-column layout | -| `UPageCard` | Content card for grids | -| `UPageFeature` | Feature item | -| `UPageLogos` | Logo cloud | -| `UPageAside` | Sticky sidebar wrapper | -| `UPageAnchors` | Simple anchor links | -| `UPageLinks` | Related resource links | -| `UPageList` | List layout for page items | - -## Blog & Changelog - -| Component | Purpose | -|---|---| -| `UBlogPosts` | Blog post grid | -| `UBlogPost` | Individual post card | -| `UChangelogVersions` | Changelog list | -| `UChangelogVersion` | Individual changelog entry | - -## Pricing - -| Component | Purpose | -|---|---| -| `UPricingPlans` | Pricing plan cards | -| `UPricingPlan` | Individual pricing plan card | -| `UPricingTable` | Feature comparison table | - -## Prose — Base Typography - -Standard Markdown elements auto-resolved by Comark/Content/MDC. No `::` prefix needed — they map directly from markdown syntax (`# Heading` → `ProseH1`, `**bold**` → `ProseStrong`, etc.). Themed via `appConfig.ui.prose.`. - -| Component | Renders | Notable | -|---|---|---| -| `H1` `H2` `H3` `H4` | Headings | H1–H3 get anchor links + TOC entries | -| `P` | Paragraph | | -| `A` | Link | External links get target/rel handling | -| `Strong` | Bold | | -| `Em` | Italic | | -| `Blockquote` | Blockquote | | -| `Hr` | Horizontal rule | | -| `Ul` `Ol` `Li` | Lists | Supports nesting and mixed lists | -| `Table` `Thead` `Tbody` `Tr` `Th` `Td` | Tables | | -| `Img` | Image | Zoom on click (`:zoom="false"` to disable), `@nuxt/image` support | -| `Pre` | Code block | Copy button, filename + icon, line highlighting (`{2,4-6}`), diff | -| `Code` | Inline code | `color` and `lang` props | - -## Prose — Feature Components - -Nuxt UI-specific Prose components. In markdown files they are used **without the `Prose` prefix** (e.g. `::callout`, `::steps`). In Vue they are referenced as `ProseCallout`, `ProseSteps`, etc. Comark resolves them automatically when `@nuxt/ui` is installed. - -Nuxt UI also registers shorthand aliases for `Callout`: `::note`, `::tip`, `::warning`, `::caution` (preset `color` + `icon`). - -| Component | Purpose | -|---|---| -| `Callout` | Highlighted note/warning/tip (`color`, `icon`, `to`) | -| `Badge` | Inline badge/tag | -| `Kbd` | Keyboard key | -| `Icon` | Inline Iconify icon | -| `Prompt` | Terminal prompt block | -| `Card` `CardGroup` | Content card and card grid | -| `Steps` | Numbered step list (`level` prop sets heading depth) | -| `Tabs` `TabsItem` | Tabbed content (`sync` for localStorage, `hash` for scroll-on-change) | -| `Accordion` `AccordionItem` | Collapsible accordion sections | -| `Collapsible` | Single collapsible section | -| `Field` `FieldGroup` | Form field display | -| `CodeGroup` | Tabbed code blocks | -| `CodeCollapse` | Collapsible code block | -| `CodeIcon` | File-type icon in code headers | -| `CodePreview` | Code + live rendered preview side by side | -| `CodeTree` | File tree display | -| `Script` | Script injection | - -## Content (Nuxt Content) - -| Component | Purpose | -|---|---| -| `UContentNavigation` | Sidebar navigation from content | -| `UContentToc` | Table of contents | -| `UContentSurround` | Prev/next navigation | -| `UContentSearch` | Search command palette | -| `UContentSearchButton` | Trigger for content search | - -## Chat (AI) - -| Component | Purpose | -|---|---| -| `UChatMessages` | Scrollable message list | -| `UChatMessage` | Individual message bubble | -| `UChatReasoning` | Collapsible AI reasoning block | -| `UChatTool` | Tool invocation status | -| `UChatShimmer` | Streaming text animation | -| `UChatPrompt` | Enhanced textarea for prompts | -| `UChatPromptSubmit` | Submit button with status | -| `UChatPalette` | Chat layout for overlays | - -## Editor - -| Component | Purpose | -|---|---| -| `UEditor` | Rich text editor (JSON/HTML/Markdown) | -| `UEditorToolbar` | Toolbar (fixed/bubble/floating) | -| `UEditorDragHandle` | Block drag-and-drop | -| `UEditorSuggestionMenu` | Slash command menu | -| `UEditorMentionMenu` | @ mention menu | -| `UEditorEmojiMenu` | Emoji picker | - -## Color Mode - -| Component | Purpose | -|---|---| -| `UColorModeButton` | Toggle button (light/dark) | -| `UColorModeSwitch` | Toggle switch (light/dark) | -| `UColorModeSelect` | Dropdown (light/dark/system) | -| `UColorModeAvatar` | Avatar that changes with color mode | -| `UColorModeImage` | Image that changes with color mode | diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/component-selection.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/component-selection.md deleted file mode 100644 index c2d1ce14..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/component-selection.md +++ /dev/null @@ -1,124 +0,0 @@ -# Component Selection - -Decision matrices for choosing the right component. When in doubt, use the MCP `search-components` tool. - -## Overlays - -| Need | Component | Why | -|---|---|---| -| Confirmation dialog, focused task, form | `UModal` | Blocks page interaction, centered, draws focus | -| Detail panel, settings, secondary content | `USlideover` | Slides from edge, doesn't feel as interruptive as modal | -| Mobile-first bottom sheet | `UDrawer` | Natural mobile pattern, swipe to dismiss | -| Contextual info attached to a trigger | `UPopover` | No backdrop, positioned relative to trigger | -| Simple hover hint | `UTooltip` | Non-interactive, hover/focus only | - -### Rules -- Use `UModal` for destructive confirmations ("Are you sure you want to delete?") -- Use `USlideover` for detail views in dashboards (email preview, user profile) -- Use `UDrawer` for mobile navigation or action sheets -- Modal and Slideover support `mode="drawer"` for automatic mobile drawer behavior -- For programmatic overlays, use `useOverlay()` instead of `v-model:open` -- Never put interactive content (buttons, links) inside `UTooltip` - -## Navigation - -| Need | Component | Why | -|---|---|---| -| Primary site/app navigation | `UNavigationMenu` | Horizontal (header) or vertical (sidebar) | -| Switch between views on same page | `UTabs` | Content stays on page, no route change needed | -| Show current location in hierarchy | `UBreadcrumb` | Nested page structures | -| Search + keyboard-driven navigation | `UCommandPalette` | Power users, global search | -| Contextual actions on a trigger element | `UDropdownMenu` | Right-click menus, action buttons | -| Step-by-step process | `UStepper` | Multi-step forms, wizards | - -### Rules -- Use `UNavigationMenu` with `orientation="vertical"` in sidebars, default horizontal in headers -- Use `UTabs` when switching views that don't need their own URL -- Use route-based navigation (`to` prop) when views should have shareable URLs -- `UCommandPalette` is typically opened via `Cmd+K` shortcut — use `defineShortcuts` to wire it up - -## Inputs - -| Need | Component | Why | -|---|---|---| -| Small fixed list (< 10 items) | `USelect` | Native-like, simple, lightweight | -| Searchable list, multiple selection, groups | `USelectMenu` | Rich dropdown with search, multi-select, grouped items | -| Autocomplete / combobox (type + select) | `UInputMenu` | User can type freely AND pick from suggestions | -| Free text entry | `UInput` | Plain text, email, password, search | -| Multi-line text | `UTextarea` | With `autoresize` and `maxrows` | -| Numeric value with +/- controls | `UInputNumber` | Min/max/step constraints | -| Date selection | `UInputDate` | Calendar dropdown, supports ranges | -| Time selection | `UInputTime` | Hour/minute picker, 12/24 hour | -| Tags / multi-value free text | `UInputTags` | Chip-style input with max limit | -| Verification code | `UPinInput` | Fixed-length code entry | -| Boolean toggle | `USwitch` | On/off, enable/disable | -| Boolean checkbox | `UCheckbox` | Single option with label | -| Multiple choices from a list | `UCheckboxGroup` | Multiple selection, vertical or horizontal | -| Single choice from a list (visible) | `URadioGroup` | All options visible, one selected | -| Range value | `USlider` | Min/max with visual track | -| Color value | `UColorPicker` | Hex/RGB/HSL picker | -| File upload | `UFileUpload` | Button or drop area variants | - -### Rules -- Use `UAuthForm` for login/signup pages — handles fields, social providers, validation, and layout out of the box -- Use `USelect` for short, known lists (country, status, role) -- Use `USelectMenu` when the list is long or needs search -- Use `UInputMenu` when the user might want to type a value that's not in the list -- Wrap all form inputs in `UFormField` for labels, descriptions, hints, and validation errors -- Group related inline inputs with `UFieldGroup` - -## Feedback - -| Need | Component | Why | -|---|---|---| -| Ephemeral notification after action | `useToast()` | Auto-dismisses, stacks, non-blocking | -| Inline persistent message | `UAlert` | Stays visible, in-page context | -| App-wide announcement | `UBanner` | Sticky top bar, dismissible | -| Loading state | `USkeleton` | Placeholder shimmer while loading | -| Progress indicator | `UProgress` | Determinate or indeterminate progress | -| Breakdown of a total | `UProgressGroup` | One bar split into colored segments that add up to `max` | - -### Rules -- Use `useToast()` for action feedback: "Item saved", "Email sent", "Error occurred" -- Use `UAlert` for contextual warnings in forms or sections -- Use `UBanner` for site-wide messages (maintenance, new feature) -- Never use a toast for information the user needs to act on — use an alert or modal instead - -## Markdown - -When rendering Markdown (for instance with Comark), **prefer Prose components** — they are styled and tuned for Markdown contexts. Generic Nuxt UI components can also be used. `` (or ``) auto-resolves `ProseX` components when `@nuxt/ui` is installed. In Markdown, the `Prose` prefix can be omitted (`::callout`, `::steps`, etc.). - -| Need | Use | Not | -|---|---|---| -| Note / warning / tip | `Callout` | `UAlert` | -| Tabbed content | `Tabs` + `TabsItem` | `UTabs` | -| Step-by-step list | `Steps` | custom list | -| Content card grid | `Card` + `CardGroup` | `UCard` | -| Collapsible section | `Collapsible` / `Accordion` | `UCollapsible` / `UAccordion` | -| Tabbed code blocks | `CodeGroup` | manual tabs | - -### Rules -- Prose components use native Vue slots — Comark maps named `#slot` blocks directly to `` -- Theme via `appConfig.ui.prose.` using the same override pattern as other Nuxt UI components -- `Callout` colors: `neutral` (default), `primary`, `secondary`, `info`, `success`, `warning`, `error` - -## Layout containers - -| Need | Component | Why | -|---|---|---| -| Grouped content with header/body/footer | `UCard` | Bordered/shadow container with slots | -| Rich content card with icon, badge, links | `UPageCard` | Extended card for grids — supports icon, badge, highlight, links | -| Marketing page section | `UPageSection` | Full-width section with headline, title, features | -| Page hero | `UPageHero` | Title + description + links + optional media | -| Call to action | `UPageCTA` | Highlighted section with action links | -| Feature grid | `UPageGrid` + `UPageCard` | Multi-column card grid | -| Centered content wrapper | `UContainer` | Max-width container | -| Collapsible section | `UCollapsible` | Animated expand/collapse | -| Accordion (multiple collapsibles) | `UAccordion` | FAQ, grouped collapsible content | -| Resizable side-by-side panes | `USplitter` | IDE-style layouts, resizable sidebars | - -### Rules -- Don't overuse `UCard` — plain content with spacing is often better than wrapping everything in cards -- Use `UPageCard` instead of `UCard` when you need icon, badge, highlight, or links — it's designed for feature grids and landing pages -- Use `UPageSection` for marketing/landing page sections, not for app UI -- Use `UContainer` inside `UDashboardPanel` body for consistent content width diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/conventions.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/conventions.md deleted file mode 100644 index c1aa29eb..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/conventions.md +++ /dev/null @@ -1,376 +0,0 @@ -# Conventions - -Coding patterns specific to Nuxt UI. - -## Auto-registered modules - -Nuxt UI automatically registers `@nuxt/icon`, `@nuxt/fonts`, and `@nuxtjs/color-mode`. Do **not** add them to your `modules` array. Configure them via root-level keys in `nuxt.config.ts`: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui'], - icon: { /* @nuxt/icon options */ }, - fonts: { /* @nuxt/fonts options */ }, - colorMode: { /* @nuxtjs/color-mode options */ } -}) -``` - -Disable any of them: `ui: { fonts: false }`, `ui: { colorMode: false }`. - -## Content module integration - -When using `@nuxt/content`, it **must** come after `@nuxt/ui` in the `modules` array — otherwise prose components won't be available: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui', '@nuxt/content'] -}) -``` - -Add `@source` in your CSS so Tailwind generates classes used in markdown/MDC: - -```css -/* app/assets/css/main.css */ -@import "tailwindcss"; -@import "@nuxt/ui"; - -@source "../../../content/**/*"; -``` - -Use `mapContentNavigation` to transform content navigation for components like `UBreadcrumb`: - -```ts -import { mapContentNavigation } from '@nuxt/ui/utils/content' -import { findPageBreadcrumb } from '@nuxt/content/utils' - -const breadcrumb = computed(() => - mapContentNavigation(findPageBreadcrumb(navigation.value, page.value?.path)) -) -``` - -## IDE setup - -Recommended `.vscode/settings.json` for Tailwind IntelliSense autocomplete with Nuxt UI: - -```json -{ - "files.associations": { "*.css": "tailwindcss" }, - "editor.quickSuggestions": { "strings": "on" }, - "tailwindCSS.classAttributes": ["class", "ui"], - "tailwindCSS.classFunctions": ["defineAppConfig"] -} -``` - -## UApp wrapper - -Always wrap your app in `UApp` — it provides: -- Toast container (`useToast`) -- Tooltip provider -- Programmatic overlay context (`useOverlay`) -- i18n locale support - -```vue - - - -``` - -## Icons - -Nuxt UI registers `@nuxt/icon` automatically. Format: `i-{collection}-{name}`. Prefer `lucide` collection. - -```vue - - - -``` - -Install collections locally for reliable SSR and best performance: - -```bash -pnpm i @iconify-json/lucide -pnpm i @iconify-json/simple-icons -``` - -Custom local collections (Nuxt only): - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - icon: { - customCollections: [{ - prefix: 'custom', - dir: './app/assets/icons' - }] - } -}) -``` - -### Default icon overrides - -Components like `Modal`, `Select`, `Accordion`, etc. use default icons from `appConfig.ui.icons`. Override them globally: - -```ts -// app.config.ts -export default defineAppConfig({ - ui: { - icons: { - loading: 'i-lucide-refresh-cw', - close: 'i-lucide-x', - check: 'i-lucide-check', - chevronDown: 'i-lucide-chevron-down', - chevronRight: 'i-lucide-chevron-right', - arrowLeft: 'i-lucide-arrow-left', - arrowRight: 'i-lucide-arrow-right' - } - } -}) -``` - -## Slot patterns - -Most components follow consistent slot naming: - -| Slot | Used by | Purpose | -|---|---|---| -| `#header` | Card, Modal, Slideover, DashboardPanel | Top section | -| `#body` | DashboardPanel | Scrollable content area | -| `#footer` | Card, Modal, Slideover, DashboardPanel | Bottom section | -| `#left` | Page, DashboardNavbar | Left sidebar or content | -| `#right` | Page, DashboardNavbar, Header | Right sidebar or content | -| `#leading` | Input, Button, Alert | Before main content (icon area) | -| `#trailing` | Input, Button | After main content (icon area) | -| `#content` | Modal, Slideover, Popover, Tooltip | Full content override | -| `#default` | Most components | Main content area | - -## Items arrays - -Many components accept an `items` prop. Two patterns: - -**Flat array** — plain list: - -```ts -const items = [ - { label: 'Edit', icon: 'i-lucide-pencil' }, - { label: 'Delete', icon: 'i-lucide-trash', color: 'error' } -] -``` - -**Nested array** — groups with automatic separators between them: - -```ts -const items = [ - [ - { label: 'Edit', icon: 'i-lucide-pencil' }, - { label: 'Duplicate', icon: 'i-lucide-copy' } - ], - [ - { label: 'Delete', icon: 'i-lucide-trash', color: 'error' } - ] -] -``` - -Components supporting nested arrays: `UDropdownMenu`, `UContextMenu`, `UCommandPalette`, `UNavigationMenu`. - -## Composables - -### useToast - -```ts -const toast = useToast() - -toast.add({ - title: 'Success', - description: 'Item saved', - color: 'success', - icon: 'i-lucide-check-circle', - duration: 5000, - actions: [{ label: 'Undo', onClick: () => {} }] -}) - -toast.remove('toast-id') -toast.clear() -``` - -### useOverlay - -Programmatic modals, slideovers, drawers — no template `v-model` needed. See [overlays recipe](../recipes/overlays.md) for full patterns. - -```ts -const overlay = useOverlay() -const modal = overlay.create(MyComponent) -const instance = modal.open({ title: 'Confirm?' }) -if (await instance.result) { /* confirmed */ } -``` - -### defineShortcuts - -```ts -defineShortcuts({ - meta_k: () => openSearch(), - escape: () => close(), - meta_enter: { - handler: () => submit(), - whenever: [isFormValid] - } -}) -``` - -Keys: `meta` (Cmd/Ctrl), `ctrl`, `alt`, `shift`. Separator: `_`. - -### extractShortcuts - -Wire up keyboard shortcuts from menu items: - -```ts -const items = [ - { label: 'New file', kbds: ['meta', 'n'], onSelect: () => newFile() }, - { label: 'Save', kbds: ['meta', 's'], onSelect: () => save() } -] - -defineShortcuts(extractShortcuts(items)) -``` - -### Internationalization (i18n) - -Nuxt UI supports 50+ locales. Set the locale on `UApp` — all components inherit it. - -#### Static locale - -```vue - - - -``` - -#### Extend a built-in locale - -`extendLocale` is auto-imported. Override specific messages or the `code` (affects date/time formatting in Calendar, InputDate, InputTime): - -```ts -import { en } from '@nuxt/ui/locale' - -const locale = extendLocale(en, { - code: 'en-AU', - messages: { - commandPalette: { placeholder: 'Search a component...' } - } -}) -``` - -#### Custom locale from scratch - -```ts -import type { Messages } from '@nuxt/ui' - -const locale = defineLocale({ - name: 'My locale', - code: 'en', - dir: 'ltr', - messages: { - // all component message keys - } -}) -``` - -#### Dynamic locale with @nuxtjs/i18n - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - modules: ['@nuxt/ui', '@nuxtjs/i18n'], - i18n: { - locales: [ - { code: 'en', name: 'English' }, - { code: 'fr', name: 'Français' }, - { code: 'ar', name: 'العربية' } - ] - } -}) -``` - -```vue - - - -``` - -Each locale has a `dir` property (`'ltr'` or `'rtl'`). `UApp` uses it to set directionality on all components. Use `useHead` to propagate `lang` and `dir` to the `` element. - -## Color mode - -Nuxt UI registers `@nuxtjs/color-mode` automatically. Built-in components for switching: -- `UColorModeButton` — single button toggle (light/dark) -- `UColorModeSwitch` — toggle switch -- `UColorModeSelect` — dropdown with system/light/dark options -- `UColorModeAvatar` — displays different avatar per mode -- `UColorModeImage` — displays different image per mode - -For custom color mode UI, use `useColorMode` with `ClientOnly` to avoid hydration mismatch: - -```vue - - - -``` - -## Official templates - -Bootstrap a project from a template instead of starting from scratch: - -```bash -npx nuxi@latest init -t ui # Starter -npx nuxi@latest init -t ui/dashboard # Dashboard -npx nuxi@latest init -t ui/docs # Docs (Nuxt Content) -npx nuxi@latest init -t ui/landing # Landing page -npx nuxi@latest init -t ui/saas # SaaS (landing + pricing + docs + blog) -npx nuxi@latest init -t ui/chat # AI chat (Vercel AI SDK) -npx nuxi@latest init -t ui/editor # Rich text editor -npx nuxi@latest init -t ui/portfolio # Portfolio -npx nuxi@latest init -t ui/changelog # Changelog -npx nuxi@latest init -t ui/calendar # Calendar -``` - -## Responsive patterns - -- Dashboard sidebar hides on mobile, shows a slideover/drawer via `UDashboardSidebar` `mode` prop -- `UHeader` body slot is the mobile menu content (shown when hamburger is tapped) -- Most components handle responsiveness automatically — avoid manual breakpoint classes unless needed -- Use `UPageAside` for sidebars that should hide below `lg` breakpoint diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/design-system.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/design-system.md deleted file mode 100644 index 561dc411..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/design-system.md +++ /dev/null @@ -1,378 +0,0 @@ -# Design System - -## Semantic colors - -Nuxt UI uses 7 semantic colors. Never use raw Tailwind palette colors in components — always use these semantic names. - -| Color | Default | When to use | -|---|---|---| -| `primary` | green | CTAs, active states, brand accent, links | -| `secondary` | blue | Secondary actions, complementary highlights | -| `success` | green | Success messages, confirmations, positive states | -| `info` | blue | Informational alerts, tips, neutral highlights | -| `warning` | yellow | Warnings, caution states, pending actions | -| `error` | red | Errors, destructive actions, validation failures | -| `neutral` | slate | Text, borders, backgrounds, disabled states, chrome | - -### Choosing colors for components - -- **Primary action** on a page (submit, save, confirm) → `color="primary"` -- **Secondary actions** (cancel, back, alternative) → `color="neutral"` with `variant="outline"` or `"ghost"` -- **Destructive actions** (delete, remove) → `color="error"` -- **Status indicators** → match the semantic meaning: `success`, `warning`, `error`, `info` -- **Navigation and chrome** → `color="neutral"` - -### Configuring colors - -```ts -// Nuxt — app.config.ts -export default defineAppConfig({ - ui: { - colors: { - primary: 'indigo', - secondary: 'violet', - success: 'emerald', - error: 'rose', - neutral: 'zinc' - } - } -}) -``` - -```ts -// Vue — vite.config.ts -ui({ - ui: { - colors: { primary: 'indigo', secondary: 'violet', neutral: 'zinc' } - } -}) -``` - -Only colors that exist in your theme work — either Tailwind's defaults or custom colors defined with `@theme`. - -Available color palettes: -- **Standard Tailwind**: red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose -- **Neutral palettes** (for `neutral` key — pick one that matches the aesthetic): - - `slate` — cool blue-gray, professional (default) - - `gray` — true neutral, clean - - `zinc` — slightly cool, modern, techy - - `neutral` — perfectly balanced - - `stone` — warm gray, earthy - - `taupe` — warm brown-gray, sophisticated - - `mauve` — purple-tinted gray, elegant - - `mist` — soft blue-gray, airy - - `olive` — green-tinted gray, natural - -### Adding custom brand colors - -1. Define all 11 shades in CSS: - -```css -/* app/assets/css/main.css */ -@theme static { - --color-brand-50: #fef2f2; - --color-brand-100: #fee2e2; - --color-brand-200: #fecaca; - --color-brand-300: #fca5a5; - --color-brand-400: #f87171; - --color-brand-500: #ef4444; - --color-brand-600: #dc2626; - --color-brand-700: #b91c1c; - --color-brand-800: #991b1b; - --color-brand-900: #7f1d1d; - --color-brand-950: #450a0a; -} -``` - -2. Assign it: `ui: { colors: { primary: 'brand' } }` - -### Extending with new semantic color names - -To add a color beyond the 7 defaults (e.g., `tertiary`), register it in `theme.colors`: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - theme: { - colors: ['primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error'] - } - } -}) -``` - -## Semantic utility classes - -Use these everywhere instead of raw palette colors: - -### Text -- `text-default` — primary body text -- `text-muted` — secondary text (descriptions, hints) -- `text-toned` — medium-emphasis text (between muted and default) -- `text-dimmed` — tertiary text (placeholders, disabled) -- `text-highlighted` — emphasized text (headings, important labels) -- `text-inverted` — text on inverted backgrounds (pair with `bg-inverted`) - -### Backgrounds -- `bg-default` — page background -- `bg-muted` — subtle backgrounds (hover states, alternating rows) -- `bg-elevated` — raised surfaces (cards, dropdowns) -- `bg-accented` — accent backgrounds (active states, selected items) -- `bg-inverted` — inverse background (dark on light, light on dark) - -### Borders -- `border-default` — standard borders -- `border-muted` — subtle borders (dividers, separators) -- `border-accented` — accent borders (active states) -- `border-inverted` — inverse borders - -## Variants - -Most components accept a `variant` prop. Choose based on visual weight: - -| Variant | Weight | When to use | -|---|---|---| -| `solid` | Highest | Primary actions, main CTAs | -| `outline` | Medium | Secondary actions, form fields | -| `soft` | Medium-low | Tags, badges, subtle buttons | -| `subtle` | Low | Background highlights, less prominent actions | -| `ghost` | Lowest | Inline actions, icon buttons, navigation items | -| `link` | Lowest | Text-only links inside content | - -### Rules - -- **One solid primary button per view** — everything else should be lower weight -- **Destructive buttons** use `color="error"` but not necessarily `variant="solid"` — use `variant="soft"` or `"outline"` unless it's the primary action on a confirmation dialog -- **Button groups** should use consistent variants — don't mix `solid` and `outline` siblings - -## Customizing components - -### `ui` prop - -Override theme **slots** on a single instance — wins over global config and variants. - -```vue - - -``` - -Rules for `ui` overrides: -- **Prefer `defaultVariants`** over slot class overrides when possible (e.g., changing default button variant/size). -- **Don't duplicate default classes** — check the generated theme file first to see what's already there. -- Border radius defaults come from `--ui-radius`, but you can override with `rounded-*` classes in `ui` or `class` when you need a specific radius on a component. - -### `class` prop - -Override the **root** (or `base`) slot only — simpler than `ui` for single-slot changes. - -```vue - -``` - -### Finding slot names - -Read the generated theme file for any component: -- **Nuxt**: `.nuxt/ui/.ts` -- **Vue**: `node_modules/.nuxt-ui/ui/.ts` - -These files show every available slot name, variant combination, and default class. - -### Global config - -Override `slots`, `variants`, `compoundVariants`, and `defaultVariants` globally in `app.config.ts` (Nuxt) or `vite.config.ts` (Vue): - -```ts -// Nuxt — app.config.ts -export default defineAppConfig({ - ui: { - button: { - slots: { - base: 'font-bold' - }, - compoundVariants: [{ - color: 'neutral', - variant: 'outline', - class: 'ring-default hover:bg-accented' - }], - defaultVariants: { - color: 'neutral', - variant: 'outline' - } - } - } -}) -``` - -Tailwind Variants uses `tailwind-merge` under the hood — conflicting classes are resolved automatically. - -### Replace instead of merge - -Classes from the `ui` prop, the `class` prop, and global config are merged onto the component defaults. To replace them instead, set the slot to a function, which receives the default classes as its argument so you can reuse part of them. - -In global config it replaces the slot's own classes, so `variants` and `compoundVariants` still apply on top. In the `ui` and `class` props it runs after the variants, so it replaces the resolved classes, variants included. - -```vue - -``` - -```ts -// app.config.ts, applies to every instance -export default defineAppConfig({ - ui: { - button: { - slots: { - label: () => 'text-base font-bold' - } - } - } -}) -``` - -### Theme component - -Override theme for a section of the component tree without affecting the rest of the app. Renders no DOM element — uses `provide`/`inject`: - -```vue - - - - -``` - -### Global `defaultVariants` - -Override default `size` and `color` for **all** components at once: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - theme: { - defaultVariants: { - size: 'lg', - color: 'neutral' - } - } - } -}) -``` - -### `theme.transitions` - -Controls whether interactive components get `transition-colors`. Enabled by default. - -```ts -// nuxt.config.ts — disable transitions -export default defineNuxtConfig({ - ui: { - theme: { - transitions: false - } - } -}) -``` - -### `theme.prefix` - -When using Tailwind CSS with a prefix, configure the same prefix in Nuxt UI so component classes match: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - theme: { - prefix: 'tw' - } - } -}) -``` - -```css -/* app/assets/css/main.css */ -@import "tailwindcss" prefix(tw); -@import "@nuxt/ui"; -``` - -### Tree-shaking with `experimental.componentDetection` - -Enable automatic component detection to only generate CSS for components you actually use: - -```ts -// nuxt.config.ts -export default defineNuxtConfig({ - ui: { - experimental: { - componentDetection: true - } - } -}) -``` - -For dynamic components (e.g., ``), pass an array of component names to guarantee they're included: - -```ts -componentDetection: ['Modal', 'Dropdown', 'Popover'] -``` - -## CSS `@theme` customization - -Customize Tailwind design tokens in `main.css`: - -### Fonts - -```css -@theme { - --font-sans: 'Public Sans', system-ui, sans-serif; - --font-mono: 'JetBrains Mono', monospace; -} -``` - -In Nuxt, fonts defined here are automatically loaded by `@nuxt/fonts`. - -### Breakpoints - -```css -@theme { - --breakpoint-3xl: 1920px; -} -``` - -## CSS variables - -Nuxt UI exposes CSS variables you can override in `main.css`: - -```css -:root { - --ui-radius: 0.25rem; - --ui-container: 80rem; - --ui-header-height: 4rem; -} -``` - -### Color shade overrides - -Each semantic color defaults to shade 500 in light mode, 400 in dark mode. Override per-mode: - -```css -:root { - --ui-primary: var(--ui-color-primary-700); -} -.dark { - --ui-primary: var(--ui-color-primary-200); -} -``` - -You can use `var(--ui-color--)` to reference shades from the active palette (e.g., `var(--ui-color-neutral-800)` maps to whichever neutral palette is configured). - -### Black/white as primary - -`black` and `white` have no shades, so they can't be used in config. Set them directly: - -```css -:root { - --ui-primary: black; -} -.dark { - --ui-primary: white; -} -``` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/forms.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/forms.md deleted file mode 100644 index 2a3eda14..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/guidelines/forms.md +++ /dev/null @@ -1,233 +0,0 @@ -# Forms - -## Basic pattern - -Nuxt UI forms use `UForm` + `UFormField` + Standard Schema validation (Zod, Valibot, Yup, or Joi). - -```vue - - - -``` - -## Key rules - -- Always use `UFormField` around inputs — it connects validation errors via the `name` prop -- The `name` prop on `UFormField` must match the schema field name exactly -- Use `reactive>({})` for state — `Partial` allows empty initial values -- `@submit` only fires when validation passes -- For nested objects, use dot notation: `name="address.city"` - -## UFormField props - -| Prop | Purpose | -|---|---| -| `name` | Links to schema field for validation errors | -| `label` | Visible label text | -| `description` | Help text below the input | -| `hint` | Right-aligned hint text (e.g., "Optional") | -| `required` | Shows required indicator | -| `size` | Inherits to child input | - -## Field layout patterns - -### Vertical stack (default) - -```vue - - - - - - - - -``` - -### Inline fields with UFieldGroup - -```vue - - - - - - - - -``` - -### Grid layout - -```vue - - - - - - - - - - - -``` - -## Common field patterns - -### Select - -```vue - - - -``` - -### Checkbox - -```vue - - - -``` - -### Radio group - -```vue - - - -``` - -### Switch - -```vue - - - -``` - -### Textarea - -```vue - - - -``` - -### File upload - -```vue - - - - - - - - -``` - -### Date - -```vue - - - - - - - - -``` - -## Programmatic validation - -```vue - - - -``` - -## Form in a modal - -Use `#footer="{ close }"` scoped slot for cancel/submit actions. Wrap the modal body in `UForm` with a `type="submit"` button in the footer so validation runs on submit. - -```vue - - - - -``` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/chat.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/chat.md deleted file mode 100644 index 5ba3b6c8..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/chat.md +++ /dev/null @@ -1,263 +0,0 @@ -# Chat Layout - -Build AI chat interfaces with message streams, reasoning, tool calling, and Vercel AI SDK integration. - -## When to use - -- AI chatbot interfaces -- Customer support chat -- Any conversational UI with streaming responses - -## Setup - -### Install dependencies - -**Nuxt:** - -```bash -pnpm add ai @ai-sdk/gateway @ai-sdk/vue @comark/nuxt -``` - -**Vue (Vite):** - -```bash -pnpm add ai @ai-sdk/gateway @ai-sdk/vue @comark/vue -``` - -### Register Comark module - -**Nuxt:** - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - modules: [ - '@nuxt/ui', - '@comark/nuxt' - ] -}) -``` - -**Vue (Vite):** No module registration needed, import directly from `@comark/vue`. - -> `@comark/nuxt` (or `@comark/vue` for Vue projects) provides the `Comark` component used to render AI responses as streaming Markdown, it incrementally renders tokens as they arrive and automatically enables Nuxt UI's prose components. - -### Dark mode for syntax highlighting - -When using the `highlight` plugin, add the following CSS to your stylesheet: - -```css [main.css] -html.dark .shiki span { - color: var(--shiki-dark) !important; - background-color: var(--shiki-dark-bg) !important; - font-style: var(--shiki-dark-font-style) !important; - font-weight: var(--shiki-dark-font-weight) !important; - text-decoration: var(--shiki-dark-text-decoration) !important; -} -``` - -### Server endpoint - -Using [Vercel AI Gateway](https://vercel.com/ai-gateway) (recommended): - -```ts [server/api/chat.post.ts] -import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai' -import { gateway } from '@ai-sdk/gateway' - -export default defineEventHandler(async (event) => { - const { messages } = await readBody(event) - - const result = streamText({ - model: gateway('anthropic/claude-sonnet-5'), - instructions: 'You are a helpful assistant.', - messages: await convertToModelMessages(messages) - }) - - const stream = toUIMessageStream({ stream: result.stream }) - return createUIMessageStreamResponse({ stream }) -}) -``` - -Or with a direct provider (e.g., `pnpm add @ai-sdk/openai`): - -```ts [server/api/chat.post.ts] -import { streamText, convertToModelMessages, toUIMessageStream, createUIMessageStreamResponse } from 'ai' -import { openai } from '@ai-sdk/openai' - -export default defineEventHandler(async (event) => { - const { messages } = await readBody(event) - - const result = streamText({ - model: openai('gpt-5-nano'), - instructions: 'You are a helpful assistant.', - messages: await convertToModelMessages(messages) - }) - - const stream = toUIMessageStream({ stream: result.stream }) - return createUIMessageStreamResponse({ stream }) -}) -``` - -## Component tree - -``` -UDashboardPanel -├── #header → UDashboardNavbar -├── #body → UContainer → UChatMessages -│ ├── #content → UChatReasoning, UChatTool, Comark -│ └── #indicator (loading) -└── #footer → UContainer → UChatPrompt - └── UChatPromptSubmit -``` - -## Full page chat - -```vue [pages/chat/[id].vue] - - - -``` - -## Key components - -- `UChatMessages` — scrollable message list with auto-scroll. Props: `messages`, `status`. Slots: `#content` (per message), `#actions`, `#indicator`. -- `UChatMessage` — individual bubble. Props: `message`, `side` (`'left'`/`'right'`). -- `UChatReasoning` — collapsible reasoning block. Auto-opens during streaming, auto-closes when done. Use `isPartStreaming(part)` from `@nuxt/ui/utils/ai`. -- `UChatTool` — tool invocation status. Use `isToolStreaming(part)`. Variants: `'inline'` (default), `'card'`. -- `UChatPrompt` — enhanced textarea. Accepts all Textarea props + `error` prop. -- `UChatPromptSubmit` — submit button with automatic status handling (send/stop/reload). -- `UChatPalette` — layout wrapper for chat inside overlays. - -## Chat in a modal - -```vue - - - -``` - -## With model selector - -```vue - - - - - -``` - -## Conversation sidebar - -Combine with dashboard layout for a ChatGPT-like interface: - -```vue [layouts/dashboard.vue] - -``` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/dashboard.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/dashboard.md deleted file mode 100644 index 10d99548..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/dashboard.md +++ /dev/null @@ -1,233 +0,0 @@ -# Dashboard Layout - -Build admin interfaces with resizable sidebars, multi-panel layouts, and toolbars. - -## When to use - -- Admin panels, back-office UIs -- Email clients, project management tools -- Any app with a persistent sidebar and content panels -- Combine with chat or editor layouts for specialized dashboards - -## Component tree - -``` -UApp -└── NuxtLayout (dashboard) - └── UDashboardGroup - ├── UDashboardSidebar - │ ├── #header (logo, search button) - │ ├── #default (navigation) — receives { collapsed } slot prop - │ └── #footer (user menu) - └── NuxtPage - └── UDashboardPanel - ├── #header → UDashboardNavbar + UDashboardToolbar - ├── #body (scrollable content) - └── #footer (optional) -``` - -## Layout - -```vue [layouts/dashboard.vue] - - - -``` - -## Page - -```vue [pages/dashboard/index.vue] - - - -``` - -### Common mistakes - -- Forgetting `definePageMeta({ layout: 'dashboard' })` — the page won't use the dashboard layout without it. -- Putting content directly in `UDashboardPanel` without using `#body` slot — content won't scroll properly. -- Not handling the `collapsed` slot prop — sidebar content should adapt when collapsed (hide labels, center icons). - -## Key components - -### DashboardGroup - -Root wrapper. Manages sidebar state and persistence. - -| Prop | Default | Purpose | -|---|---|---| -| `storage` | `'cookie'` | `'cookie'`, `'localStorage'`, `false` | -| `storage-key` | `'dashboard'` | Storage key name | - -### DashboardSidebar - -Resizable, collapsible sidebar. Must be inside `DashboardGroup`. - -| Prop | Default | Purpose | -|---|---|---| -| `resizable` | `false` | Drag to resize | -| `collapsible` | `false` | Collapse when dragged to edge | -| `side` | `'left'` | `'left'` or `'right'` | -| `mode` | `'slideover'` | Mobile: `'modal'`, `'slideover'`, `'drawer'` | - -All slots receive `{ collapsed, collapse }` — `collapsed` is the boolean state, `collapse(value)` toggles it programmatically. Use `v-model:collapsed` and `v-model:open` (mobile) for state control. - -### DashboardPanel - -Content panel with `#header`, `#body` (scrollable), `#footer`, and `#default` (raw, no scroll) slots. - -### DashboardNavbar / DashboardToolbar - -Navbar: `#leading`, `#left`, `#default`, `#right` slots + `title` prop. Use `UDashboardSidebarCollapse` in `#leading` to toggle sidebar on mobile. -Toolbar: same slots, sits below navbar for filters/actions. - -### UNavigationMenu in sidebar - -Always pass `:collapsed="collapsed"` to `UNavigationMenu` inside a collapsible sidebar — it auto-hides labels and centers icons. Use `NavigationMenuItem[][]` (array of arrays) for separate groups (main nav + footer links). - -## Multi-panel (list-detail) - -```vue [pages/dashboard/inbox.vue] - - - -``` - -## With toolbar - -```vue - - - -``` - -## With search - -```vue [layouts/dashboard.vue] - -``` - -## Right sidebar - -```vue - - - - - - - - - - - -``` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/docs.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/docs.md deleted file mode 100644 index e539897e..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/docs.md +++ /dev/null @@ -1,152 +0,0 @@ -# Docs Layout - -Build documentation sites with sidebar navigation, table of contents, and surround links. - -## When to use - -- Technical documentation sites -- Knowledge bases, help centers -- Any content-heavy site with hierarchical navigation - -> Requires `@nuxt/content` — see [conventions](../guidelines/conventions.md#content-module-integration) for setup (module order + `@source`). - -## Component tree - -``` -UApp -├── UHeader -├── UMain -│ └── NuxtLayout (docs) -│ └── UPage -│ ├── #left → UPageAside → UContentNavigation -│ └── NuxtPage -│ ├── UPageHeader -│ ├── UPageBody → ContentRenderer + UContentSurround -│ └── #right → UContentToc -└── UFooter -``` - -## App shell - -```vue [app.vue] - - - -``` - -## Layout - -```vue [layouts/docs.vue] - - - -``` - -## Page - -```vue [pages/docs/[...slug].vue] - - - -``` - -### How nesting works - -The outer `UPage` in the layout handles the **left sidebar**. The inner `UPage` in the page handles the **right sidebar**. They nest correctly — this is intentional. - -### Common mistakes - -- Not providing navigation via `provide`/`inject` — the layout needs it from the app shell. -- Forgetting `UContentSearch` in app.vue — search won't work without it. -- Using `UContentSearchButton` without `UContentSearch` — the button opens search, but the search component must exist. - -## Key components - -- `UPage` — multi-column grid with `#left`, `#default`, `#right` slots -- `UPageAside` — sticky sidebar wrapper (visible from `lg` breakpoint) -- `UContentNavigation` — sidebar navigation tree from Nuxt Content -- `UContentToc` — table of contents from page headings -- `UContentSurround` — prev/next links -- `UContentSearch` / `UContentSearchButton` — search command palette -- `UPageAnchors` — simpler alternative to full TOC diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/editor.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/editor.md deleted file mode 100644 index eb224a66..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/editor.md +++ /dev/null @@ -1,153 +0,0 @@ -# Editor Layout - -Build a rich text editor with toolbars, slash commands, mentions, and drag-and-drop. - -## When to use - -- Note-taking apps, CMS editors -- Collaborative editing interfaces -- Any rich text editing need (supports JSON, HTML, and Markdown) - -## Component tree - -``` -UEditor -├── UEditorToolbar (fixed / bubble / floating) -├── UEditorDragHandle -├── UEditorSuggestionMenu -├── UEditorMentionMenu -└── UEditorEmojiMenu -``` - -## Basic editor - -```vue - - - -``` - -> If you encounter prosemirror-related errors, add prosemirror packages to `vite.optimizeDeps.include` in `nuxt.config.ts`. - -## Key components - -- `UEditor` — rich text editor. `v-model` accepts JSON (default), HTML, or Markdown via `content-type` prop. Default slot provides `{ editor, handlers }` — `editor` is the Tiptap instance, `handlers` contains action functions for toolbar/menus. -- `UEditorToolbar` — toolbar with `layout`: `'fixed'` (default), `'bubble'` (on selection), `'floating'` (on empty lines). -- `UEditorDragHandle` — block drag-and-drop handle. -- `UEditorSuggestionMenu` — slash command menu (type `/` to open). -- `UEditorMentionMenu` — `@` mention menu. -- `UEditorEmojiMenu` — emoji picker (type `:` to open). - -## Toolbar modes - -```vue - - - - - - - - -``` - -## Content types - -```vue - - - - - - - - -``` - -## With document sidebar - -Combine with Dashboard layout for a multi-document editor: - -```vue [layouts/editor.vue] - -``` - -```vue [pages/editor/[id].vue] - - - -``` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/landing.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/landing.md deleted file mode 100644 index a0d231ad..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/layouts/landing.md +++ /dev/null @@ -1,185 +0,0 @@ -# Landing Page Layout - -Build public-facing pages — landing, blog, changelog, pricing — using the Header + Main + Footer shell with Page components. - -## When to use - -- Marketing sites, product pages, company sites -- Blog and content pages -- Pricing, changelog, portfolio pages -- Any public-facing page that isn't a dashboard or documentation - -## App shell - -```vue [app.vue] - - - -``` - -### Common mistakes - -- Forgetting the `#body` slot on `UHeader` — this is the mobile menu content. Without it, mobile users have no navigation. -- Using `variant="solid"` for both header and hero buttons — the header button should be lower weight than the hero CTA. - -## Landing page - -```vue [pages/index.vue] - -``` - -## Key components - -- `UPageHero` — hero with title, description, links, and optional media. Use `orientation="horizontal"` for side-by-side layout. -- `UPageSection` — content section with headline, title, description, and `features` grid. Use `id` for anchor links. -- `UPageCTA` — call to action block. -- `UPageGrid` / `UPageCard` — card grid for features, testimonials, etc. -- `UPageFeature` — individual feature item. -- `UPageLogos` — logo wall for social proof. -- `UPricingPlans` / `UPricingTable` — pricing cards and comparison tables. -- `UFooterColumns` — multi-column footer with link groups (used inside `UFooter`). - -## Variations - -### Alternating feature sections - -```vue - - - - - - - -``` - -### Blog listing - -```vue [pages/blog/index.vue] - - - -``` - -### Changelog - -```vue [pages/changelog.vue] - - - -``` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/auth.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/auth.md deleted file mode 100644 index 57d2bdc0..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/auth.md +++ /dev/null @@ -1,162 +0,0 @@ -# Auth Forms - -## UAuthForm (recommended) - -`UAuthForm` provides a complete auth form with fields, providers, validation, and submit — no manual `UForm` + `UFormField` wiring needed. Wrap it in `UPageCard` for a polished look. - -```vue [pages/login.vue] - - - -``` - -### UAuthForm key props - -| Prop | Purpose | -|---|---| -| `title`, `description`, `icon` | Header content | -| `fields` | `AuthFormField[]` — each has `name`, `type`, `label`, `placeholder`, `required` | -| `providers` | `ButtonProps[]` — social login buttons shown above/below the form | -| `schema` | Zod/Valibot schema for validation | -| `submit` | Customize submit button: `{ label: 'Sign in', block: true }` | -| `separator` | Text between providers and fields (default: `'or'`) | - -### UAuthForm key slots - -| Slot | Purpose | -|---|---| -| `#description` | Override description (e.g., add sign-up link) | -| `#password-hint` | "Forgot password?" link on password field | -| `#validation` | Custom error display (e.g., `UAlert`) | -| `#footer` | Terms of service, sign-up link | -| `#-field` | Override a specific field's rendering | - -## Custom auth layout - -For layouts where `UAuthForm` is too opinionated, use `UCard` + `UForm` + `UFormField` directly. - -```vue [pages/login.vue] - - - -``` - -## Tips - -- Prefer `UAuthForm` with `UPageCard` for standard auth pages — handles layout, providers, validation, and submit -- Use `import * as z from 'zod'` and `z.email()` (Zod 4 syntax) -- Type the submit handler: `function onSubmit(event: FormSubmitEvent)` — access validated data via `event.data` -- Center auth forms with `flex min-h-dvh items-center justify-center` -- Place "Forgot password?" link as `#password-hint` slot on `UAuthForm`, or `#hint` slot on `UFormField` -- Social login buttons: use `providers` prop on `UAuthForm`, or add manually with `` diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/data-tables.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/data-tables.md deleted file mode 100644 index f5c81f86..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/data-tables.md +++ /dev/null @@ -1,225 +0,0 @@ -# Data Tables - -Complete patterns for displaying and managing tabular data. - -## Basic table - -```vue - - - -``` - -## With search and filters (dashboard) - -```vue - - - -``` - -## With row selection - -Row selection uses TanStack Table's `rowSelection` state — a `Record` keyed by row index. - -```vue - - - -``` - -Add a checkbox column using the `h` function. Use tri-state `modelValue` (`true`, `false`, or `'indeterminate'`) for the "select all" header: - -```ts -import { h } from 'vue' - -const UCheckbox = resolveComponent('UCheckbox') - -const columns: TableColumn[] = [{ - id: 'select', - header: ({ table }) => h(UCheckbox, { - 'modelValue': table.getIsSomePageRowsSelected() ? 'indeterminate' : table.getIsAllPageRowsSelected(), - 'onUpdate:modelValue': (value: boolean | 'indeterminate') => table.toggleAllPageRowsSelected(!!value), - 'aria-label': 'Select all' - }), - cell: ({ row }) => h(UCheckbox, { - 'modelValue': row.getIsSelected(), - 'onUpdate:modelValue': (value: boolean | 'indeterminate') => row.toggleSelected(!!value), - 'aria-label': 'Select row' - }) -}, -// ... other columns -] -``` - -## With pagination - -Use `v-model:pagination` on `UTable` with TanStack's `getPaginationRowModel`, then wire `UPagination` to the table API. `UPagination`'s `total` is total **items** (not pages) — it calculates page count from `total / items-per-page`. - -```vue - - - -``` - -## With async data (Nuxt) - -Use `status === 'pending' || status === 'idle'` for loading state — `idle` covers the initial render before `useLazyFetch` starts. - -```vue - - - -``` - -For server-side pagination: - -```vue - - - -``` - -## Tips - -- Table is built on [TanStack Table v8](https://tanstack.com/table/v8) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` -- Use `#-cell` and `#-header` template slots to customize rendering with Vue templates -- Alternatively, use the `h` function inside `header` and `cell` column properties for inline rendering -- Row data in slots is accessed via `row.original` (not `row` directly) -- Use `v-model:row-selection` for selection, `v-model:sorting` for sort state -- Wrap tables in `UDashboardPanel` with `#header` toolbar for the dashboard pattern -- For empty states, use the `#empty` slot diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/navigation.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/navigation.md deleted file mode 100644 index ef71a988..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/navigation.md +++ /dev/null @@ -1,90 +0,0 @@ -# Navigation - -Patterns for headers, sidebars, breadcrumbs, and tab navigation. - -## Header with mobile menu - -`UHeader` default slot is desktop nav, `#body` is the mobile menu. Without `#body`, mobile users have no navigation. - -```vue - - - - - - - - - -``` - -> Full app shell example in [landing layout](../layouts/landing.md). - -## Sidebar navigation (dashboard) - -See [dashboard layout](../layouts/dashboard.md) for the full sidebar pattern with `UDashboardSidebar` + `UNavigationMenu`. Key points: -- Pass `:collapsed="collapsed"` to `UNavigationMenu` inside collapsible sidebars -- Use `NavigationMenuItem[][]` (nested arrays) for separate nav groups -- Use `#footer` slot for user menu with `UDropdownMenu` - -## Breadcrumbs - -```vue - - - -``` - -## Tab navigation (within a page) - -```vue - - - -``` - diff --git a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/overlays.md b/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/overlays.md deleted file mode 100644 index 597def75..00000000 --- a/code/link-site/link-nuxt/.claude/skills/nuxt-ui/references/recipes/overlays.md +++ /dev/null @@ -1,173 +0,0 @@ -# Overlays - -Patterns for modals, slideovers, drawers, and command palettes. - -## Confirmation dialog - -```vue - - - -``` - -## Programmatic confirmation (useOverlay) - -Reusable pattern — no template state needed at the call site. - -```vue [components/ConfirmModal.vue] - - - -``` - -```ts -// Usage anywhere -const overlay = useOverlay() -const confirm = overlay.create(ConfirmModal) - -async function deleteItem(item) { - const instance = confirm.open({ - title: 'Delete item', - description: `Are you sure you want to delete "${item.name}"?` - }) - - if (await instance.result) { - // user confirmed - } -} -``` - -## Form in a slideover - -```vue - - - -``` - -## Command palette - -```vue - - - -``` - -## Drawer (bottom sheet) - -```vue - - - -``` - diff --git a/code/link-site/link-nuxt/.editorconfig b/code/link-site/link-nuxt/.editorconfig deleted file mode 100644 index 91422397..00000000 --- a/code/link-site/link-nuxt/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -# editorconfig.org -root = true - -[*] -indent_size = 2 -indent_style = space -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -trim_trailing_whitespace = false diff --git a/code/link-site/link-nuxt/.github/workflows/ci.yml b/code/link-site/link-nuxt/.github/workflows/ci.yml deleted file mode 100644 index 7b6a2418..00000000 --- a/code/link-site/link-nuxt/.github/workflows/ci.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: ci - -on: push - -jobs: - ci: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest] - node: [22] - - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Install pnpm - uses: pnpm/action-setup@v6 - - - name: Install node - uses: actions/setup-node@v7 - with: - node-version: ${{ matrix.node }} - cache: pnpm - - - name: Install dependencies - run: pnpm install - - - name: Lint - run: pnpm run lint - - - name: Typecheck - run: pnpm run typecheck diff --git a/code/link-site/link-nuxt/.gitignore b/code/link-site/link-nuxt/.gitignore deleted file mode 100644 index 4a7f73a2..00000000 --- a/code/link-site/link-nuxt/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Nuxt dev/build outputs -.output -.data -.nuxt -.nitro -.cache -dist - -# Node dependencies -node_modules - -# Logs -logs -*.log - -# Misc -.DS_Store -.fleet -.idea - -# Local env files -.env -.env.* -!.env.example diff --git a/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T12-50-58-825Z.yml b/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T12-50-58-825Z.yml deleted file mode 100644 index 607e3490..00000000 --- a/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T12-50-58-825Z.yml +++ /dev/null @@ -1,158 +0,0 @@ -- generic [ref=f10e3]: - - banner [ref=f10e4]: - - generic [ref=f10e5]: - - generic [ref=f10e6]: - - link "链通物流": - - /url: / - - link "链通物流" [ref=f10e7] [cursor=pointer]: - - /url: / - - navigation [ref=f10e11]: - - list [ref=f10e13]: - - listitem [ref=f10e14]: - - link "首页" [ref=f10e15] [cursor=pointer]: - - /url: / - - listitem [ref=f10e18]: - - link "企业目录" [ref=f10e19] [cursor=pointer]: - - /url: /directory - - listitem [ref=f10e22]: - - link "资讯" [ref=f10e23] [cursor=pointer]: - - /url: /news - - generic [ref=f10e26]: - - button "切换到深色模式" [ref=f10e27] - - textbox "搜索企业" [ref=f10e30]: - - /placeholder: 搜索企业… - - button "消息(示例阶段未开放)" [disabled] [ref=f10e33] - - link "入驻平台" [ref=f10e35] [cursor=pointer]: - - /url: /directory - - main [ref=f10e38]: - - generic [ref=f10e39]: - - navigation "breadcrumb" [ref=f10e42]: - - list [ref=f10e43]: - - listitem [ref=f10e44]: - - link "链通物流" [ref=f10e45] [cursor=pointer]: - - /url: / - - listitem [ref=f10e47] - - listitem [ref=f10e49]: - - link "企业目录" [ref=f10e50] [cursor=pointer]: - - /url: /directory - - listitem [ref=f10e52] - - listitem [ref=f10e54]: - - generic [ref=f10e55]: 环洋国际货运代理(上海)有限公司 - - generic [ref=f10e59]: - - generic [ref=f10e60]: 环 - - generic [ref=f10e61]: - - generic [ref=f10e62]: - - heading "环洋国际货运代理(上海)有限公司" [level=1] [ref=f10e63] - - generic [ref=f10e64]: 平台认证 - - paragraph [ref=f10e66]: 让全球贸易更简单 - - generic [ref=f10e67]: - - generic [ref=f10e68]: 上海 - - generic [ref=f10e70]: · - - generic [ref=f10e71]: 成立于 2008 - - generic [ref=f10e72]: · - - generic [ref=f10e73]: 120-200 人 - - generic [ref=f10e74]: - - generic [ref=f10e75]: 美线 - - generic [ref=f10e76]: 欧线 - - link "在线沟通" [ref=f10e78] [cursor=pointer]: - - /url: /company/huanyang/contact - - navigation [ref=f10e83]: - - link "主页" [ref=f10e84] [cursor=pointer]: - - /url: /company/huanyang - - link "关于" [ref=f10e85] [cursor=pointer]: - - /url: /company/huanyang/about - - link "文章" [ref=f10e86] [cursor=pointer]: - - /url: /company/huanyang/articles - - link "服务" [ref=f10e87] [cursor=pointer]: - - /url: /company/huanyang/services - - link "联系" [ref=f10e88] [cursor=pointer]: - - /url: /company/huanyang/contact - - generic [ref=f10e89]: - - generic [ref=f10e91]: - - generic [ref=f10e92]: - - paragraph [ref=f10e93]: 关于我们 / ABOUT US - - heading "环洋国际货运代理(上海)有限公司" [level=2] [ref=f10e94] - - paragraph [ref=f10e95]: 环洋国际货运代理(上海)有限公司成立于 2008 年,总部位于上海,在宁波、青岛、深圳设有分公司,是一家以欧美远洋航线为核心的国际货运代理企业。 - - generic [ref=f10e96]: - - generic [ref=f10e97]: 成立于 2008 年 - - generic [ref=f10e99]: 120-200 人 - - generic [ref=f10e101]: 上海 - - link "了解更多" [ref=f10e103] [cursor=pointer]: - - /url: /company/huanyang/about - - generic [ref=f10e106]: - - generic [ref=f10e107]: - - paragraph [ref=f10e108]: 海运整箱 - - paragraph [ref=f10e109]: 主营服务 - - generic [ref=f10e110]: - - paragraph [ref=f10e111]: 海运拼箱 - - paragraph [ref=f10e112]: 主营服务 - - generic [ref=f10e113]: - - paragraph [ref=f10e114]: 报关报检 - - paragraph [ref=f10e115]: 主营服务 - - generic [ref=f10e117]: - - generic [ref=f10e118]: - - paragraph [ref=f10e119]: 主营业务 / SERVICES - - heading "服务项目" [level=2] [ref=f10e120] - - generic [ref=f10e121]: - - link [ref=f10e122] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "海运整箱(FCL)" [level=3] [ref=f10e125] - - paragraph [ref=f10e126]: 美西 / 美东 / 北欧 / 地中海基本港及内陆点整箱运输,20GP / 40GP / 40HQ / 45HQ 全柜型。 - - link [ref=f10e127] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "海运拼箱(LCL)" [level=3] [ref=f10e130] - - paragraph [ref=f10e131]: 欧美主要港口每周固定拼箱航班,最低 1CBM 起运,目的港网络覆盖 40+ 城市。 - - link [ref=f10e132] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "报关报检" [level=3] [ref=f10e135] - - paragraph [ref=f10e136]: 一般贸易、跨境电商出口报关,产地证、危包证等配套单证代办。 - - link [ref=f10e137] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "门到门物流" [level=3] [ref=f10e140] - - paragraph [ref=f10e141]: 起运地提货、仓储装箱、港口操作、目的国清关派送一站式服务。 - - generic [ref=f10e142]: - - generic [ref=f10e143]: - - paragraph [ref=f10e144]: 为什么选择我们 / WHY US - - heading "核心优势" [level=2] [ref=f10e145] - - generic [ref=f10e146]: - - generic [ref=f10e147]: - - heading "欧美航线直约" [level=3] [ref=f10e150] - - paragraph [ref=f10e151]: 与主流船司直签长约,美线 / 欧线运价与舱位双保障。 - - generic [ref=f10e152]: - - heading "自建报关团队" [level=3] [ref=f10e155] - - paragraph [ref=f10e156]: 上海、宁波口岸全品类报关报检,单证当日出单。 - - generic [ref=f10e157]: - - heading "全流程可视化" [level=3] [ref=f10e160] - - paragraph [ref=f10e161]: 订舱、装箱、进港、开船、到港节点在线可查。 - - generic [ref=f10e163]: - - generic [ref=f10e164]: - - generic [ref=f10e165]: - - paragraph [ref=f10e166]: 公司动态 / NEWS - - heading "新闻资讯" [level=2] [ref=f10e167] - - link "更多文章" [ref=f10e168] [cursor=pointer]: - - /url: /company/huanyang/articles - - generic [ref=f10e171]: - - link "行业资讯 2026-08-26 5 分钟 红海局势缓和后的欧线运价走势:旺季前还能涨多少? 欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。" [ref=f10e172] [cursor=pointer]: - - /url: /news/red-sea-rerouting-2026 - - generic [ref=f10e173]: - - generic [ref=f10e174]: 行业资讯 - - generic [ref=f10e175]: 2026-08-26 - - generic [ref=f10e177]: 5 分钟 - - heading "红海局势缓和后的欧线运价走势:旺季前还能涨多少?" [level=3] [ref=f10e179] - - paragraph [ref=f10e180]: 欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。 - - link "行业资讯 2026-08-22 4 分钟 美西长滩港劳工谈判落地,塞港风险解除? 劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。" [ref=f10e181] [cursor=pointer]: - - /url: /news/us-west-lcr-2026 - - generic [ref=f10e182]: - - generic [ref=f10e183]: 行业资讯 - - generic [ref=f10e184]: 2026-08-22 - - generic [ref=f10e186]: 4 分钟 - - heading "美西长滩港劳工谈判落地,塞港风险解除?" [level=3] [ref=f10e188] - - paragraph [ref=f10e189]: 劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。 - - contentinfo [ref=f10e190]: - - generic [ref=f10e191]: - - generic [ref=f10e192]: - - link "企业目录" [ref=f10e193] [cursor=pointer]: - - /url: /directory - - link "行业资讯" [ref=f10e195] [cursor=pointer]: - - /url: /news - - paragraph [ref=f10e198]: 链通物流 · 物流企业连接平台 © 2026 \ No newline at end of file diff --git a/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T12-57-42-004Z.yml b/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T12-57-42-004Z.yml deleted file mode 100644 index 10b158b9..00000000 --- a/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T12-57-42-004Z.yml +++ /dev/null @@ -1,148 +0,0 @@ -- generic [ref=f13e3]: - - banner [ref=f13e4]: - - generic [ref=f13e6]: - - link "链通物流" [ref=f13e7] [cursor=pointer]: - - /url: / - - navigation [ref=f13e10]: - - link "首页" [ref=f13e11] [cursor=pointer]: - - /url: / - - link "企业目录" [ref=f13e12] [cursor=pointer]: - - /url: /directory - - link "资讯" [ref=f13e13] [cursor=pointer]: - - /url: /news - - generic [ref=f13e14]: - - textbox "搜索企业…" [ref=f13e16] - - link "入驻平台" [ref=f13e19] [cursor=pointer]: - - /url: /directory - - main [ref=f13e22]: - - generic [ref=f13e23]: - - navigation "breadcrumb" [ref=f13e26]: - - list [ref=f13e27]: - - listitem [ref=f13e28]: - - link "链通物流" [ref=f13e29] [cursor=pointer]: - - /url: / - - listitem [ref=f13e31] - - listitem [ref=f13e33]: - - link "企业目录" [ref=f13e34] [cursor=pointer]: - - /url: /directory - - listitem [ref=f13e36] - - listitem [ref=f13e38]: - - generic [ref=f13e39]: 环洋国际货运代理(上海)有限公司 - - generic [ref=f13e44]: - - generic [ref=f13e45]: 环 - - generic [ref=f13e46]: - - generic [ref=f13e47]: - - heading "环洋国际货运代理(上海)有限公司" [level=1] [ref=f13e48] - - generic [ref=f13e49]: 平台认证 - - paragraph [ref=f13e51]: 让全球贸易更简单 - - generic [ref=f13e52]: - - generic [ref=f13e53]: 上海 - - generic [ref=f13e55]: · - - generic [ref=f13e56]: 成立于 2008 - - generic [ref=f13e57]: · - - generic [ref=f13e58]: 120-200 人 - - generic [ref=f13e59]: - - generic [ref=f13e60]: 美线 - - generic [ref=f13e61]: 欧线 - - link "在线沟通" [ref=f13e63] [cursor=pointer]: - - /url: /company/huanyang/contact - - navigation [ref=f13e68]: - - link "主页" [ref=f13e69] [cursor=pointer]: - - /url: /company/huanyang - - link "关于" [ref=f13e70] [cursor=pointer]: - - /url: /company/huanyang/about - - link "文章" [ref=f13e71] [cursor=pointer]: - - /url: /company/huanyang/articles - - link "服务" [ref=f13e72] [cursor=pointer]: - - /url: /company/huanyang/services - - link "联系" [ref=f13e73] [cursor=pointer]: - - /url: /company/huanyang/contact - - generic [ref=f13e74]: - - generic [ref=f13e76]: - - generic [ref=f13e77]: - - paragraph [ref=f13e78]: 关于我们 / ABOUT US - - heading "环洋国际货运代理(上海)有限公司" [level=2] [ref=f13e79] - - paragraph [ref=f13e80]: 环洋国际货运代理(上海)有限公司成立于 2008 年,总部位于上海,在宁波、青岛、深圳设有分公司,是一家以欧美远洋航线为核心的国际货运代理企业。 - - generic [ref=f13e81]: - - generic [ref=f13e82]: 成立于 2008 年 - - generic [ref=f13e84]: 120-200 人 - - generic [ref=f13e86]: 上海 - - link "了解更多" [ref=f13e88] [cursor=pointer]: - - /url: /company/huanyang/about - - generic [ref=f13e91]: - - generic [ref=f13e92]: - - paragraph [ref=f13e93]: 海运整箱 - - paragraph [ref=f13e94]: 主营服务 - - generic [ref=f13e95]: - - paragraph [ref=f13e96]: 海运拼箱 - - paragraph [ref=f13e97]: 主营服务 - - generic [ref=f13e98]: - - paragraph [ref=f13e99]: 报关报检 - - paragraph [ref=f13e100]: 主营服务 - - generic [ref=f13e102]: - - generic [ref=f13e103]: - - paragraph [ref=f13e104]: 主营业务 / SERVICES - - heading "服务项目" [level=2] [ref=f13e105] - - generic [ref=f13e106]: - - link [ref=f13e107] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "海运整箱(FCL)" [level=3] [ref=f13e110] - - paragraph [ref=f13e111]: 美西 / 美东 / 北欧 / 地中海基本港及内陆点整箱运输,20GP / 40GP / 40HQ / 45HQ 全柜型。 - - link [ref=f13e112] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "海运拼箱(LCL)" [level=3] [ref=f13e115] - - paragraph [ref=f13e116]: 欧美主要港口每周固定拼箱航班,最低 1CBM 起运,目的港网络覆盖 40+ 城市。 - - link [ref=f13e117] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "报关报检" [level=3] [ref=f13e120] - - paragraph [ref=f13e121]: 一般贸易、跨境电商出口报关,产地证、危包证等配套单证代办。 - - link [ref=f13e122] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "门到门物流" [level=3] [ref=f13e125] - - paragraph [ref=f13e126]: 起运地提货、仓储装箱、港口操作、目的国清关派送一站式服务。 - - generic [ref=f13e127]: - - generic [ref=f13e128]: - - paragraph [ref=f13e129]: 为什么选择我们 / WHY US - - heading "核心优势" [level=2] [ref=f13e130] - - generic [ref=f13e131]: - - generic [ref=f13e132]: - - heading "欧美航线直约" [level=3] [ref=f13e135] - - paragraph [ref=f13e136]: 与主流船司直签长约,美线 / 欧线运价与舱位双保障。 - - generic [ref=f13e137]: - - heading "自建报关团队" [level=3] [ref=f13e140] - - paragraph [ref=f13e141]: 上海、宁波口岸全品类报关报检,单证当日出单。 - - generic [ref=f13e142]: - - heading "全流程可视化" [level=3] [ref=f13e145] - - paragraph [ref=f13e146]: 订舱、装箱、进港、开船、到港节点在线可查。 - - generic [ref=f13e148]: - - generic [ref=f13e149]: - - generic [ref=f13e150]: - - paragraph [ref=f13e151]: 公司动态 / NEWS - - heading "新闻资讯" [level=2] [ref=f13e152] - - link "更多文章" [ref=f13e153] [cursor=pointer]: - - /url: /company/huanyang/articles - - generic [ref=f13e156]: - - link "行业资讯 2026-08-26 5 分钟 红海局势缓和后的欧线运价走势:旺季前还能涨多少? 欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。" [ref=f13e157] [cursor=pointer]: - - /url: /news/red-sea-rerouting-2026 - - generic [ref=f13e158]: - - generic [ref=f13e159]: 行业资讯 - - generic [ref=f13e160]: 2026-08-26 - - generic [ref=f13e162]: 5 分钟 - - heading "红海局势缓和后的欧线运价走势:旺季前还能涨多少?" [level=3] [ref=f13e164] - - paragraph [ref=f13e165]: 欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。 - - link "行业资讯 2026-08-22 4 分钟 美西长滩港劳工谈判落地,塞港风险解除? 劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。" [ref=f13e166] [cursor=pointer]: - - /url: /news/us-west-lcr-2026 - - generic [ref=f13e167]: - - generic [ref=f13e168]: 行业资讯 - - generic [ref=f13e169]: 2026-08-22 - - generic [ref=f13e171]: 4 分钟 - - heading "美西长滩港劳工谈判落地,塞港风险解除?" [level=3] [ref=f13e173] - - paragraph [ref=f13e174]: 劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。 - - contentinfo [ref=f13e175]: - - generic [ref=f13e176]: - - generic [ref=f13e177]: - - link "企业目录" [ref=f13e178] [cursor=pointer]: - - /url: /directory - - link "行业资讯" [ref=f13e180] [cursor=pointer]: - - /url: /news - - paragraph [ref=f13e183]: 链通物流 · 物流企业连接平台 © 2026 \ No newline at end of file diff --git a/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T13-24-59-639Z.yml b/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T13-24-59-639Z.yml deleted file mode 100644 index f22a21fb..00000000 --- a/code/link-site/link-nuxt/.playwright-cli/page-2026-08-31T13-24-59-639Z.yml +++ /dev/null @@ -1,124 +0,0 @@ -- generic [ref=f14e3]: - - main [ref=f14e4]: - - generic [ref=f14e5]: - - generic [ref=f14e8]: - - link "链通物流" [ref=f14e10] [cursor=pointer]: - - /url: / - - navigation [ref=f14e13]: - - link "主页" [ref=f14e14] [cursor=pointer]: - - /url: /company/huanyang - - link "关于" [ref=f14e15] [cursor=pointer]: - - /url: /company/huanyang/about - - link "服务" [ref=f14e16] [cursor=pointer]: - - /url: /company/huanyang/services - - link "新闻" [ref=f14e17] [cursor=pointer]: - - /url: /company/huanyang/articles - - link "联系" [ref=f14e18] [cursor=pointer]: - - /url: /company/huanyang/contact - - generic [ref=f14e22]: - - generic [ref=f14e23]: 环 - - generic [ref=f14e24]: - - generic [ref=f14e25]: - - heading "环洋国际货运代理(上海)有限公司" [level=1] [ref=f14e26] - - generic [ref=f14e27]: 平台认证 - - paragraph [ref=f14e29]: 让全球贸易更简单 - - generic [ref=f14e30]: - - generic [ref=f14e31]: 上海 - - generic [ref=f14e33]: · - - generic [ref=f14e34]: 成立于 2008 - - generic [ref=f14e35]: · - - generic [ref=f14e36]: 120-200 人 - - generic [ref=f14e37]: - - generic [ref=f14e38]: 美线 - - generic [ref=f14e39]: 欧线 - - link "在线咨询" [ref=f14e41] [cursor=pointer]: - - /url: /company/huanyang/contact - - generic [ref=f14e44]: - - generic [ref=f14e46]: - - generic [ref=f14e47]: - - paragraph [ref=f14e48]: 关于我们 / ABOUT US - - heading "环洋国际货运代理(上海)有限公司" [level=2] [ref=f14e49] - - paragraph [ref=f14e50]: 环洋国际货运代理(上海)有限公司成立于 2008 年,总部位于上海,在宁波、青岛、深圳设有分公司,是一家以欧美远洋航线为核心的国际货运代理企业。 - - generic [ref=f14e51]: - - generic [ref=f14e52]: 成立于 2008 年 - - generic [ref=f14e54]: 120-200 人 - - generic [ref=f14e56]: 上海 - - link "了解更多" [ref=f14e58] [cursor=pointer]: - - /url: /company/huanyang/about - - generic [ref=f14e61]: - - generic [ref=f14e62]: - - paragraph [ref=f14e63]: 海运整箱 - - paragraph [ref=f14e64]: 主营服务 - - generic [ref=f14e65]: - - paragraph [ref=f14e66]: 海运拼箱 - - paragraph [ref=f14e67]: 主营服务 - - generic [ref=f14e68]: - - paragraph [ref=f14e69]: 报关报检 - - paragraph [ref=f14e70]: 主营服务 - - generic [ref=f14e72]: - - generic [ref=f14e73]: - - paragraph [ref=f14e74]: 主营业务 / SERVICES - - heading "服务项目" [level=2] [ref=f14e75] - - generic [ref=f14e76]: - - link [ref=f14e77] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "海运整箱(FCL)" [level=3] [ref=f14e80] - - paragraph [ref=f14e81]: 美西 / 美东 / 北欧 / 地中海基本港及内陆点整箱运输,20GP / 40GP / 40HQ / 45HQ 全柜型。 - - link [ref=f14e82] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "海运拼箱(LCL)" [level=3] [ref=f14e85] - - paragraph [ref=f14e86]: 欧美主要港口每周固定拼箱航班,最低 1CBM 起运,目的港网络覆盖 40+ 城市。 - - link [ref=f14e87] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "报关报检" [level=3] [ref=f14e90] - - paragraph [ref=f14e91]: 一般贸易、跨境电商出口报关,产地证、危包证等配套单证代办。 - - link [ref=f14e92] [cursor=pointer]: - - /url: /company/huanyang/services - - heading "门到门物流" [level=3] [ref=f14e95] - - paragraph [ref=f14e96]: 起运地提货、仓储装箱、港口操作、目的国清关派送一站式服务。 - - generic [ref=f14e97]: - - generic [ref=f14e98]: - - paragraph [ref=f14e99]: 为什么选择我们 / WHY US - - heading "核心优势" [level=2] [ref=f14e100] - - generic [ref=f14e101]: - - generic [ref=f14e102]: - - heading "欧美航线直约" [level=3] [ref=f14e105] - - paragraph [ref=f14e106]: 与主流船司直签长约,美线 / 欧线运价与舱位双保障。 - - generic [ref=f14e107]: - - heading "自建报关团队" [level=3] [ref=f14e110] - - paragraph [ref=f14e111]: 上海、宁波口岸全品类报关报检,单证当日出单。 - - generic [ref=f14e112]: - - heading "全流程可视化" [level=3] [ref=f14e115] - - paragraph [ref=f14e116]: 订舱、装箱、进港、开船、到港节点在线可查。 - - generic [ref=f14e118]: - - generic [ref=f14e119]: - - generic [ref=f14e120]: - - paragraph [ref=f14e121]: 公司动态 / NEWS - - heading "新闻资讯" [level=2] [ref=f14e122] - - link "更多文章" [ref=f14e123] [cursor=pointer]: - - /url: /company/huanyang/articles - - generic [ref=f14e126]: - - link "行业资讯 2026-08-26 5 分钟 红海局势缓和后的欧线运价走势:旺季前还能涨多少? 欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。" [ref=f14e127] [cursor=pointer]: - - /url: /news/red-sea-rerouting-2026 - - generic [ref=f14e128]: - - generic [ref=f14e129]: 行业资讯 - - generic [ref=f14e130]: 2026-08-26 - - generic [ref=f14e132]: 5 分钟 - - heading "红海局势缓和后的欧线运价走势:旺季前还能涨多少?" [level=3] [ref=f14e134] - - paragraph [ref=f14e135]: 欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。 - - link "行业资讯 2026-08-22 4 分钟 美西长滩港劳工谈判落地,塞港风险解除? 劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。" [ref=f14e136] [cursor=pointer]: - - /url: /news/us-west-lcr-2026 - - generic [ref=f14e137]: - - generic [ref=f14e138]: 行业资讯 - - generic [ref=f14e139]: 2026-08-22 - - generic [ref=f14e141]: 4 分钟 - - heading "美西长滩港劳工谈判落地,塞港风险解除?" [level=3] [ref=f14e143] - - paragraph [ref=f14e144]: 劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。 - - contentinfo [ref=f14e145]: - - generic [ref=f14e146]: - - generic [ref=f14e147]: - - link "企业目录" [ref=f14e148] [cursor=pointer]: - - /url: /directory - - link "行业资讯" [ref=f14e150] [cursor=pointer]: - - /url: /news - - paragraph [ref=f14e153]: 链通物流 · 物流企业连接平台 © 2026 \ No newline at end of file diff --git a/code/link-site/link-nuxt/CLAUDE.md b/code/link-site/link-nuxt/CLAUDE.md deleted file mode 100644 index c9201ba2..00000000 --- a/code/link-site/link-nuxt/CLAUDE.md +++ /dev/null @@ -1,28 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project - -A Nuxt 4 application built on Nuxt UI v4 (Tailwind CSS v4, TypeScript). Currently the Nuxt UI starter template with a single landing page (`app/pages/index.vue`); the repo is named `link-nuxt` under `link-site`. - -## Commands - -```bash -pnpm install # install dependencies (runs `nuxt prepare` via postinstall) -pnpm dev # dev server on http://localhost:3000 -pnpm build # production build -pnpm preview # preview production build -pnpm lint # ESLint over the whole repo -pnpm typecheck # nuxt typecheck (vue-tsc) -``` - -There is no test setup. CI (`.github/workflows/ci.yml`) runs lint + typecheck on Node 22 with pnpm — both must pass before a change is considered done. - -## Architecture - -- Nuxt 4 directory structure: app code lives in `app/` (`app.vue` shell, `app/pages/`, `app/components/`, `app/assets/css/main.css`, `app/app.config.ts`). -- UI is entirely Nuxt UI v4 components (`UApp`, `UHeader`, `UPageHero`, etc.). The `nuxt-ui` skill in `.claude/skills/` is the reference for component usage, selection guidelines, and layout recipes — consult it before building UI. -- Theming: primary/neutral colors set in `app/app.config.ts` (`ui.colors`); the primary `green` palette is overridden in `app/assets/css/main.css` via `@theme static` (Tailwind v4 CSS-first config — no `tailwind.config` file). -- `nuxt.config.ts` prerenders `/` (SSG) and pins ESLint stylistic rules: no trailing commas, 1tbs braces. Keep new code consistent with this. -- `tsconfig.json` only references generated configs under `.nuxt/` — don't edit it directly; run `pnpm install` or `nuxt prepare` to regenerate. diff --git a/code/link-site/link-nuxt/LICENSE b/code/link-site/link-nuxt/LICENSE deleted file mode 100644 index 3a3b2d24..00000000 --- a/code/link-site/link-nuxt/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Nuxt UI Templates - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/code/link-site/link-nuxt/README.md b/code/link-site/link-nuxt/README.md deleted file mode 100644 index caf51f47..00000000 --- a/code/link-site/link-nuxt/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Nuxt Starter Template - -[![Nuxt UI](https://img.shields.io/badge/Made%20with-Nuxt%20UI-00DC82?logo=nuxt&labelColor=020420)](https://ui.nuxt.com) - -Use this template to get started with [Nuxt UI](https://ui.nuxt.com) quickly. - -- [Live demo](https://starter-template.nuxt.dev/) -- [Documentation](https://ui.nuxt.com/docs/getting-started/installation/nuxt) - - - - - - Nuxt Starter Template - - - -> The starter template for Vue is on https://github.com/nuxt-ui-templates/starter-vue. - -## Quick Start - -```bash [Terminal] -npm create nuxt@latest -- -t ui -``` - -## Deploy your own - -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-name=starter&repository-url=https%3A%2F%2Fgithub.com%2Fnuxt-ui-templates%2Fstarter&demo-image=https%3A%2F%2Fui.nuxt.com%2Fassets%2Ftemplates%2Fnuxt%2Fstarter-dark.png&demo-url=https%3A%2F%2Fstarter-template.nuxt.dev%2F&demo-title=Nuxt%20Starter%20Template&demo-description=A%20minimal%20template%20to%20get%20started%20with%20Nuxt%20UI.) - -## Setup - -Make sure to install the dependencies: - -```bash -pnpm install -``` - -## Development Server - -Start the development server on `http://localhost:3000`: - -```bash -pnpm dev -``` - -## Production - -Build the application for production: - -```bash -pnpm build -``` - -Locally preview production build: - -```bash -pnpm preview -``` - -Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. - -## Renovate integration - -Install [Renovate GitHub app](https://github.com/apps/renovate/installations/select_target) on your repository and you are good to go. diff --git a/code/link-site/link-nuxt/app/app.config.ts b/code/link-site/link-nuxt/app/app.config.ts deleted file mode 100644 index d1a42c74..00000000 --- a/code/link-site/link-nuxt/app/app.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default defineAppConfig({ - ui: { - colors: { - primary: 'blue', - neutral: 'slate' - } - } -}) diff --git a/code/link-site/link-nuxt/app/app.vue b/code/link-site/link-nuxt/app/app.vue deleted file mode 100644 index 1629cff4..00000000 --- a/code/link-site/link-nuxt/app/app.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/assets/css/main.css b/code/link-site/link-nuxt/app/assets/css/main.css deleted file mode 100644 index 11ba1d0b..00000000 --- a/code/link-site/link-nuxt/app/assets/css/main.css +++ /dev/null @@ -1,6 +0,0 @@ -@import "tailwindcss"; -@import "@nuxt/ui"; - -@theme static { - --font-sans: 'Public Sans', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif; -} diff --git a/code/link-site/link-nuxt/app/components/ArticleCard.vue b/code/link-site/link-nuxt/app/components/ArticleCard.vue deleted file mode 100644 index 6586add5..00000000 --- a/code/link-site/link-nuxt/app/components/ArticleCard.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/components/CompanyCard.vue b/code/link-site/link-nuxt/app/components/CompanyCard.vue deleted file mode 100644 index a0bb84a1..00000000 --- a/code/link-site/link-nuxt/app/components/CompanyCard.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/components/CompanyIdentityHeader.vue b/code/link-site/link-nuxt/app/components/CompanyIdentityHeader.vue deleted file mode 100644 index d0811507..00000000 --- a/code/link-site/link-nuxt/app/components/CompanyIdentityHeader.vue +++ /dev/null @@ -1,93 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/components/CompanyLogo.vue b/code/link-site/link-nuxt/app/components/CompanyLogo.vue deleted file mode 100644 index 98eacea5..00000000 --- a/code/link-site/link-nuxt/app/components/CompanyLogo.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/components/CompanyPageBanner.vue b/code/link-site/link-nuxt/app/components/CompanyPageBanner.vue deleted file mode 100644 index 91ca8286..00000000 --- a/code/link-site/link-nuxt/app/components/CompanyPageBanner.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/components/CompanyPageTabs.vue b/code/link-site/link-nuxt/app/components/CompanyPageTabs.vue deleted file mode 100644 index 955260a1..00000000 --- a/code/link-site/link-nuxt/app/components/CompanyPageTabs.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/data/mock.ts b/code/link-site/link-nuxt/app/data/mock.ts deleted file mode 100644 index e46a12c8..00000000 --- a/code/link-site/link-nuxt/app/data/mock.ts +++ /dev/null @@ -1,414 +0,0 @@ -// ───────────────────────────────────────────────────────────── -// Mock 数据(示例阶段,未接后端) -// 对应《需求分析.md》中的字典 / 企业空间 / 资讯流模型 -// ───────────────────────────────────────────────────────────── - -export interface Company { - slug: string - name: string - slogan: string - verified: boolean - region: string - city: string - routes: string[] - services: string[] - established: number - employees: string - color: string - description: string - about: string[] - strengths: { title: string, description: string, icon: string }[] - servicesDetail: { name: string, description: string }[] - contact: { - phone: string - email: string - address: string - hours: string - } -} - -export interface Article { - id: string - companySlug: string - category: string - title: string - summary: string - content: string[] - date: string - readMinutes: number -} - -// ── 平台运营字典 ────────────────────────────────────────────── - -export const routeOptions = ['美线', '欧线', '东南亚线', '中东线', '日韩线', '非洲线', '澳新线', '中南美线'] - -export const serviceOptions = ['海运整箱', '海运拼箱', '空运', '铁路联运', '公路运输', '报关报检', '仓储服务', '跨境电商物流'] - -export const regionOptions = ['华东', '华南', '华北', '西北', '西南', '东北'] - -export const articleCategories = ['行业资讯', '公司动态', '案例分享'] - -// ── 企业数据 ────────────────────────────────────────────────── - -export const companies: Company[] = [ - { - slug: 'huanyang', - name: '环洋国际货运代理(上海)有限公司', - slogan: '让全球贸易更简单', - verified: true, - region: '华东', - city: '上海', - routes: ['美线', '欧线'], - services: ['海运整箱', '海运拼箱', '报关报检'], - established: 2008, - employees: '120-200 人', - color: 'blue', - description: '深耕欧美航线十七年,提供海运整箱、拼箱及全套报关报检服务,上海港月均出货 2000+ TEU。', - about: [ - '环洋国际货运代理(上海)有限公司成立于 2008 年,总部位于上海,在宁波、青岛、深圳设有分公司,是一家以欧美远洋航线为核心的国际货运代理企业。', - '公司持有 NVOCC 无船承运人资质,与多家主流船公司签订长期运价协议,美西、美东及北欧基本港舱位稳定,旺季保障能力强。', - '自建报关行与单证团队,覆盖上海、宁波口岸的全品类报关报检,跨境电商 9610 / 9710 出口申报经验丰富。' - ], - strengths: [ - { title: '欧美航线直约', description: '与主流船司直签长约,美线 / 欧线运价与舱位双保障。', icon: 'i-lucide-ship' }, - { title: '自建报关团队', description: '上海、宁波口岸全品类报关报检,单证当日出单。', icon: 'i-lucide-file-check' }, - { title: '全流程可视化', description: '订舱、装箱、进港、开船、到港节点在线可查。', icon: 'i-lucide-radar' } - ], - servicesDetail: [ - { name: '海运整箱(FCL)', description: '美西 / 美东 / 北欧 / 地中海基本港及内陆点整箱运输,20GP / 40GP / 40HQ / 45HQ 全柜型。' }, - { name: '海运拼箱(LCL)', description: '欧美主要港口每周固定拼箱航班,最低 1CBM 起运,目的港网络覆盖 40+ 城市。' }, - { name: '报关报检', description: '一般贸易、跨境电商出口报关,产地证、危包证等配套单证代办。' }, - { name: '门到门物流', description: '起运地提货、仓储装箱、港口操作、目的国清关派送一站式服务。' } - ], - contact: { - phone: '021-6600 XXXX', - email: 'sales@huanyang-logistics.example.com', - address: '上海市浦东新区世纪大道 1200 号 XX 大厦 15 层', - hours: '周一至周五 09:00 - 18:00' - } - }, - { - slug: 'pengcheng', - name: '鹏城跨境供应链(深圳)有限公司', - slogan: '跨境电商物流专家', - verified: true, - region: '华南', - city: '深圳', - routes: ['东南亚线', '美线'], - services: ['跨境电商物流', '海运拼箱', '仓储服务'], - established: 2014, - employees: '80-120 人', - color: 'orange', - description: '专注东南亚及美国跨境电商物流,海外仓 + 专线小包双轨服务,深圳日均处理订单 3 万+。', - about: [ - '鹏城跨境供应链成立于 2014 年,总部深圳,依托珠三角制造产业带,专注跨境电商物流解决方案。', - '公司在深圳、东莞运营两个共 4 万平米的集货仓,提供贴标、质检、拍照等增值服务;在美国洛杉矶、东南亚多国布局合作海外仓。', - '主营 Shopee / Lazada / TikTok / Amazon 平台头程及海外仓履约,专线小包时效稳定,尾程渠道资源丰富。' - ], - strengths: [ - { title: '东南亚专线', description: '新加坡 / 马来 / 泰国 / 越南专线,6-10 天妥投。', icon: 'i-lucide-globe' }, - { title: '海外仓网络', description: '洛杉矶 + 东南亚多国仓储,一件代发当日出库。', icon: 'i-lucide-warehouse' }, - { title: '电商系统对接', description: '主流 ERP / 平台 API 直连,订单自动流转。', icon: 'i-lucide-plug' } - ], - servicesDetail: [ - { name: '跨境电商专线', description: '东南亚六国专线小包、美国 FBA 头程海派 / 空派,全程轨迹可查。' }, - { name: '集货仓服务', description: '深圳 / 东莞 4 万平集货仓,收货、质检、贴标、打包一体化。' }, - { name: '海外仓履约', description: '洛杉矶及东南亚海外仓,一件代发、退换货换标、中转服务。' }, - { name: '海运拼箱', description: '东南亚各基本港每周航班,整柜 / 拼箱灵活搭配。' } - ], - contact: { - phone: '0755-8800 XXXX', - email: 'service@pc-crossborder.example.com', - address: '深圳市宝安区西乡街道 XX 创新园 B 栋 6 层', - hours: '周一至周六 09:00 - 19:00' - } - }, - { - slug: 'jifeng', - name: '极风航空货运代理(北京)有限公司', - slogan: '时效即承诺', - verified: true, - region: '华北', - city: '北京', - routes: ['欧线', '中东线'], - services: ['空运', '报关报检'], - established: 2016, - employees: '50-80 人', - color: 'violet', - description: '国际空运包板代理,欧洲、中东航线当日订舱次日起飞,鲜活冷链与紧急件操作经验丰富。', - about: [ - '极风航空货运代理成立于 2016 年,总部北京,在郑州、乌鲁木齐设操作点,专注国际航空货运。', - '公司为国航、南航、汉莎、阿联酋航空等多家航司的包板代理,欧洲和中东主要机场舱位直采,旺季不甩货。', - '具备危险品(含锂电池)、鲜活冷链、AOG 紧急航材等特种货物操作资质与经验。' - ], - strengths: [ - { title: '包板直采', description: '欧洲 / 中东主要机场包板舱位,运价与舱位直采。', icon: 'i-lucide-plane' }, - { title: '特种货操作', description: '锂电池、鲜活冷链、AOG 航材等特种货合规操作。', icon: 'i-lucide-thermometer-snowflake' }, - { title: '极速响应', description: '当日订舱、次日起飞,紧急件 2 小时内出方案。', icon: 'i-lucide-timer' } - ], - servicesDetail: [ - { name: '国际空运', description: '欧洲、中东、北美主要机场进出港空运,普货 / 特种货全覆盖。' }, - { name: '包机与包板', description: '临时包机、长期包板方案定制,大货量出运成本最优。' }, - { name: '冷链空运', description: '主动 / 被动温控方案,鲜活、医药冷链全程温湿度记录。' }, - { name: '报关报检', description: '北京首都 / 大兴机场口岸报关,快件 / 一般贸易双通道。' } - ], - contact: { - phone: '010-5200 XXXX', - email: 'ops@jifeng-air.example.com', - address: '北京市顺义区天竺综保区 XX 楼 3 层', - hours: '周一至周日 08:30 - 20:00' - } - }, - { - slug: 'silu', - name: '丝路铁联物流(西安)有限公司', - slogan: '钢铁驼队,联通欧亚', - verified: true, - region: '西北', - city: '西安', - routes: ['欧线', '中东线'], - services: ['铁路联运', '公路运输', '仓储服务'], - established: 2015, - employees: '80-120 人', - color: 'emerald', - description: '中欧班列(西安)核心订舱代理,长安号欧洲全境 15 天直达,中亚五国全线覆盖。', - about: [ - '丝路铁联物流成立于 2015 年,扎根西安国际港务区,是中欧班列长安号的核心订舱代理之一。', - '公司运营西安至杜伊斯堡、汉堡、马拉舍维奇、塔什干等 10 余条线路,欧洲全境 15 天左右直达。', - '提供整列 / 集拼双模式,配套口岸换装追踪、境外段铁路延伸服务及堆场仓储。' - ], - strengths: [ - { title: '长安号核心代理', description: '中欧班列长安号核心订舱代理,整列 / 集拼双模式。', icon: 'i-lucide-train' }, - { title: '中亚全线覆盖', description: '中亚五国全线直达,塔什干 / 阿拉木图固定发车。', icon: 'i-lucide-map' }, - { title: '口岸换装追踪', description: '阿拉山口 / 霍尔果斯口岸换装节点实时追踪。', icon: 'i-lucide-radar' } - ], - servicesDetail: [ - { name: '中欧班列', description: '西安至杜伊斯堡 / 汉堡 / 马拉等线路,全程 15 天左右直达。' }, - { name: '中亚班列', description: '中亚五国全线直达,塔什干、阿拉木图每周固定发车。' }, - { name: '公路跨境运输', description: 'TIR 公路运输及国内段拖车短驳,门到门灵活衔接。' }, - { name: '堆场仓储', description: '国际港务区内堆场,装箱、加固、暂存一站式操作。' } - ], - contact: { - phone: '029-9900 XXXX', - email: 'booking@silu-rail.example.com', - address: '西安市国际港务区港务大道 XX 号', - hours: '周一至周五 08:30 - 18:00' - } - }, - { - slug: 'bluewhale', - name: '蓝鲸国际物流(青岛)有限公司', - slogan: '日韩航线的贴身管家', - verified: false, - region: '华东', - city: '青岛', - routes: ['日韩线', '美线'], - services: ['海运整箱', '海运拼箱'], - established: 2019, - employees: '20-50 人', - color: 'sky', - description: '聚焦日韩近洋航线,青岛 / 上海出运日本基本港 3 天直达,拼箱每周三班。', - about: [ - '蓝鲸国际物流成立于 2019 年,总部青岛,是一家聚焦日韩近洋航线的年轻货代团队。', - '公司与山东海运及多家日本线船司合作,大阪、东京、釜山等基本港拼箱每周三班,整箱即订即走。', - '团队核心成员均来自一线船公司,擅长近洋航线的快速响应与灵活操作。' - ], - strengths: [ - { title: '日韩专线', description: '日本基本港 3 天直达,拼箱每周三班。', icon: 'i-lucide-ship' }, - { title: '快速响应', description: '核心成员来自一线船司,询价 30 分钟内回复。', icon: 'i-lucide-zap' }, - { title: '灵活操作', description: '小货量、异形货、近洋临时补货均可承接。', icon: 'i-lucide-package' } - ], - servicesDetail: [ - { name: '日本航线', description: '大阪、东京、横滨、名古屋整箱及拼箱,3 天直达。' }, - { name: '韩国航线', description: '釜山、仁川整箱及拼箱,周班稳定,可接 DDP。' }, - { name: '近洋拼箱', description: '日韩基本港每周三班,1CBM 起运,仓库免费暂存 7 天。' } - ], - contact: { - phone: '0532-8800 XXXX', - email: 'hr@bluewhale-log.example.com', - address: '青岛市市南区香港中路 XX 号 XX 大厦 21 层', - hours: '周一至周五 08:30 - 17:30' - } - }, - { - slug: 'junda', - name: '骏达港航物流(广州)有限公司', - slogan: '非洲航线的老朋友', - verified: true, - region: '华南', - city: '广州', - routes: ['东南亚线', '非洲线'], - services: ['海运整箱', '报关报检', '仓储服务'], - established: 2011, - employees: '120-200 人', - color: 'amber', - description: '华南至非洲航线深耕十四年,拉各斯 / 蒙巴萨 / 德班直达,工程物流与项目货经验丰富。', - about: [ - '骏达港航物流成立于 2011 年,总部广州,在佛山、东莞设仓库,专注非洲及东南亚航线。', - '公司与多家非洲航线船司长期合作,拉各斯、蒙巴萨、德班等主要港口直达服务稳定,工程车辆、水泥厂设备等项目货操作经验丰富。', - '配套白云机场及南沙港报关资源,提供仓储、装柜、绑扎加固等全流程地面服务。' - ], - strengths: [ - { title: '非洲直达', description: '拉各斯 / 蒙巴萨 / 德班直达航线,西非东非双覆盖。', icon: 'i-lucide-ship' }, - { title: '项目货经验', description: '工程车辆、成套设备等大件项目货方案定制。', icon: 'i-lucide-container' }, - { title: '地面一体化', description: '仓储、装柜、绑扎加固、报关全流程自营。', icon: 'i-lucide-warehouse' } - ], - servicesDetail: [ - { name: '非洲航线整箱', description: '西非 / 东非 / 南非主要港口整箱直达,可接特种柜。' }, - { name: '项目物流', description: '工程车辆、成套设备大件运输方案设计与现场操作。' }, - { name: '仓储装柜', description: '广州 / 佛山仓储装柜,出口免熏蒸托盘及绑扎加固。' }, - { name: '报关报检', description: '南沙港、白云机场口岸报关,产地证代办。' } - ], - contact: { - phone: '020-3700 XXXX', - email: 'gd@junda-shipping.example.com', - address: '广州市黄埔区港湾路 XX 号 XX 大厦 9 层', - hours: '周一至周六 08:30 - 18:00' - } - } -] - -// ── 文章数据 ────────────────────────────────────────────────── - -export const articles: Article[] = [ - { - id: 'red-sea-rerouting-2026', - companySlug: 'huanyang', - category: '行业资讯', - title: '红海局势缓和后的欧线运价走势:旺季前还能涨多少?', - summary: '欧线即期运价在连续两个月回落后企稳,舱位利用率回升至九成。我们结合三大船司的排舱数据,分析旺季前欧线的运价区间与订舱窗口建议。', - content: [ - '经历年初的红海绕行高峰后,欧线即期运价自二季度起持续回落,上海出口至北欧基本港运价较年内高点回落约四成,最近三周开始企稳。', - '从舱位利用率看,主流船司欧线周度舱位利用率已回升至 90% 左右,部分航次出现满舱。这一方面是旺季出货的前置,另一方面也是船司主动控制运力投放的结果。', - '我们认为,短期内欧线运价将以稳为主、结构性上涨为辅:基本港运价波动有限,但旺季附加费(PSS)已在部分航次开征;内陆点因中转拥堵,涨幅会更明显。', - '订舱建议:若货量在 5 个高柜以上,建议提前两周锁定舱位;中小货量可关注拼箱渠道,当前拼箱价格相对整箱更具性价比。' - ], - date: '2026-08-26', - readMinutes: 5 - }, - { - id: 'us-west-lcr-2026', - companySlug: 'huanyang', - category: '行业资讯', - title: '美西长滩港劳工谈判落地,塞港风险解除?', - summary: '劳资协议达成后,长滩 / 洛杉矶港的等泊时间已回落至 2 天以内。但旺季叠加返校季出货,工会换班效率与铁路疏运仍是两大变量。', - content: [ - '持续一年多的美西港口劳工谈判正式落地,新的六年期劳资协议覆盖了从码头到仓储的 2 万余名工人。', - '协议达成后,长滩、洛杉矶两大港的等泊时间快速回落,目前在锚地等泊时间已降至 2 天以内,码头作业效率恢复至正常水平的九成以上。', - '但需要提醒的是:暑期出货旺季叠加返校季补货,未来两个月美西港口吞吐量预计环比上升 15% 以上。工会新协议下的换班效率、内陆铁路疏运能力,仍是影响提柜速度的两大变量。', - '对于计划在四季度出货的客户,我们建议将提货与派送计划各预留 3-5 天弹性,或考虑美东 / 墨西哥湾港口分流。' - ], - date: '2026-08-22', - readMinutes: 4 - }, - { - id: 'seafood-cold-chain-case', - companySlug: 'jifeng', - category: '案例分享', - title: '48 小时跨半球:一批挪威三文鱼的空运冷链实操', - summary: '奥斯陆起飞、北京落地,全程温控记录 2-8℃ 零偏差。拆解这批 12 吨三文鱼的舱位申请、温控方案与清关节点。', - content: [ - '上个月,我们承接了一批 12 吨挪威冰鲜三文鱼的空运业务:奥斯陆起飞、经停后直达北京首都机场,全程地面 + 空中冷链不断链。', - '方案设计上,采用主动温控集装箱(RKN e1)搭配备用冰袋方案,出发前在奥斯陆机场完成 4 小时预冷,装载温度严格控制在 2-8℃ 区间。', - '清关节点提前与首都机场口岸沟通,鲜活产品走绿色通道,落地后 90 分钟内完成通关放行,较常规流程缩短一半以上。', - '最终全程温控记录零偏差,货主损耗率低于 0.5%。冷链空运的核心不只是硬件,更是每个节点的分钟级衔接。' - ], - date: '2026-08-20', - readMinutes: 6 - }, - { - id: 'china-europe-train-q3', - companySlug: 'silu', - category: '行业资讯', - title: '中欧班列三季度运行数据:西安开行量为何持续领先?', - summary: '三季度长安号开行量同比增长 12%,欧洲全境时效稳定在 15 天左右。从集结中心模式看西安枢纽的护城河。', - content: [ - '三季度中欧班列整体开行量保持增长,其中长安号同比增长 12%,继续稳居全国前列,欧洲全境运输时效稳定在 15 天左右。', - '西安领先的核心在于「集结中心」模式:货源地集拼 + 本地报关 + 一站式场站操作,把原本分散在各口岸的环节前置,压缩了口岸滞留时间。', - '从货类结构看,光伏组件、新能源汽车、家电仍是主力货类,合计占比过半;回程班列的欧洲二手车、粮油货量增长明显,去回程比已优化至接近 1:0.9。', - '对于时效敏感但成本预算有限、货量在中欧之间的客户,班列 + 公路门到门的组合方案,性价比正在持续改善。' - ], - date: '2026-08-18', - readMinutes: 5 - }, - { - id: 'sea-erp-upgrade', - companySlug: 'pengcheng', - category: '公司动态', - title: '鹏城跨境 WMS 3.0 上线:集货仓处理能力提升 40%', - summary: '新的仓储管理系统全面接入 AI 面单识别与自动分拣线,深圳仓日均处理订单能力从 3 万提升至 4.2 万单。', - content: [ - '经过三个月的灰度运行,鹏城跨境自研 WMS 3.0 已在深圳、东莞两仓全面上线。', - '新系统的核心变化:面单 AI 识别准确率提升至 99.6%,自动分拣线接入后,单件包裹的平均处理时长从 26 秒压缩至 15 秒。', - '两仓合并的日均处理订单能力从 3 万单提升至 4.2 万单,大促期间不再需要临时外仓分流。', - '下一阶段我们将开放 WMS 的标准 API 给核心客户,实现库存与订单数据的实时双向同步。' - ], - date: '2026-08-15', - readMinutes: 3 - }, - { - id: 'aog-emergency-case', - companySlug: 'jifeng', - category: '案例分享', - title: 'AOG 紧急航材运输:从接到电话到起飞 11 小时', - summary: '一架外航宽体机滞留浦东,急需更换件 2.4 吨。我们如何在一夜之间完成提货、报关、订舱与装载。', - content: [ - '凌晨 0:40,值班手机响起:某外航一架宽体客机因液压部件故障滞留浦东,AOG 紧急航材在苏州工厂,2.4 吨,需要当天装机运回。', - '1:20 派车从苏州提货;4:30 货物抵达浦东机场货站;6:00 完成出口报关与安检(航材需民航鉴定,我们提前备好了资质文件)。', - '8:30 与航司确认舱位,利用当天上午一班的腹舱空间装机;11:50 飞机起飞。从接到电话到起飞,全程 11 小时。', - 'AOG 业务的价值在于预案:航材运输的资质、鉴定文件、货站通道,都需要在平时准备好,紧急时刻才跑得起来。' - ], - date: '2026-08-12', - readMinutes: 4 - }, - { - id: 'africa-project-cargo-case', - companySlug: 'junda', - category: '案例分享', - title: '30 台工程车是怎么运到拉各斯的:一个项目货的完整拆解', - summary: '滚装 + 框架柜组合方案,从广州到拉各斯 38 天。项目货的难点从来不是运输本身,而是方案设计与节点控制。', - content: [ - '客户需求很直接:30 台自卸工程车,交期 45 天内到拉各斯,预算有限。', - '方案设计上,我们拆成了滚装船 + 框架柜两段:18 台走滚装船直航拉各斯,12 台因船期错配改用框架柜班轮,两条腿走路分散风险。', - '难点在细节:工程车需要拆解后视镜与排气管、断电处理、断电后的固定加固,每台车的绑扎方案都要单独确认;框架柜那批还涉及超限申请与港口吊装协调。', - '最终滚装批次 32 天到达、框架柜批次 38 天到达,全部在交期内。项目货的核心能力是「把不确定性拆解成节点」,然后逐个节点盯死。' - ], - date: '2026-08-08', - readMinutes: 6 - }, - { - id: 'jp-lcl-schedule-update', - companySlug: 'bluewhale', - category: '公司动态', - title: '日本线拼箱加开周三班:大阪 / 东京 / 名古屋全覆盖', - summary: '9 月起日本线拼箱加开周三班次,三大基本港每周两班,1CBM 起运,仓库免费暂存 7 天。', - content: [ - '感谢各位客户的支持,我们的日本线拼箱货量持续增长,9 月起加开周三班次。', - '调整后,大阪、东京、名古屋三大基本港拼箱均为每周两班(周三 / 周六),截关时间分别为周一 12:00 与周四 12:00。', - '拼箱最低 1CBM 起运,仓库免费暂存 7 天,支持异地送货与上门提货。', - '新班次首航舱位有限,欢迎通过平台私信或来电提前订舱。' - ], - date: '2026-08-05', - readMinutes: 2 - } -] - -// ── 数据访问 ────────────────────────────────────────────────── - -export function getCompany(slug: string): Company | undefined { - return companies.find(c => c.slug === slug) -} - -export function getCompanyArticles(slug: string): Article[] { - return articles - .filter(a => a.companySlug === slug) - .sort((a, b) => b.date.localeCompare(a.date)) -} - -export function getArticle(id: string): Article | undefined { - return articles.find(a => a.id === id) -} - -export function getLatestArticles(limit = 6): Article[] { - return [...articles].sort((a, b) => b.date.localeCompare(a.date)).slice(0, limit) -} diff --git a/code/link-site/link-nuxt/app/layouts/company.vue b/code/link-site/link-nuxt/app/layouts/company.vue deleted file mode 100644 index 20b0ac87..00000000 --- a/code/link-site/link-nuxt/app/layouts/company.vue +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/code/link-site/link-nuxt/app/layouts/default.vue b/code/link-site/link-nuxt/app/layouts/default.vue deleted file mode 100644 index 98221dea..00000000 --- a/code/link-site/link-nuxt/app/layouts/default.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/company/[slug].vue b/code/link-site/link-nuxt/app/pages/company/[slug].vue deleted file mode 100644 index 76c7a71c..00000000 --- a/code/link-site/link-nuxt/app/pages/company/[slug].vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/company/[slug]/about.vue b/code/link-site/link-nuxt/app/pages/company/[slug]/about.vue deleted file mode 100644 index 77f3d821..00000000 --- a/code/link-site/link-nuxt/app/pages/company/[slug]/about.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/company/[slug]/articles.vue b/code/link-site/link-nuxt/app/pages/company/[slug]/articles.vue deleted file mode 100644 index 80187fd8..00000000 --- a/code/link-site/link-nuxt/app/pages/company/[slug]/articles.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/company/[slug]/contact.vue b/code/link-site/link-nuxt/app/pages/company/[slug]/contact.vue deleted file mode 100644 index 7cfff5aa..00000000 --- a/code/link-site/link-nuxt/app/pages/company/[slug]/contact.vue +++ /dev/null @@ -1,85 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/company/[slug]/index.vue b/code/link-site/link-nuxt/app/pages/company/[slug]/index.vue deleted file mode 100644 index 27682478..00000000 --- a/code/link-site/link-nuxt/app/pages/company/[slug]/index.vue +++ /dev/null @@ -1,157 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/company/[slug]/services.vue b/code/link-site/link-nuxt/app/pages/company/[slug]/services.vue deleted file mode 100644 index db7374e9..00000000 --- a/code/link-site/link-nuxt/app/pages/company/[slug]/services.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/directory.vue b/code/link-site/link-nuxt/app/pages/directory.vue deleted file mode 100644 index f5eae89e..00000000 --- a/code/link-site/link-nuxt/app/pages/directory.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/index.vue b/code/link-site/link-nuxt/app/pages/index.vue deleted file mode 100644 index 46a90bfd..00000000 --- a/code/link-site/link-nuxt/app/pages/index.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/news/[id].vue b/code/link-site/link-nuxt/app/pages/news/[id].vue deleted file mode 100644 index ecf92bbc..00000000 --- a/code/link-site/link-nuxt/app/pages/news/[id].vue +++ /dev/null @@ -1,134 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/app/pages/news/index.vue b/code/link-site/link-nuxt/app/pages/news/index.vue deleted file mode 100644 index 718057fd..00000000 --- a/code/link-site/link-nuxt/app/pages/news/index.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - diff --git a/code/link-site/link-nuxt/company-final.png b/code/link-site/link-nuxt/company-final.png deleted file mode 100644 index 00c0a88d..00000000 Binary files a/code/link-site/link-nuxt/company-final.png and /dev/null differ diff --git a/code/link-site/link-nuxt/company-new.png b/code/link-site/link-nuxt/company-new.png deleted file mode 100644 index a71c1431..00000000 Binary files a/code/link-site/link-nuxt/company-new.png and /dev/null differ diff --git a/code/link-site/link-nuxt/current-company.png b/code/link-site/link-nuxt/current-company.png deleted file mode 100644 index ff999825..00000000 Binary files a/code/link-site/link-nuxt/current-company.png and /dev/null differ diff --git a/code/link-site/link-nuxt/eslint.config.mjs b/code/link-site/link-nuxt/eslint.config.mjs deleted file mode 100644 index 934c3a1d..00000000 --- a/code/link-site/link-nuxt/eslint.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -// @ts-check -import withNuxt from './.nuxt/eslint.config.mjs' - -export default withNuxt( - // Your custom configs here -) diff --git a/code/link-site/link-nuxt/nuxt.config.ts b/code/link-site/link-nuxt/nuxt.config.ts deleted file mode 100644 index bd5bf3e6..00000000 --- a/code/link-site/link-nuxt/nuxt.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -// https://nuxt.com/docs/api/configuration/nuxt-config -export default defineNuxtConfig({ - modules: [ - '@nuxt/eslint', - '@nuxt/ui' - ], - - devtools: { - enabled: true - }, - - css: ['~/assets/css/main.css'], - - routeRules: { - '/': { prerender: true } - }, - - compatibilityDate: '2026-06-30', - - eslint: { - config: { - stylistic: { - commaDangle: 'never', - braceStyle: '1tbs' - } - } - } -}) diff --git a/code/link-site/link-nuxt/package.json b/code/link-site/link-nuxt/package.json deleted file mode 100644 index da068b65..00000000 --- a/code/link-site/link-nuxt/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "link-nuxt", - "private": true, - "type": "module", - "scripts": { - "build": "nuxt build", - "dev": "nuxt dev", - "preview": "nuxt preview", - "postinstall": "nuxt prepare", - "lint": "eslint .", - "typecheck": "nuxt typecheck" - }, - "dependencies": { - "@iconify-json/lucide": "^1.2.127", - "@iconify-json/simple-icons": "^1.2.94", - "@nuxt/ui": "^4.11.0", - "nuxt": "^4.5.2", - "tailwindcss": "^4.3.3" - }, - "devDependencies": { - "@nuxt/eslint": "^1.17.0", - "eslint": "^10.9.1", - "typescript": "^6.0.3", - "vue-tsc": "^3.3.11" - }, - "packageManager": "pnpm@11.24.0" -} diff --git a/code/link-site/link-nuxt/pnpm-lock.yaml b/code/link-site/link-nuxt/pnpm-lock.yaml deleted file mode 100644 index 0ddfb385..00000000 --- a/code/link-site/link-nuxt/pnpm-lock.yaml +++ /dev/null @@ -1,11072 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@iconify-json/lucide': - specifier: ^1.2.127 - version: 1.2.127 - '@iconify-json/simple-icons': - specifier: ^1.2.94 - version: 1.2.94 - '@nuxt/ui': - specifier: ^4.11.0 - version: 4.11.0(2cb0382fb94ddb82dc3bbb00dab71962) - nuxt: - specifier: ^4.5.2 - version: 4.5.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@oxc-project/types@0.142.0)(@parcel/watcher@2.5.6)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(@vue/compiler-sfc@3.5.40)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.1)(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue-tsc@3.3.11(typescript@6.0.3))(yaml@2.9.0) - tailwindcss: - specifier: ^4.3.3 - version: 4.3.3 - devDependencies: - '@nuxt/eslint': - specifier: ^1.17.0 - version: 1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(srvx@0.11.22)(supports-color@10.2.2)(typescript@6.0.3)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - eslint: - specifier: ^10.9.1 - version: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - typescript: - specifier: ^6.0.3 - version: 6.0.3 - vue-tsc: - specifier: ^3.3.11 - version: 3.3.11(typescript@6.0.3) - -packages: - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@antfu/install-pkg@1.1.0': - resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - - '@antfu/install-pkg@2.0.1': - resolution: {integrity: sha512-iCKVQcIC0e3oDxEfs3SHQGW+ovhBMZmS1TE+bTk50rVyMCBmCfClv7Qi3HQKlumYwvjb/iIMeWCW2i67q6kFfQ==} - - '@apidevtools/json-schema-ref-parser@14.2.1': - resolution: {integrity: sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==} - engines: {node: '>= 20'} - peerDependencies: - '@types/json-schema': ^7.0.15 - - '@babel/code-frame@7.29.7': - resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.29.3': - resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.29.7': - resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} - engines: {node: '>=6.9.0'} - - '@babel/generator@8.0.0': - resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-annotate-as-pure@7.29.7': - resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.29.7': - resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-globals@7.29.7': - resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.29.7': - resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-optimise-call-expression@7.29.7': - resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.29.7': - resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-replace-supers@7.29.7': - resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@7.29.7': - resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.29.7': - resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@8.0.0': - resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@8.0.4': - resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.7': - resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@8.0.4': - resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} - engines: {node: ^22.18.0 || >=24.11.0} - hasBin: true - - '@babel/plugin-syntax-jsx@7.28.6': - resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.29.7': - resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.29.7': - resolution: {integrity: sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.29.7': - resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.29.7': - resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.7': - resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} - engines: {node: '>=6.9.0'} - - '@babel/types@8.0.4': - resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@bomb.sh/tab@0.0.19': - resolution: {integrity: sha512-dTRfo9Q9B+lbLG3JCu8a/AGQSfD2XXcFcnakQzVjSOX+VvR/s9zpsH8TlqV3iHqazniRn1Ypwd1hcRlXcu/4BA==} - hasBin: true - peerDependencies: - cac: ^6.7.14 - citty: ^0.1.6 || ^0.2.0 - commander: ^13.1.0 || ^14.0.0 || ^15.0.0 - peerDependenciesMeta: - cac: - optional: true - citty: - optional: true - commander: - optional: true - - '@capsizecss/unpack@4.0.0': - resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} - engines: {node: '>=18'} - - '@clack/core@1.4.3': - resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} - engines: {node: '>= 20.12.0'} - - '@clack/prompts@1.7.0': - resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} - engines: {node: '>= 20.12.0'} - - '@cloudflare/kv-asset-handler@0.4.2': - resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} - engines: {node: '>=18.0.0'} - - '@colordx/core@5.4.3': - resolution: {integrity: sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ==} - - '@devframes/hub@0.7.15': - resolution: {integrity: sha512-g2aUJZAsmBsWARqvA2nhT5F9v2usJ/uiavstsWA7FZaXU6+2LYx/OafqDlFNUa+PxGUWwEZe/qzwAuRoZjv8uA==} - peerDependencies: - devframe: 0.7.15 - - '@devframes/json-render@0.7.15': - resolution: {integrity: sha512-IB1EsAHKK313yuslrEyAl7z6347YeV+eT5EtNQwjLcoYh1sD6er/eqdj4Aeicovpg49U7tmlFZHicDxVl1W89A==} - peerDependencies: - '@devframes/hub': 0.7.15 - devframe: 0.7.15 - peerDependenciesMeta: - '@devframes/hub': - optional: true - - '@dxup/nuxt@0.5.6': - resolution: {integrity: sha512-uZjAFoocWtWHr7YP9jm6FqwI8kjX2QN9bjcncoZt0GS+zExIAP3Ewv6EqEUvVP7w9pjZE+T19QxLHeoacN/MNg==} - - '@dxup/unimport@0.1.2': - resolution: {integrity: sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==} - - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - - '@emnapi/core@1.11.2': - resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} - - '@emnapi/core@2.0.0-alpha.3': - resolution: {integrity: sha512-AZypUeJ/yByuxyS7BlSNRDOMLMlROYtjYdIAuBmJssVz1UJDSeYxLrdizhXCFYhedC5bqd/ASy8EuNXbVVXp9g==} - - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - - '@emnapi/runtime@1.11.2': - resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} - - '@emnapi/runtime@2.0.0-alpha.3': - resolution: {integrity: sha512-hFPAhMUjJD9BSyCANEISPOogeXC9Zo9ZQl7L6vKnaVsMkCtzznaW/naYypeyl0Gv5rYfWYsZbpixTMpjDJzQeA==} - - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - - '@emnapi/wasi-threads@2.0.1': - resolution: {integrity: sha512-9DsSk+o5NBX0CCJT8s0EROGSGxjR/tKu6aBTaVyq+SjAEQH4XcdcRxPBRzsBLizTTJ49MJjF+jgu3qnO9GLQcQ==} - - '@es-joy/jsdoccomment@0.91.0': - resolution: {integrity: sha512-vgqlMGNNhZxwDYbUNIHj3Hskb4R28iqdXx90ufHyt/NeuTQkeqjTDslAs9I0/GCAfbxP5BpH5WsL1R1fht5Lxg==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@es-joy/resolve.exports@1.2.0': - resolution: {integrity: sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==} - engines: {node: '>=10'} - - '@esbuild/aix-ppc64@0.27.7': - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.28.0': - resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.27.7': - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.28.0': - resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.27.7': - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.28.0': - resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.27.7': - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.28.0': - resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.27.7': - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.28.0': - resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.7': - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.28.0': - resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.27.7': - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.28.0': - resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.7': - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.28.0': - resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.27.7': - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.28.0': - resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.27.7': - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.28.0': - resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.27.7': - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.28.0': - resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.27.7': - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.28.0': - resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.27.7': - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.28.0': - resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.27.7': - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.28.0': - resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.7': - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.28.0': - resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.27.7': - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.28.0': - resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.27.7': - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.28.0': - resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.7': - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-arm64@0.28.0': - resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.7': - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.28.0': - resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.7': - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-arm64@0.28.0': - resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.7': - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.28.0': - resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.7': - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/openharmony-arm64@0.28.0': - resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.27.7': - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.28.0': - resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.27.7': - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.28.0': - resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.27.7': - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.28.0': - resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.27.7': - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.28.0': - resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/compat@2.1.0': - resolution: {integrity: sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: ^8.40 || 9 || 10 - peerDependenciesMeta: - eslint: - optional: true - - '@eslint/config-array@0.23.5': - resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/config-helpers@0.5.5': - resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/config-helpers@0.7.0': - resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/config-inspector@3.2.0': - resolution: {integrity: sha512-kylJhcii8eDOiRFPANNUHOyDebBIOt+nqYXt8q6W9FbhYzFJAXjLzJz6KFNzY0WvIyOBKdbSQdwdPNrkMh05tg==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - hasBin: true - peerDependencies: - eslint: ^8.50.0 || ^9.0.0 || ^10.0.0 - - '@eslint/core@1.2.1': - resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/css-tree@4.0.5': - resolution: {integrity: sha512-iPmijIAq4hlIJB86PYmY/fcZORHtjphSqICDbwuw32A/JmkhZQ/K/6TjHE03zqf3n5yABpVcbRAMG8Mi9ojy8g==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/js@10.0.1': - resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: ^10.0.0 - peerDependenciesMeta: - eslint: - optional: true - - '@eslint/object-schema@3.0.5': - resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/plugin-kit@0.7.2': - resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@floating-ui/core@1.8.0': - resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} - - '@floating-ui/dom@1.8.0': - resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} - - '@floating-ui/utils@0.2.12': - resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} - - '@floating-ui/vue@1.1.11': - resolution: {integrity: sha512-HzHKCNVxnGS35r9fCHBc3+uCnjw9IWIlCPL683cGgM9Kgj2BiAl8x1mS7vtvP6F9S/e/q4O6MApwSHj8hNLGfw==} - - '@humanfs/core@0.19.2': - resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.8': - resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} - engines: {node: '>=18.18.0'} - - '@humanfs/types@0.15.0': - resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@iconify-json/lucide@1.2.127': - resolution: {integrity: sha512-7KuCCpkly00kefna4wEnCr8l2HFRkbn4mD4zRib8wCSbrBmnR/l57ExpU6j5jv/Bo+qHpWuHpDtcqceQ0ptArw==} - - '@iconify-json/simple-icons@1.2.94': - resolution: {integrity: sha512-l8UWzVxKaqZd9ABsE/M/9p6NyGkQnmCnOoZyhQmjlXCtY5PuL2rcWxOFk2l9pk7ux3ERMPkTLE4jl6kQpTkwxA==} - - '@iconify/collections@1.0.727': - resolution: {integrity: sha512-n+ipAqz5A6TWExnndwdT6qVX7KfXiw5GNDSxO2otXs6rxFWdHqizHTW1WvmWmT6m2BqQ8lhzUyWSJvm4M3nMAg==} - - '@iconify/types@2.0.0': - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - - '@iconify/utils@3.1.4': - resolution: {integrity: sha512-b1S7B1k9ohZ+iNTi2ATxbRYG9fTrJmUT0rc46bvVnNxqNRGW7dyo/vRREwyniI5IRN2RSJHDcm+s3BjWrSAjHw==} - - '@iconify/vue@5.0.1': - resolution: {integrity: sha512-aumwwooJlFJ5H5qYWB6ZTAyM0C8hpfcSVLB9/a3qnH1GGvIJ+FEbpEs4s/HfErYe/M5qZeLjwmESR5fFm3lXEw==} - peerDependencies: - vue: '>=3.0.0' - - '@internationalized/date@3.12.1': - resolution: {integrity: sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==} - - '@internationalized/number@3.6.6': - resolution: {integrity: sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==} - - '@ioredis/commands@1.5.1': - resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.11': - resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@json-render/core@0.19.0': - resolution: {integrity: sha512-vvcyZ+10EDZKbEyB1J2kXOGfDaiZR2LurZGSqi2r5STHyKr+Te85DWaBxTwRGgM7U1LtIvNx85BzzjElRKoAIg==} - peerDependencies: - zod: ^4.0.0 - - '@kwsites/file-exists@1.1.1': - resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} - - '@kwsites/promise-deferred@1.1.1': - resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - - '@mapbox/node-pre-gyp@2.0.3': - resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} - engines: {node: '>=18'} - hasBin: true - - '@napi-rs/wasm-runtime@1.2.0': - resolution: {integrity: sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - peerDependencies: - '@emnapi/core': ^2.0.0-alpha.3 - '@emnapi/runtime': ^2.0.0-alpha.3 - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nuxt/cli@3.37.0': - resolution: {integrity: sha512-Zj9NwHjEBzVrgezsgMFjpMhNqwNgROk9DzNi/dyfk1mCbXIRigV11br2xOl0Satek30bmv7oZAfMtCnDe6Ip0Q==} - engines: {node: ^16.14.0 || >=18.0.0} - hasBin: true - peerDependencies: - '@nuxt/schema': ^4.4.6 - peerDependenciesMeta: - '@nuxt/schema': - optional: true - - '@nuxt/devalue@2.0.2': - resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} - - '@nuxt/devtools-kit@3.4.1': - resolution: {integrity: sha512-6ltPm2yUW8GvDdf3VJna7+flLi+ej7xRfSr+S4ovevKt/CuPf9EqYOn1jW7Kw/U1MXt/71zkn+/O2vu3G6O9Hg==} - peerDependencies: - vite: '>=6.0' - - '@nuxt/devtools-wizard@3.4.1': - resolution: {integrity: sha512-taGeuTnkHsZVjgD9r6NXvvHaBzB2j4mCgOmlmkz3ntsqgh1SJfmsD11Tmtl7FVAxJS8Wuvuzgt0GyTlADBW9Wg==} - hasBin: true - - '@nuxt/devtools@3.4.1': - resolution: {integrity: sha512-20zZs6k/zAdi+PM7s1BwxE3hanZ+R1OGi5DWCKPyzSnhUUeeNebvWNgec7Rwnx6iKLkJfK4WFIZ+FL2QurG/ZQ==} - hasBin: true - peerDependencies: - '@vitejs/devtools': '*' - vite: '>=6.0' - peerDependenciesMeta: - '@vitejs/devtools': - optional: true - - '@nuxt/eslint-config@1.17.0': - resolution: {integrity: sha512-5lHecnGvi7RxGsR3Amvnl47bxb3F4wFD9KQgbbmhd6prz3OAAbgQio9EK88tPyNHt7+dxIFFOnCH6TJNl/QbqQ==} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - eslint-plugin-format: '*' - peerDependenciesMeta: - eslint-plugin-format: - optional: true - - '@nuxt/eslint-plugin@1.17.0': - resolution: {integrity: sha512-h/fn4K09tA5tvdLj9Zlu5mb3TOVO2zLAetCsfJ1/LLVm2XWtgDVhfSB+Sm93cF1rCGxahmHZd4RJz2nAsWTDvg==} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - - '@nuxt/eslint@1.17.0': - resolution: {integrity: sha512-54aD2xJvI2QJnHvQwN22hEgE/izF5ez+diPE7yLCJskKQ0tqPrNJCcRjBtuFQmQMQjTfHESsfuFdLfwMGUz8bw==} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - eslint-webpack-plugin: ^4.1.0 - vite-plugin-eslint2: ^5.0.0 - peerDependenciesMeta: - eslint-webpack-plugin: - optional: true - vite-plugin-eslint2: - optional: true - - '@nuxt/fonts@0.14.0': - resolution: {integrity: sha512-4uXQl9fa5F4ibdgU8zomoOcyMdnwgdem+Pi8JEqeDYI5yPR32Kam6HnuRr47dTb97CstaepAvXPWQUUHMtjsFQ==} - - '@nuxt/icon@2.5.0': - resolution: {integrity: sha512-EBczSfd3QmAD7GoSmJ5jCPvQ5zzNaPPuWPU9DSMcBuBM10A3JIvjaMLEOEniHQRz4iVPb05cJRO/JdC60oiiwg==} - - '@nuxt/kit@4.5.2': - resolution: {integrity: sha512-l66LU9DcJYjmNwqwAj2I5UGRrUbnG2DOKGChnN70zIGtn0eq/z87gi/FRgha6eMb9/FmB1PFHgtx6PWVml1C2Q==} - engines: {node: '>=18.12.0'} - - '@nuxt/nitro-server@4.5.2': - resolution: {integrity: sha512-sx/vtT8D1WIRUOMuKQz/9z8nZb7jgVWc6HWwlkXKDjYZ84otPFtYCozKqhXWv6xf3JxJvge/RUAOwh9Z7P4nQQ==} - engines: {node: ^22.19.0 || ^24.11.0 || >=26.0.0} - peerDependencies: - '@babel/plugin-proposal-decorators': ^7.25.0 || ^8.0.0 - '@babel/plugin-syntax-typescript': ^7.25.0 || ^8.0.0 - '@rollup/plugin-babel': ^6.0.0 || ^7.0.0 - nuxt: ^4.5.2 - peerDependenciesMeta: - '@babel/plugin-proposal-decorators': - optional: true - '@babel/plugin-syntax-typescript': - optional: true - '@rollup/plugin-babel': - optional: true - - '@nuxt/schema@4.5.2': - resolution: {integrity: sha512-h9g1kt9O2iU9nX6HDFu9gvwtpn+8oSJX0RSTWRBnEx/Pkz+WlOHtjuS0SbkTAXw5aT1+H1GysWVwNTjJfBY/0w==} - engines: {node: ^14.18.0 || >=16.10.0} - - '@nuxt/telemetry@2.8.0': - resolution: {integrity: sha512-zAwXY24KYvpLTmiV+osagd2EHkfs5IF+7oDZYTQoit5r0kPlwaCNlzHp5I/wUAWT4LBw6lG8gZ6bWidAdv/erQ==} - engines: {node: '>=18.12.0'} - hasBin: true - peerDependencies: - '@nuxt/kit': '>=3.0.0' - - '@nuxt/ui@4.11.0': - resolution: {integrity: sha512-gDs67/fWk3kipcEV4Pc5h1VnZD1glfWfINmJU7s3qpkxxRTkfkPxnUszXG664whNWcoqucS1WgZ/rNjZa3pTMw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@inertiajs/vue3': ^2.0.7 || ^3.0.0 - '@internationalized/date': ^3.0.0 - '@internationalized/number': ^3.0.0 - '@nuxt/content': ^3.0.0 - '@tiptap/core': ^3 - '@tiptap/extension-bubble-menu': ^3 - '@tiptap/extension-code': ^3 - '@tiptap/extension-collaboration': ^3 - '@tiptap/extension-drag-handle': ^3 - '@tiptap/extension-drag-handle-vue-3': ^3 - '@tiptap/extension-floating-menu': ^3 - '@tiptap/extension-horizontal-rule': ^3 - '@tiptap/extension-image': ^3 - '@tiptap/extension-mention': ^3 - '@tiptap/extension-node-range': ^3 - '@tiptap/extension-placeholder': ^3 - '@tiptap/markdown': ^3 - '@tiptap/pm': ^3 - '@tiptap/starter-kit': ^3 - '@tiptap/suggestion': ^3 - '@tiptap/vue-3': ^3 - ai: ^6 || ^7 - joi: ^18.0.0 - superstruct: ^2.0.0 - tailwindcss: ^4.0.0 - typescript: ^5.6.3 || ^6.0.0 || ^7.0.0 - valibot: ^1.0.0 - vue-router: ^4.5.0 || ^5.0.0 - yup: ^1.7.0 - zod: ^3.24.0 || ^4.0.0 - peerDependenciesMeta: - '@inertiajs/vue3': - optional: true - '@internationalized/date': - optional: true - '@internationalized/number': - optional: true - '@nuxt/content': - optional: true - ai: - optional: true - joi: - optional: true - superstruct: - optional: true - valibot: - optional: true - vue-router: - optional: true - yup: - optional: true - zod: - optional: true - - '@nuxt/vite-builder@4.5.2': - resolution: {integrity: sha512-fC8KUs5F1VpSEjTIjmx5pdflciMlp3FDCubx3AXElvRPLtBAPmyB69kmqVFjRnVQ8+vRHNyI7iBHUg9Se8srLA==} - engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} - peerDependencies: - '@babel/plugin-proposal-decorators': ^7.25.0 || ^8.0.0 - '@babel/plugin-syntax-jsx': ^7.25.0 || ^8.0.0 - nuxt: 4.5.2 - rolldown: ^1.0.0 - rollup-plugin-visualizer: ^6.0.0 || ^7.0.1 - vue: ^3.3.4 - peerDependenciesMeta: - '@babel/plugin-proposal-decorators': - optional: true - '@babel/plugin-syntax-jsx': - optional: true - rolldown: - optional: true - rollup-plugin-visualizer: - optional: true - - '@nuxtjs/color-mode@4.0.1': - resolution: {integrity: sha512-eiA7hWXi5zNHaYKyJFCGF6i0wFZtuvR7KDXZ6jiSvwxjCpRFwphrw0MOSmNfArTSSsT1wpW+/2H92cejeVfUlg==} - - '@oxc-parser/binding-android-arm-eabi@0.140.0': - resolution: {integrity: sha512-ZfjDZ422mo7eo3b3VltqNsV9kmv1qt/sPEAMSl64iOSwhVfd0eIZ9LB79Mbs1xYXJnk7WSROwzBCKDIiVxPTvQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxc-parser/binding-android-arm64@0.140.0': - resolution: {integrity: sha512-Ia8jSvikUX6Sf+Ht+KOCUF/k1HpR0VlmqIYymubmWDebOEGtsyliHDR6JxsZ4IX3/c/GbrB1uh09aVGQv/LQmQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxc-parser/binding-darwin-arm64@0.140.0': - resolution: {integrity: sha512-G6VK0nK61pH0d0mBjUqSZbVxGqqO5uzeginLDQj+gOO6ObfJjXRwgkD/ol0w1INcnFeAb6YGGO7qc3ueGHaycQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxc-parser/binding-darwin-x64@0.140.0': - resolution: {integrity: sha512-HazBOuZzd2pO1C2uMmp8Gv7mhzMHqKSKDS1OZfcLEvpIcgA+48J92HEtNanVHDIzRD9PRPCV6aS6fkZIWOVl8Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxc-parser/binding-freebsd-x64@0.140.0': - resolution: {integrity: sha512-9hSUU+HmTUyOe4JzMHxNGgLWNY7rrO+6ShicZwImNJacEAACDMIkuEQQkvXSL+WJN50jaNtLYJv8s4OcBdpyUQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxc-parser/binding-linux-arm-gnueabihf@0.140.0': - resolution: {integrity: sha512-RAEuQsYtS0KcDFqN0ABTjyyNlokS91JeuDuoW9tEbG0JTbRNXnpQUdbYc/16JoA6Z/2ALbNrE3KmxtqDiuIjCQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxc-parser/binding-linux-arm-musleabihf@0.140.0': - resolution: {integrity: sha512-c4CkHvPvqfojouredJ0w3e6+jiBq0SbFyhH61kr/zPb/7XsaYTNKQ54vmlSsopfdQbNDX40ZeK9Abs2Qet6wcw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxc-parser/binding-linux-arm64-gnu@0.140.0': - resolution: {integrity: sha512-yrjmLj8ixPB25yqvPGr28meGjb+keed7m1GqqY/0uqkhZIoT4t9zmfwUgFEtC33C7dtE+UQ7TU0IaVxf97SWJg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxc-parser/binding-linux-arm64-musl@0.140.0': - resolution: {integrity: sha512-ggGMQTN8Agwxp2WiLMpdY671dt0qTDJWiWlJeig3HnUwTnerRl0J2JdGVghWBeDcss2D9S2V2Js6dZHEiVabVA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxc-parser/binding-linux-ppc64-gnu@0.140.0': - resolution: {integrity: sha512-IgTs8xYAFgAUGNmR65tIqjlJ8vKgrfXzC515e9goSdfMyKQV4aJpd2pUUudU4u51G64H0/DSEJEXKOraxm9ZCA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@oxc-parser/binding-linux-riscv64-gnu@0.140.0': - resolution: {integrity: sha512-A1x+PMWZmSGaFVOx2YeNTFau8uD+QO14/vLP4GrcuvUPs3+nBkUOjy9Lus86ftHsDojjYMbvBelmKc3F7Rv08g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxc-parser/binding-linux-riscv64-musl@0.140.0': - resolution: {integrity: sha512-zBqpfRo2myWPrPo5xUjeZqlnPXPXsX8BcWtWff66/eGRQdbPjhzPgXa/F+AtxT2afUViPxbuDlwscMKzQ5tg+g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxc-parser/binding-linux-s390x-gnu@0.140.0': - resolution: {integrity: sha512-2M1DPm/8w9I//YzFlFC9qXw+r2tJFh5CYwRlYTq2vUJQS7qoQftEDeCZ8EnN7KHtvSiXvYj8mZI5pR7DpXmcEw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxc-parser/binding-linux-x64-gnu@0.140.0': - resolution: {integrity: sha512-8aRDbZ/U/jO8N7go1MO72jtbpb4uswV8d7vOkMvt/BPgZiyEYvl1VIWK4ESxZZhnJ4tqwVldgX7dNiP/eB1Jdg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxc-parser/binding-linux-x64-musl@0.140.0': - resolution: {integrity: sha512-xRqpeI8U2sQQS1W5BMWRyMTxtagkuLG2dEWruet5lFsWHTvBth11/TpSaJatHdqVVwHN0q3uuoS9zRsGinq8hg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxc-parser/binding-openharmony-arm64@0.140.0': - resolution: {integrity: sha512-GbGRe26MqAKciFRvXeHNQJ6VAHYs9R4miP89sEAncysM3n+f4lnyLWgsa9kklJNpfnxdq2yRoNYHFqwBckVimw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxc-parser/binding-wasm32-wasi@0.140.0': - resolution: {integrity: sha512-vFiC1hqys+hkX1GnQkIoiTQJNiUm43Z0lO35ETKXTw0YtpW7+cN58YRRXFAQQ+TgpkIi3lrhcxdlnqz+Oi3ptQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@oxc-parser/binding-win32-arm64-msvc@0.140.0': - resolution: {integrity: sha512-fGSQldwEYKhM+H8uLt76Op8hh5+FYaR6lvvQ1Txw3Mhn86DyQXLcI0fi1EkFlTK7F+46OCk/j0AJMzZQm6g5Xg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxc-parser/binding-win32-ia32-msvc@0.140.0': - resolution: {integrity: sha512-sDS2Bai+g3ZWYwfZqmosiSuFDBcVnZ3Ta6pszzsiJoLMqsJEWKcxXXbGa7b7yXr++W2lQNPb3ZRJ8czseqL7RA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxc-parser/binding-win32-x64-msvc@0.140.0': - resolution: {integrity: sha512-kHbE1zWyb5OQgJA6/5P4WjiuB01sYdQwtZnSSyE58FQEXDAMnyeeq4vj7KgN75i5SlBzOs8A5MrtlD3gOlDKqQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@oxc-project/types@0.140.0': - resolution: {integrity: sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==} - - '@oxc-project/types@0.142.0': - resolution: {integrity: sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==} - - '@parcel/watcher-android-arm64@2.5.6': - resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [android] - - '@parcel/watcher-darwin-arm64@2.5.6': - resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [darwin] - - '@parcel/watcher-darwin-x64@2.5.6': - resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [darwin] - - '@parcel/watcher-freebsd-x64@2.5.6': - resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [freebsd] - - '@parcel/watcher-linux-arm-glibc@2.5.6': - resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@parcel/watcher-linux-arm-musl@2.5.6': - resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - libc: [musl] - - '@parcel/watcher-linux-arm64-glibc@2.5.6': - resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@parcel/watcher-linux-arm64-musl@2.5.6': - resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@parcel/watcher-linux-x64-glibc@2.5.6': - resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@parcel/watcher-linux-x64-musl@2.5.6': - resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@parcel/watcher-wasm@2.5.6': - resolution: {integrity: sha512-byAiBZ1t3tXQvc8dMD/eoyE7lTXYorhn+6uVW5AC+JGI1KtJC/LvDche5cfUE+qiefH+Ybq0bUCJU0aB1cSHUA==} - engines: {node: '>= 10.0.0'} - bundledDependencies: - - napi-wasm - - '@parcel/watcher-win32-arm64@2.5.6': - resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [win32] - - '@parcel/watcher-win32-ia32@2.5.6': - resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} - engines: {node: '>= 10.0.0'} - cpu: [ia32] - os: [win32] - - '@parcel/watcher-win32-x64@2.5.6': - resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [win32] - - '@parcel/watcher@2.5.6': - resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} - engines: {node: '>= 10.0.0'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@poppinss/colors@4.1.6': - resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} - - '@poppinss/dumper@0.7.0': - resolution: {integrity: sha512-0UTYalzk2t6S4rA2uHOz5bSSW2CHdv4vggJI6Alg90yvl0UgXs6XSXpH96OH+bRkX4J/06djv29pqXJ0lq5Kag==} - - '@poppinss/exception@1.2.3': - resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} - - '@rolldown/binding-android-arm64@1.2.1': - resolution: {integrity: sha512-02hOeOSryYxVrOIphmLAsqnCJWxwlzFk+pEt/N/i6OgT3lShHO7xGCU5cpgchRDHboAEbSjzgGh+O/u1GswQmA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.2.1': - resolution: {integrity: sha512-fMsTOnN0OjFm3CyppWPitKnc8UlliVARUULW6cfU6AIqjdtgmSFWSk9vecHzZduv/yMWIHDlRhM1e8Iff9uAfA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.2.1': - resolution: {integrity: sha512-1wjKdz/XLGKHaTNHjQveQ/B23TKx4ItAqm1JbyVuvNPc4Ze0Fb48s49TAd/2zcplPl8okE/UbTgmlVfwT7eFeQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.2.1': - resolution: {integrity: sha512-Fa0jHR07E7YBN4vOEsbVf2briYNsuOowfLJaXULZM0ldMlaCaj2LJgLMbMe4iacRyZmvR8efFhgR9wKuGclQUg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.2.1': - resolution: {integrity: sha512-pzkgu1SSHGgRRyRZ4fbmSgmajbVt+epaLP99NDjFft69v/ypfTi6swBMiVdh2EkQ0OSnHE1lZDM7DRGkyAzUpA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.2.1': - resolution: {integrity: sha512-QI5SEDY8cbiYWHx0VO4vIc3UlS6a32vXHjU8Qy/17adEmZIPuByJg13UEvo9c/UCiUkdcVWY83C+b+JrwnNyUg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.2.1': - resolution: {integrity: sha512-Sm41FyCeXqmYcERoYOCbGIL5hNfd8w9LQ7Y61Bev48HkcjaJqV/iiVOaiDxjVTRMS+QKrZmD8cfPt4uMVnvM+A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.2.1': - resolution: {integrity: sha512-2x+WhXTGl9yJYPbltW/BSEPTVz9OIWQyER4N+gJEDWkkn904eRcBzELqh/Hf7K0w/ubGbKNMv0ZC+94QK/IFEg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.2.1': - resolution: {integrity: sha512-eEjmQpuRQayHPWWnywaWHkFT3ToPbP3RYy42VVd/B9aBGDA+Ol25EIWHxKQST3IiWJjikCWUF7KtbfqwZrzVwQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.2.1': - resolution: {integrity: sha512-/Orga1fZYkLc/56jBICcHrKchl8Z2UKdDSr3LG9ToWO1lQ6a4Livk9Xz+9WN91zsz5QR3XQz2NNoSDEvP6qadw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.2.1': - resolution: {integrity: sha512-xxBJRL+0q0Kce7orznGWLuylHDY65vuARXZRpX+hPdv+DqK2c3NlCsVA98tlWzWNEE7yPqA/1NQ5nnCrj49Y5A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.2.1': - resolution: {integrity: sha512-M6AdXIXw3s+/8XpKMzdGDEXGS1S7kwUsy+rcTIUIOx5Ge4nXKCtAFHFV9YKkXvGcC5WMoTjAteLzlsQROVI0Yw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.2.1': - resolution: {integrity: sha512-/TX0SoRGojHzSAHpfVBbavRVSazg5U3h3Y3VXfcc0cdugq6kxdqw8LPGFiPr+/7gE/60zRcsOY2Vi9b9eT0jww==} - engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - - '@rolldown/binding-win32-arm64-msvc@1.2.1': - resolution: {integrity: sha512-EvRrivJieyHG+AO9lleZWgq+g0+S7oV2C51yuqlcyU/R9net+sI4Pj0F+lUoP2bEr6TWX3SqFaaS0SzfLxSzkw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.2.1': - resolution: {integrity: sha512-Z4eCmn5QJ/5+azF9knpLWKfVd9aidn0mAe9TpJgvBLId9Ax3t0+JVxBmT25Bv7NBbVW1TZyKjQjQReouMeH5UQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - - '@rollup/plugin-alias@6.0.0': - resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} - engines: {node: '>=20.19.0'} - peerDependencies: - rollup: '>=4.0.0' - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-commonjs@29.0.2': - resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-inject@5.0.5': - resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-json@6.1.0': - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-node-resolve@16.0.3': - resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-replace@6.0.3': - resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-terser@1.0.0': - resolution: {integrity: sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==} - engines: {node: '>=20.0.0'} - peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} - cpu: [x64] - os: [win32] - - '@simple-git/args-pathspec@1.0.3': - resolution: {integrity: sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==} - - '@simple-git/argv-parser@1.1.1': - resolution: {integrity: sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==} - - '@sindresorhus/base62@1.0.0': - resolution: {integrity: sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==} - engines: {node: '>=18'} - - '@sindresorhus/is@7.2.0': - resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} - engines: {node: '>=18'} - - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - - '@speed-highlight/core@1.2.15': - resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@stylistic/eslint-plugin@5.10.0': - resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - - '@swc/helpers@0.5.21': - resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} - - '@tailwindcss/node@4.3.3': - resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} - - '@tailwindcss/oxide-android-arm64@4.3.3': - resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [android] - - '@tailwindcss/oxide-darwin-arm64@4.3.3': - resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [darwin] - - '@tailwindcss/oxide-darwin-x64@4.3.3': - resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [darwin] - - '@tailwindcss/oxide-freebsd-x64@4.3.3': - resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [freebsd] - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': - resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} - engines: {node: '>= 20'} - cpu: [arm] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': - resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@tailwindcss/oxide-linux-arm64-musl@4.3.3': - resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@tailwindcss/oxide-linux-x64-gnu@4.3.3': - resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@tailwindcss/oxide-linux-x64-musl@4.3.3': - resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@tailwindcss/oxide-wasm32-wasi@4.3.3': - resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib - - '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': - resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [win32] - - '@tailwindcss/oxide-win32-x64-msvc@4.3.3': - resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [win32] - - '@tailwindcss/oxide@4.3.3': - resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} - engines: {node: '>= 20'} - - '@tailwindcss/postcss@4.3.3': - resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==} - - '@tailwindcss/vite@4.3.3': - resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} - peerDependencies: - vite: ^5.2.0 || ^6 || ^7 || ^8 - - '@tanstack/table-core@8.21.3': - resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} - engines: {node: '>=12'} - - '@tanstack/virtual-core@3.17.8': - resolution: {integrity: sha512-BfEvehNpOT75r5Ksc5xW6NZuXujTfb7nlSEyVu4XHG3gdxNg1KqXruWbDewXOUaUYIo4oRbSfkjIajz4MAT8tA==} - - '@tanstack/vue-table@8.21.3': - resolution: {integrity: sha512-rusRyd77c5tDPloPskctMyPLFEQUeBzxdQ+2Eow4F7gDPlPOB1UnnhzfpdvqZ8ZyX2rRNGmqNnQWm87OI2OQPw==} - engines: {node: '>=12'} - peerDependencies: - vue: '>=3.2' - - '@tanstack/vue-virtual@3.13.36': - resolution: {integrity: sha512-gKpExv4RbB9luVG+SucTXoqPZv/gzu/Yvz6BNO+8kpNxJ2x+I/ulryzl5W9BRciahZGp5Tls3Dp5XP1ztVGbMw==} - peerDependencies: - vue: ^2.7.0 || ^3.0.0 - - '@tiptap/core@3.24.0': - resolution: {integrity: sha512-GTAsXAI32p4hEZgPzvUv2RPrObxamy9AFhmhG10fXSvN/cDUs8naEYVIqDV3Sh99jMwQEbTFKW1E1mcspsY6ow==} - peerDependencies: - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-blockquote@3.24.0': - resolution: {integrity: sha512-DgwEEJ1GbDQcT054ynxoaZGmB9apGeUklPrinq9o6xdLHpdg+bO9HCQzggdB8n21VLLglb8jfAEWsVNwh3eASQ==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-bold@3.24.0': - resolution: {integrity: sha512-CujogYaynasklFKHADUseuvj8X2FnWktTCCo3Hl+nlyRvBTmm5TK2aqiamg3v2P4dBh3O6a70mo8BfRJPuiR1g==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-bubble-menu@3.24.0': - resolution: {integrity: sha512-jRXD+JPu9ayvq78g8hsCxx4q/qUFtrdfIYirRSf5YUseuuUbtfrq83AsGabcygpUTefjJkMQoXNITkh6294Ggw==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-bullet-list@3.24.0': - resolution: {integrity: sha512-IOpAm5c4XVVVvkOef+V9XYMVpea+3MgBpCQgn83UQRlwO9eIMwmcyxOznu7gQPQVShTEpkt4T6uK+ZN9o8meIA==} - peerDependencies: - '@tiptap/extension-list': 3.24.0 - - '@tiptap/extension-code-block@3.24.0': - resolution: {integrity: sha512-NZglw4oHoH6oJ5+HvxxQCYk+wODJmsxzUpRQdsOmje08sekQH+Zt9i4UKimBhg4urpd5r+dKXTslab9a5eQ86w==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-code@3.24.0': - resolution: {integrity: sha512-MAQtrPRQ+HRmcGotWbksdIGeH1gqayFAdvi4lNGeFT7taHXP1o1XD7CQp7iYIKmg8IU4/MQ+RdetSfuC1A9edQ==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-collaboration@3.24.0': - resolution: {integrity: sha512-PF9rFZrZtgr7xemnzQaU1uScUz4GwDjE+vLMosugUJxaoz/zSsHRXQ00dHM32MKxBzbWg3A4ZQTHB7YzAtyl3Q==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - '@tiptap/y-tiptap': ^3.0.4 - yjs: ^13 - - '@tiptap/extension-document@3.24.0': - resolution: {integrity: sha512-yxgM3+yXy2XZzEwH43y2Kp8D1BkblxEWLXqo0YCoAKtxyKCcEaT8kdlf70kS7D0+VSzYU4D0iN7VdQIYHcL2mA==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-drag-handle-vue-3@3.24.0': - resolution: {integrity: sha512-tk9yKgGPYMRAKeCtEdza532EZzbIID7pO6sSLqmteyDH3MxuaJZLhi6tqRheWm55SlPTTJzAUZuY8EchzPpC7g==} - peerDependencies: - '@tiptap/extension-drag-handle': 3.24.0 - '@tiptap/pm': 3.24.0 - '@tiptap/vue-3': 3.24.0 - vue: ^3.0.0 - - '@tiptap/extension-drag-handle@3.24.0': - resolution: {integrity: sha512-DMW2Dx89aS28+FXlpl5nlkZT4dhqdaAO6W76qXVUPIHFvO5yWP0q5UzAPGW5JEBOI+LxWj0AkTDMrX0XrLw9oA==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/extension-collaboration': 3.24.0 - '@tiptap/extension-node-range': 3.24.0 - '@tiptap/pm': 3.24.0 - '@tiptap/y-tiptap': ^3.0.2 - - '@tiptap/extension-dropcursor@3.24.0': - resolution: {integrity: sha512-Dbv1c5LnvG3PT+yEbCNroyOeeUkHq9wcir2pbC7wri7g7d2sCi0+HvKH0MAxLwY3j5NJJSiSyG2ypMaXOAs4sg==} - peerDependencies: - '@tiptap/extensions': 3.24.0 - - '@tiptap/extension-floating-menu@3.24.0': - resolution: {integrity: sha512-7QEbf3mUzFAkejjQGX9f0L507oMtnOBRwHt2skUTR+9yXgudsN8zaDBSSRHLeMWGk9b7L293ZMA6zCRrZaHrfA==} - peerDependencies: - '@floating-ui/dom': ^1.0.0 - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-gapcursor@3.24.0': - resolution: {integrity: sha512-CzCP5/jni5RFwW9jCfBO6auh83GbaioMTpSk6tyR3sd+CbwlBcUdsJFGJkbaRdiSS9dgIyi+6hRbhjpYdHcp+w==} - peerDependencies: - '@tiptap/extensions': 3.24.0 - - '@tiptap/extension-hard-break@3.24.0': - resolution: {integrity: sha512-T/ZEBiHQPMyTqDvXG0tiqBToNeuSemIPmNtdoGSgBN/degVl7VJZqQIrLIvOUHfjf3QkRs7TE/mcqTJsIboO/g==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-heading@3.24.0': - resolution: {integrity: sha512-GCSgapIzQPqEGNcVGE0/Pcjg5wITMLYJlrS3GGVw7BPmECJwgexcoOsEwkxtzJnXT/HpFXbvOFW43sM0KeHSjg==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-horizontal-rule@3.24.0': - resolution: {integrity: sha512-DFzWJTrb23x+qssLLs85vEyho8ItUGp3RY9XUsVTIAGZn5IsoUw8wMsvIBlH1ux4Ch7gLchtcD6kpTdMdrL9kw==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-image@3.24.0': - resolution: {integrity: sha512-mH+bvsX2cPKuZzV7YMQi4FV2YbDP+Kmq36bY+Bwi/x4mYUc8u0cjQxcu8RzLO7GtsgUJPxGMwfkQxmDqXFLZvw==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-italic@3.24.0': - resolution: {integrity: sha512-mf3cbNlbMPUNj3IyUkIke+o3ZpOUrtVeY5Yqs5IM/VhkUUh/PdIzqw74VuqEAJ0Z4oZ6nNDHeYLrl3Be1j99lQ==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-link@3.24.0': - resolution: {integrity: sha512-MwMoNGG2mL5XGFV1tEGunBRglwsIbW+ZOB2QnKiv+Mcbi2JCWMrorndJZBqpVPR5nM+Bef2KnpchEJmYlQLvKQ==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-list-item@3.24.0': - resolution: {integrity: sha512-zl/U3viJiV9OzkKM37AHIUN1af1TSLrcbHUUoNLkfJ33Nq+NlpaXpCVK0rKRqiLFJf7zk/a5KWG5CrOy9TxjKA==} - peerDependencies: - '@tiptap/extension-list': 3.24.0 - - '@tiptap/extension-list-keymap@3.24.0': - resolution: {integrity: sha512-69fKcrngYGEKWNn4R5oLwl0YuV3FY4kufEValVcjnihUmqJTE1vx+fwctYoTsOGnIuNGpUIQ7f9YDD/0w34qBw==} - peerDependencies: - '@tiptap/extension-list': 3.24.0 - - '@tiptap/extension-list@3.24.0': - resolution: {integrity: sha512-GcxDVMMmDGj7OFTBrV7JpVgr5wxlr2vmjwH7U8QxZX7OJI5vrsMYl/U6KRTvUpG8wP+Zmo5jRlLM+BbL+a/W3g==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-mention@3.24.0': - resolution: {integrity: sha512-c68AYrEoHJ4vlBvt5stBUTveKXiNwt5BxaQxgq2R4OXjc3VMoh+XJqo1bBbMNHEJfuGMNpcdfZ2zf09jnBf8/A==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - '@tiptap/suggestion': 3.24.0 - - '@tiptap/extension-node-range@3.24.0': - resolution: {integrity: sha512-JUrhuKD5raii6IsARETNq3seAXUB9UpQGjeSJKBKBOv10PBAq0RLKlI0lbv7t9FR4vfZE7is/XpvoZ0v2Vr9kw==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-ordered-list@3.24.0': - resolution: {integrity: sha512-buRa6bmBDw0TztH+rAcusIye14DiLDS+yGheo6GiNCTD7kKJnksXagBdxvip3jhW5sx7gyAKvoBmvGSg1BbsGA==} - peerDependencies: - '@tiptap/extension-list': 3.24.0 - - '@tiptap/extension-paragraph@3.24.0': - resolution: {integrity: sha512-wD06aB6hO7LgcrlhGiw7I64k2tus9kNoICX5R+UecBSB1DVJdzKvXoXL2kPNv4DqYvljHdkIeK/OpuOTQd6MJA==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-placeholder@3.24.0': - resolution: {integrity: sha512-3jfYYCIuwMADhvZ92vB6c80YiTmgTSFR23JqyLps8qkQtV59Va5CBYpwJtSs1+VrbCVnNxhZBHhVXusZO3uRkA==} - peerDependencies: - '@tiptap/extensions': 3.24.0 - - '@tiptap/extension-strike@3.24.0': - resolution: {integrity: sha512-sfN1iQs6Fdlorrfe8wipDkTPwu/Egx3s2fkY7TAWusTGFHwlovuRUGFKqCL9dI4N3u6uqUMpEuWmQNgv+aQGjQ==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-text@3.24.0': - resolution: {integrity: sha512-Im7keLPEihxm3+LyF+drYCoaOY5hlq35lvHAp/el6M8pJ/scts88HrYpdR1Yc4BtpZBIhfHSyWgPaupI4qwdeg==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extension-underline@3.24.0': - resolution: {integrity: sha512-D4W4X3UMq9dLVIOfPB9+UodQ4eAJ8yDcm8qFWAwq0a15YWH6bnwulCuIdV+U5dEG+yaRxN8haB9GrrID9jmrSA==} - peerDependencies: - '@tiptap/core': 3.24.0 - - '@tiptap/extensions@3.24.0': - resolution: {integrity: sha512-z6gRYzy2ucJp07OQ0F2W07NxyhMTxPYH1ia2eGiQkWax1i56oExpjMsDHP8THWlg8Tb7NnbfKpkfh881EsmofA==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/markdown@3.24.0': - resolution: {integrity: sha512-EIEQmH8tOIWAxVnRpYSALIQCU8dVaGQoEVvmsa6B2B/zZeIsBSEZzcVVE2yGEVZtShf3ag37Szr6Lu7lTor3sw==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/pm@3.24.0': - resolution: {integrity: sha512-QQP/78ryOZDN99gNBV7dgh69/8AYaOYQYFklq/iR+ZRFaaL3+qqHFvPVJapGkzPdymBgNJ34xjFM8n5pJ4QmMg==} - - '@tiptap/starter-kit@3.24.0': - resolution: {integrity: sha512-Ef4PCP96vcY2GonXN9J0M8iC6zvxPTmQlL/QZiCwuYqqnH/hNpYIjNSQdTndiDpxRKofa32Sr2HWktgEnL32Bg==} - - '@tiptap/suggestion@3.24.0': - resolution: {integrity: sha512-UlLIij1fxFy7tbCmqUoInWRijzsi8hsbaXKCx6L3KvLXtxHb4hMnDhd6W++rOk9Q1hDpmNf8qNIX498q/ZNstw==} - peerDependencies: - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - - '@tiptap/vue-3@3.24.0': - resolution: {integrity: sha512-B7H630A5kGRHPrj60FMLbKC8EBWFvGeP8EytaKqxfByEFW6I2mYeZV4BzDptx6Hgy7h5oTXJ1yjc8DH1Q80WYA==} - peerDependencies: - '@floating-ui/dom': ^1.0.0 - '@tiptap/core': 3.24.0 - '@tiptap/pm': 3.24.0 - vue: ^3.0.0 - - '@tiptap/y-tiptap@3.0.7': - resolution: {integrity: sha512-3VG01F7i2JDghWsBZSBKi7ypMiN5UVVSyD18IwoXx7ilm0ZynrTS+XNpmgxfuiSBjdauWk7tUlP04xfM8Bw4Vw==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - peerDependencies: - prosemirror-model: ^1.7.1 - prosemirror-state: ^1.2.3 - prosemirror-view: ^1.9.10 - y-protocols: ^1.0.1 - yjs: ^13.5.38 - - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - - '@types/esrecurse@4.3.1': - resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/jsesc@2.5.1': - resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - - '@types/web-bluetooth@0.0.20': - resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - - '@types/web-bluetooth@0.0.21': - resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} - - '@typescript-eslint/eslint-plugin@8.66.0': - resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.66.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/parser@8.66.0': - resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/project-service@8.66.0': - resolution: {integrity: sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/scope-manager@8.66.0': - resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.66.0': - resolution: {integrity: sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/type-utils@8.66.0': - resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/types@8.66.0': - resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.66.0': - resolution: {integrity: sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/utils@8.66.0': - resolution: {integrity: sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.1.0' - - '@typescript-eslint/visitor-keys@8.66.0': - resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@unhead/bundler@3.4.0': - resolution: {integrity: sha512-RnsCYynvDiUwmZ/U7TkFwFLr6yTRXVFJlZFj3ehi+m6M4f+GWL/O+6BTQzaHdz59zg2UHHejQvwuXvcL7dj0Dw==} - peerDependencies: - '@unhead/cli': ^3.4.0 - '@vitejs/devtools-kit': ^0.4.1 - esbuild: '>=0.17.0' - lightningcss: '>=1.20.0' - oxc-parser: '>=0.98.0' - rolldown: '>=1.0.0' - unhead: ^3.4.0 - vite: '>=6.4.2' - webpack: '>=5.0.0' - peerDependenciesMeta: - '@unhead/cli': - optional: true - '@vitejs/devtools-kit': - optional: true - esbuild: - optional: true - lightningcss: - optional: true - oxc-parser: - optional: true - rolldown: - optional: true - vite: - optional: true - webpack: - optional: true - - '@unhead/vue@3.4.0': - resolution: {integrity: sha512-fSnDS9d++bqR4t1z6+zFN7bQB5F0+5nwvE4yHW7BGRfEmssCP4fel0GprooUgoLkzx+FcAWMwVIakyaeErSRBA==} - peerDependencies: - vite: '>=6.4.2' - vue: '>=3.5.18' - webpack: '>=5.0.0' - peerDependenciesMeta: - vite: - optional: true - webpack: - optional: true - - '@unrs/resolver-binding-android-arm-eabi@1.12.2': - resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.12.2': - resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.12.2': - resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.12.2': - resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.12.2': - resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': - resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': - resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': - resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-arm64-musl@1.12.2': - resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': - resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-loong64-musl@1.12.2': - resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': - resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': - resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': - resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': - resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-x64-gnu@1.12.2': - resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-x64-musl@1.12.2': - resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@unrs/resolver-binding-openharmony-arm64@1.12.2': - resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} - cpu: [arm64] - os: [openharmony] - - '@unrs/resolver-binding-wasm32-wasi@1.12.2': - resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': - resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': - resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.12.2': - resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} - cpu: [x64] - os: [win32] - - '@valibot/to-json-schema@1.7.1': - resolution: {integrity: sha512-3qkmU6KXWh8GIThEAW3kuRHPQBMjWkKy+Ppz3WkUucx53DTpOa6siMn4xDGSOhlVyMrDaJTCTMLYPZVAIk1P0A==} - peerDependencies: - valibot: ^1.4.0 - - '@vercel/nft@1.5.0': - resolution: {integrity: sha512-IWTDeIoWhQ7ZtRO/JRKH+jhmeQvZYhtGPmzw/QGDY+wDCQqfm25P9yIdoAFagu4fWsK4IwZXDFIjrmp5rRm/sA==} - engines: {node: '>=20'} - hasBin: true - - '@vitejs/devtools-kit@0.4.10': - resolution: {integrity: sha512-jaA4FQKlUa5vKrCLSZSJWcZ9DpHSl8j4R7Dq4kPeOmtXngb5eap/ZdumY8f5soCPWarjDKdPi23sAkiLH6VT/g==} - peerDependencies: - vite: '*' - - '@vitejs/plugin-vue-jsx@5.1.6': - resolution: {integrity: sha512-YXvi4as2clxt6DFw5+a0tTA97ntiQXm/raR8ofNj3aNwwdlVGTiG2gp7EvfZW17P50acL/9bP0ccF4XnqNmlgA==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - vue: ^3.0.0 - - '@vitejs/plugin-vue@6.0.8': - resolution: {integrity: sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - vue: ^3.2.25 - - '@volar/language-core@2.4.28': - resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - - '@volar/source-map@2.4.28': - resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - - '@volar/typescript@2.4.28': - resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue-macros/common@3.1.4': - resolution: {integrity: sha512-/5Fv+6DgIcM9ajY05ZmKBv+LMX1M9A0X+IUwDRVdt67ciw8OV9bvG2r34p3RiEadlsQybjhKPRKNXDC8Bp23cw==} - engines: {node: '>=20.19.0'} - peerDependencies: - vue: ^2.7.0 || ^3.2.25 - peerDependenciesMeta: - vue: - optional: true - - '@vue/babel-helper-vue-transform-on@2.0.1': - resolution: {integrity: sha512-uZ66EaFbnnZSYqYEyplWvn46GhZ1KuYSThdT68p+am7MgBNbQ3hphTL9L+xSIsWkdktwhPYLwPgVWqo96jDdRA==} - - '@vue/babel-plugin-jsx@2.0.1': - resolution: {integrity: sha512-a8CaLQjD/s4PVdhrLD/zT574ZNPnZBOY+IhdtKWRB4HRZ0I2tXBi5ne7d9eCfaYwp5gU5+4KIyFTV1W1YL9xZA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - - '@vue/babel-plugin-resolve-type@2.0.1': - resolution: {integrity: sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@vue/compiler-core@3.5.40': - resolution: {integrity: sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==} - - '@vue/compiler-dom@3.5.40': - resolution: {integrity: sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==} - - '@vue/compiler-sfc@3.5.40': - resolution: {integrity: sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==} - - '@vue/compiler-ssr@3.5.40': - resolution: {integrity: sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==} - - '@vue/devtools-api@8.2.1': - resolution: {integrity: sha512-6u4vXBlIBAC1wMplIZgpyPn7uh/s4Bf6F5bMzvLv+EdJ0aHs/+4B7Ygv864EStQSjRbsRzTko/kUG1A1IejQ3A==} - - '@vue/devtools-core@8.2.1': - resolution: {integrity: sha512-s/VfAY9oDTb/kFEWmy461jaFde2MIV1RO/gi1vwM+PAZBZ/Pc2Ndu3BNBdZUze8QDUuyYvElbEEGA83syjJfzA==} - peerDependencies: - vue: ^3.0.0 - - '@vue/devtools-kit@8.2.1': - resolution: {integrity: sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==} - - '@vue/devtools-shared@8.2.1': - resolution: {integrity: sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==} - - '@vue/language-core@3.3.11': - resolution: {integrity: sha512-QJmpliwAVpC/OxubIByPAhNzsQPRc8/gxlN2qnVzVfIMjMDz/9RnXRFoetjz5yEgXVXyp4LqhXq3V53PjmNzFw==} - - '@vue/reactivity@3.5.40': - resolution: {integrity: sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==} - - '@vue/runtime-core@3.5.40': - resolution: {integrity: sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==} - - '@vue/runtime-dom@3.5.40': - resolution: {integrity: sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==} - - '@vue/server-renderer@3.5.40': - resolution: {integrity: sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==} - - '@vue/shared@3.5.40': - resolution: {integrity: sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==} - - '@vueuse/core@10.11.1': - resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} - - '@vueuse/core@14.4.0': - resolution: {integrity: sha512-X4WHz1HlCzCBoYXesUkifzzWBAcZgXG8Fi5iNPQg/epdzOB3gu8Fawj3hvuwYR1nGcXGnvxwYYcUC/71++svtQ==} - peerDependencies: - vue: ^3.5.0 - - '@vueuse/integrations@14.4.0': - resolution: {integrity: sha512-oJz9qTgczvA7L1nXQFRU7h8tQbOCoiceqvMMhT9XYMyOGTqLJ2rEa09PON+nD2t48sZUfeOmg4eaWJXV4sZb/w==} - peerDependencies: - async-validator: ^4 - axios: ^1 - change-case: ^5 - drauu: ^0.4 - focus-trap: ^7 || ^8 - fuse.js: ^7 - idb-keyval: ^6 - jwt-decode: ^4 - nprogress: ^0.2 - qrcode: ^1.5 - sortablejs: ^1 - universal-cookie: ^7 || ^8 - vue: ^3.5.0 - peerDependenciesMeta: - async-validator: - optional: true - axios: - optional: true - change-case: - optional: true - drauu: - optional: true - focus-trap: - optional: true - fuse.js: - optional: true - idb-keyval: - optional: true - jwt-decode: - optional: true - nprogress: - optional: true - qrcode: - optional: true - sortablejs: - optional: true - universal-cookie: - optional: true - - '@vueuse/metadata@10.11.1': - resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} - - '@vueuse/metadata@14.4.0': - resolution: {integrity: sha512-swx/255R6JyHZFJhx845iz5CRWDZdCfvkZOpACWc5+c5WHcG24mv8gUT1WIdFQaHt6dq79rvILd9QnCWiyVm9g==} - - '@vueuse/shared@10.11.1': - resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} - - '@vueuse/shared@14.4.0': - resolution: {integrity: sha512-JRgY90Sz8DDtPMsaDflvPMp9xYk69JZAmbuDvAquUVXKr2gEjqtzGNTTthLfckH0BzBqvnu31gb4a8TGLRe79g==} - peerDependencies: - vue: ^3.5.0 - - abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} - - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - - acorn-import-attributes@1.9.5: - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} - peerDependencies: - acorn: ^8 - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.18.0: - resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - - ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - - alien-signals@3.2.1: - resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - - ansis@4.3.1: - resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} - engines: {node: '>=14'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - archiver-utils@5.0.2: - resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} - engines: {node: '>= 14'} - - archiver@7.0.1: - resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} - engines: {node: '>= 14'} - - are-docs-informative@0.0.2: - resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} - engines: {node: '>=14'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - - ast-kit@2.2.0: - resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} - engines: {node: '>=20.19.0'} - - ast-walker-scope@0.9.0: - resolution: {integrity: sha512-IJdzo2vLiElBxKzwS36VsCue/62d6IdWjnPB2v3nuPKeWGynp6FF/CYoLa5i/3jXH/z97ZDdsXz6abpgM6w07A==} - engines: {node: '>=20.19.0'} - - async-sema@3.1.1: - resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} - - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - autoprefixer@10.5.4: - resolution: {integrity: sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - - b4a@1.8.1: - resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} - peerDependencies: - react-native-b4a: '*' - peerDependenciesMeta: - react-native-b4a: - optional: true - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - bare-events@2.8.3: - resolution: {integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==} - peerDependencies: - bare-abort-controller: '*' - peerDependenciesMeta: - bare-abort-controller: - optional: true - - bare-fs@4.7.1: - resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==} - engines: {bare: '>=1.16.0'} - peerDependencies: - bare-buffer: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - - bare-os@3.9.1: - resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} - engines: {bare: '>=1.14.0'} - - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - - bare-stream@2.13.1: - resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} - peerDependencies: - bare-abort-controller: '*' - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-abort-controller: - optional: true - bare-buffer: - optional: true - bare-events: - optional: true - - bare-url@2.4.3: - resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - baseline-browser-mapping@2.11.7: - resolution: {integrity: sha512-APw5YuIQAg6L9w4sHDI6j26DGFJI6RpYOhnkMPdC9lWbkKvsyPHzDsve1yd73lk21yz7Y09Kci8B2Pp9FonzWA==} - engines: {node: '>=6.0.0'} - hasBin: true - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - birpc@2.9.0: - resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} - - birpc@4.0.0: - resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - brace-expansion@2.1.0: - resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} - - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} - engines: {node: 18 || 20 || >=22} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browserslist@4.28.7: - resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - buffer-crc32@1.0.0: - resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} - engines: {node: '>=8.0.0'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - - builtin-modules@5.2.0: - resolution: {integrity: sha512-02yxLeyxF4dNl6SlY6/5HfRSrSdZ/sCPoxy2kZNP5dZZX8LSAD9aE2gtJIUgWrsQTiMPl3mxESyrobSwvRGisQ==} - engines: {node: '>=18.20'} - - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} - - c12@3.3.4: - resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} - peerDependencies: - magicast: '*' - peerDependenciesMeta: - magicast: - optional: true - - cac@7.0.0: - resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} - engines: {node: '>=20.19.0'} - - caniuse-api@4.0.0: - resolution: {integrity: sha512-B0hQ1OLyJuHTQSOWXvwibWqM6DCoqJdvBA6X1S/53bd4XU7LJ1yurIPlrsouol3mw1jh9pGI4ivubSpmJeIqCA==} - - caniuse-lite@1.0.30001806: - resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} - - change-case@5.4.4: - resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} - - chokidar@5.0.0: - resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} - engines: {node: '>= 20.19.0'} - - chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - - ci-info@4.4.0: - resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} - engines: {node: '>=8'} - - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - - citty@0.2.2: - resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} - - cliui@9.0.1: - resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} - engines: {node: '>=20'} - - cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - colortranslator@5.0.0: - resolution: {integrity: sha512-Z3UPUKasUVDFCDYAjP2fmlVRf1jFHJv1izAmPjiOa0OCIw1W7iC8PZ2GsoDa8uZv+mKyWopxxStT9q05+27h7w==} - - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - comment-parser@1.4.7: - resolution: {integrity: sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==} - engines: {node: '>= 12.0.0'} - - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - - compatx@0.2.0: - resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} - - compress-commons@6.0.2: - resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} - engines: {node: '>= 14'} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - confbox@0.2.4: - resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - convert-hrtime@5.0.0: - resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} - engines: {node: '>=12'} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-es@1.2.3: - resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} - - cookie-es@2.0.1: - resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} - - cookie-es@3.1.1: - resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} - - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - crc-32@1.2.2: - resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} - engines: {node: '>=0.8'} - hasBin: true - - crc32-stream@6.0.0: - resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} - engines: {node: '>= 14'} - - croner@10.0.1: - resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} - engines: {node: '>=18.0'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - crossws@0.3.5: - resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - - crossws@0.4.10: - resolution: {integrity: sha512-pz3oubH/dt12KjqsUB0IuXW4nwRDQ583iDsP4555Cpdqx0NoU7pGlWBcayyFI8f/l/idRpgjMEfwuOxSWJYlIA==} - peerDependencies: - srvx: '>=0.11.5' - peerDependenciesMeta: - srvx: - optional: true - - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - - css-tree@2.2.1: - resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - - css-tree@3.2.1: - resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - cssnano-preset-default@8.0.2: - resolution: {integrity: sha512-+jQAqIKCqMmBjZs7741XkilU93ITZ/EW8gjAkMmujdCzfDkfjrDBv2VqkSu29Fzeig/0rZ3S9IAwfPLlmXEUfQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - cssnano-utils@6.0.1: - resolution: {integrity: sha512-zk65GIxA8tCjqVk7nTm1mE+ZKxtnxAvU5JSUaBLXbAr3ZF7IOvz3fbPOnEDvZKhnS7GOIitXTS5BgehLzNoc8Q==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - cssnano@8.0.2: - resolution: {integrity: sha512-K+a76gA1v0/CsYgcsE95HGGyIuPKxpQSetwSwz4nHEM8fFXqSkzq2JzEXFL8v5+CCjxzVVVhPcTK3Oo8SaF/xA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - csso@5.0.5: - resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - db0@0.3.4: - resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} - peerDependencies: - '@electric-sql/pglite': '*' - '@libsql/client': '*' - better-sqlite3: '*' - drizzle-orm: '*' - mysql2: '*' - sqlite3: '*' - peerDependenciesMeta: - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - better-sqlite3: - optional: true - drizzle-orm: - optional: true - mysql2: - optional: true - sqlite3: - optional: true - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - default-browser-id@5.0.1: - resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} - engines: {node: '>=18'} - - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} - engines: {node: '>=18'} - - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - - defu@6.1.7: - resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} - - denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - - detect-indent@7.0.2: - resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} - engines: {node: '>=12.20'} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - devalue@5.9.0: - resolution: {integrity: sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==} - - devframe@0.7.15: - resolution: {integrity: sha512-pHcCgDILv9BfF0oqEcpPzsPG/2/TLrhcYIUiWTNmP+YiyTmaGkW0osR/48STotnJNi3O2upj5L/6tpLOl/Ravg==} - peerDependencies: - '@modelcontextprotocol/sdk': ^1.0.0 - cac: ^7.0.0 - peerDependenciesMeta: - '@modelcontextprotocol/sdk': - optional: true - cac: - optional: true - - devframe@0.8.2: - resolution: {integrity: sha512-oodQXEQnrvufA1so/E058Z3SG3bk9AlUE5+NIAsyx5ZJH9P/oX6WMxjC0bs5PPwtKbS7pBHjxja2AD8EwGE8/Q==} - hasBin: true - peerDependencies: - '@modelcontextprotocol/client': ^2.0.0 - '@modelcontextprotocol/server': ^2.0.0 - cac: ^7.0.0 - peerDependenciesMeta: - '@modelcontextprotocol/client': - optional: true - '@modelcontextprotocol/server': - optional: true - cac: - optional: true - - diff@8.0.4: - resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} - engines: {node: '>=0.3.1'} - - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - - dot-prop@10.1.0: - resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} - engines: {node: '>=20'} - - dotenv@17.4.2: - resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} - engines: {node: '>=12'} - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - electron-to-chromium@1.5.398: - resolution: {integrity: sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ==} - - embla-carousel-auto-height@8.6.0: - resolution: {integrity: sha512-/HrJQOEM6aol/oF33gd2QlINcXy3e19fJWvHDuHWp2bpyTa+2dm9tVVJak30m2Qy6QyQ6Fc8DkImtv7pxWOJUQ==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel-auto-scroll@8.6.0: - resolution: {integrity: sha512-WT9fWhNXFpbQ6kP+aS07oF5IHYLZ1Dx4DkwgCY8Hv2ZyYd2KMCPfMV1q/cA3wFGuLO7GMgKiySLX90/pQkcOdQ==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel-autoplay@8.6.0: - resolution: {integrity: sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel-class-names@8.6.0: - resolution: {integrity: sha512-l1hm1+7GxQ+zwdU2sea/LhD946on7XO2qk3Xq2XWSwBaWfdgchXdK567yzLtYSHn4sWYdiX+x4nnaj+saKnJkw==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel-fade@8.6.0: - resolution: {integrity: sha512-qaYsx5mwCz72ZrjlsXgs1nKejSrW+UhkbOMwLgfRT7w2LtdEB03nPRI06GHuHv5ac2USvbEiX2/nAHctcDwvpg==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel-reactive-utils@8.6.0: - resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} - peerDependencies: - embla-carousel: 8.6.0 - - embla-carousel-vue@8.6.0: - resolution: {integrity: sha512-v8UO5UsyLocZnu/LbfQA7Dn2QHuZKurJY93VUmZYP//QRWoCWOsionmvLLAlibkET3pGPs7++03VhJKbWD7vhQ==} - peerDependencies: - vue: ^3.2.37 - - embla-carousel-wheel-gestures@8.1.0: - resolution: {integrity: sha512-J68jkYrxbWDmXOm2n2YHl+uMEXzkGSKjWmjaEgL9xVvPb3HqVmg6rJSKfI3sqIDVvm7mkeTy87wtG/5263XqHQ==} - engines: {node: '>=10'} - peerDependencies: - embla-carousel: ^8.0.0 || ~8.0.0-rc03 - - embla-carousel@8.6.0: - resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} - - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - enhanced-resolve@5.24.5: - resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} - engines: {node: '>=10.13.0'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} - - error-stack-parser-es@1.0.5: - resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - - error-stack-parser-es@2.0.1: - resolution: {integrity: sha512-J36ntO+rMQVRuR/umlmxmfLi4TpWwtmTnHoJoXTiC2xDNazs0VDPKcX6pbhZMDd2HFtH9isMBJXMdbki+A++Pg==} - - errx@0.1.2: - resolution: {integrity: sha512-chfpPHmCerdo/rXr/nNvPZRkV4WwDRwzwnsJ0Uzz3tVi8Z41tDctRjduYy1138ii77AFlts1qvWtX3g/Acg91Q==} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} - - esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} - engines: {node: '>=18'} - hasBin: true - - esbuild@0.28.0: - resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - eslint-config-flat-gitignore@2.3.0: - resolution: {integrity: sha512-bg4ZLGgoARg1naWfsINUUb/52Ksw/K22K+T16D38Y8v+/sGwwIYrGvH/JBjOin+RQtxxC9tzNNiy4shnGtGyyQ==} - peerDependencies: - eslint: ^9.5.0 || ^10.0.0 - - eslint-flat-config-utils@3.2.0: - resolution: {integrity: sha512-PHgo1X5uqIorJONLVD9BIaOSdoYFD3z/AeJljdqDPlWVRpeCYkDbK9k0AXoYVqqNJr6FEYIEr5Rm2TSktLQcHw==} - - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true - - eslint-merge-processors@2.0.0: - resolution: {integrity: sha512-sUuhSf3IrJdGooquEUB5TNpGNpBoQccbnaLHsb1XkBLUPPqCNivCpY05ZcpCOiV9uHwO2yxXEWVczVclzMxYlA==} - peerDependencies: - eslint: '*' - - eslint-plugin-import-lite@0.6.0: - resolution: {integrity: sha512-80vevx2A7i3H7n1/6pqDO8cc5wRz6OwLDvIyVl9UflBV1N1f46e9Ihzi65IOLYoSxM6YykK2fTw1xm0Ixx6aTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - - eslint-plugin-import-x@4.17.1: - resolution: {integrity: sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/utils': ^8.56.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - eslint-import-resolver-node: '*' - peerDependenciesMeta: - '@typescript-eslint/utils': - optional: true - eslint-import-resolver-node: - optional: true - - eslint-plugin-jsdoc@63.3.3: - resolution: {integrity: sha512-xI4IeVRzRFA2DGHrPLIxF3U+oJHU3FE+P9Zb27fVs5dPHgfcpoAs0PyCbznVhK7pwR+9BPUztFeXSgpw/CL4Yg==} - engines: {node: ^22.13.0 || >=24} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 - - eslint-plugin-regexp@3.1.1: - resolution: {integrity: sha512-MxR5nqoQCtVWmJwia0D2+NlXX1xzdpkslsVOZLEYQ4PQWEaL65PCZXURxaBc3lPnkNFpNxzMIRmYVxdl8giXRA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: '>=9.38.0' - - eslint-plugin-unicorn@73.0.0: - resolution: {integrity: sha512-V0YatLe9nkGhXEXKe2Qljb1EY0sJHwDV0HUF1NKFwtsHh/fU7qGHDgv+6fchzZcgU2/7noHo2gdjnmo0P2uDPw==} - engines: {node: '>=22'} - peerDependencies: - eslint: '>=10.4' - - eslint-plugin-vue@10.10.0: - resolution: {integrity: sha512-dL9x9rBHqqNcByWiLOHK6L0SB97V82/NC0cZRn9cXPjM7pCuWlpQQP9bFH4vjBv80ej1ZpzAkuD8zWH1o9bZbA==} - 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 || ^10.0.0 - vue-eslint-parser: ^10.3.0 - peerDependenciesMeta: - '@stylistic/eslint-plugin': - optional: true - '@typescript-eslint/parser': - optional: true - - eslint-processor-vue-blocks@2.0.0: - resolution: {integrity: sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==} - peerDependencies: - '@vue/compiler-sfc': ^3.3.0 - eslint: '>=9.0.0' - - eslint-scope@9.1.2: - resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - eslint-typegen@2.3.1: - resolution: {integrity: sha512-zVdh8rThBvv2o5T/K524Fr5iy1Jo0q09rHL7y7FbOhgMB177T2gw+shxfC4ChCEqdq6/y6LJA4j8Fbr/Xls9aw==} - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@5.0.1: - resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - eslint@10.9.1: - resolution: {integrity: sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - espree@11.2.0: - resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - - events-universal@1.0.1: - resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - - exsolve@1.1.1: - resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-npm-meta@2.2.0: - resolution: {integrity: sha512-99jPl8JkCSCa4VlboNU1XuL98ijm74Pm9CGo6H4BoMVoVh1uhguQcvwLgXDT8Vkl2qj/UEQ0J9gD8beHjTFk1w==} - hasBin: true - - fast-string-truncated-width@3.0.3: - resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} - - fast-string-width@3.0.2: - resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - - fast-wrap-ansi@0.2.0: - resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up-simple@1.0.1: - resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} - engines: {node: '>=18'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - find-up@8.0.0: - resolution: {integrity: sha512-JGG8pvDi2C+JxidYdIwQDyS/CgcrIdh18cvgxcBge3wSHRQOrooMD3GlFBcmMJAN9M42SAZjDp5zv1dglJjwww==} - engines: {node: '>=20'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - - fnv1a-64@0.1.2: - resolution: {integrity: sha512-mJbcILTPybAR1jdOwt/lVv8N2cffeJFFP+gVbSAwLEx1ujXH27RpPd8Rokec/KX9c76UYIB6Co+H4lQzxPnJfA==} - - fontaine@0.8.0: - resolution: {integrity: sha512-eek1GbzOdWIj9FyQH/emqW1aEdfC3lYRCHepzwlFCm5T77fBSRSyNRKE6/antF1/B1M+SfJXVRQTY9GAr7lnDg==} - engines: {node: '>=18.12.0'} - - fontkitten@1.0.3: - resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} - engines: {node: '>=20'} - - fontless@0.2.1: - resolution: {integrity: sha512-mUWZ8w91/mw2KEcZ6gHNoNNmsAq9Wiw2IypIux5lM03nhXm+WSloXGUNuRETNTLqZexMgpt7Aj/v63qqrsWraQ==} - engines: {node: '>=18.12.0'} - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - - framer-motion@13.1.1: - resolution: {integrity: sha512-B/xn2TPS4f61cEBLFjiYlQFnBZUW1YVj/LM+C+N4OP8Rs95VLEI2ot/RlfBg111la/EiyECFaJJi/A3FWA8MUA==} - peerDependencies: - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function-timeout@1.0.2: - resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} - engines: {node: '>=18'} - - fuse.js@7.5.0: - resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==} - engines: {node: '>=10'} - - fzf@0.5.2: - resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} - - generic-names@4.0.0: - resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} - - get-port-please@3.2.0: - resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} - - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.14.0: - resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} - - giget@3.3.1: - resolution: {integrity: sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg==} - hasBin: true - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - - glob@13.0.6: - resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} - engines: {node: 18 || 20 || >=22} - - global-directory@4.0.1: - resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} - engines: {node: '>=18'} - - globals@17.9.0: - resolution: {integrity: sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==} - engines: {node: '>=18'} - - globby@16.2.0: - resolution: {integrity: sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==} - engines: {node: '>=20'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - gzip-size@7.0.0: - resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - h3@1.15.11: - resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} - - h3@2.0.1-rc.26: - resolution: {integrity: sha512-GDxlvDsKxgjRvG5UBRJYyGJTMWLV30CJ4cV+e7QCTgftDHihrvio1fVPbNembhEr6J4WNm8IWy3fookgyTweLw==} - engines: {node: '>=20.11.1'} - hasBin: true - peerDependencies: - crossws: ^0.4.9 - peerDependenciesMeta: - crossws: - optional: true - - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} - engines: {node: '>= 0.4'} - - hey-listen@1.0.8: - resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} - - hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - - hookable@6.1.1: - resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} - - html-entities@2.6.0: - resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} - - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} - - http-shutdown@1.2.2: - resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - httpxy@0.5.1: - resolution: {integrity: sha512-JPhqYiixe1A1I+MXDewWDZqeudBGU8Q9jCHYN8ML+779RQzLjTi78HBvWz4jMxUD6h2/vUL12g4q/mFM0OUw1A==} - - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - identifier-regex@1.1.0: - resolution: {integrity: sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA==} - engines: {node: '>=18'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.6: - resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} - engines: {node: '>= 4'} - - image-meta@0.2.2: - resolution: {integrity: sha512-3MOLanc3sb3LNGWQl1RlQlNWURE5g32aUphrDyFeCsxBTk08iE3VNe4CwsUZ0Qs1X+EfX0+r29Sxdpza4B+yRA==} - - import-meta-resolve@4.2.0: - resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - - impound@1.1.6: - resolution: {integrity: sha512-ugavDQkE74SGrBjagNIwNVHNBxX14mmfQnTm4jFGzOoWwYsgihqV698BNr5xwRY9quKK4rEg8bc6ECltllMr+w==} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@4.1.1: - resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - ioredis@5.10.1: - resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} - engines: {node: '>=12.22.0'} - - iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} - - is-builtin-module@5.0.0: - resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} - engines: {node: '>=18.20'} - - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-identifier@1.1.0: - resolution: {integrity: sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==} - engines: {node: '>=18'} - - is-in-ssh@1.0.0: - resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} - engines: {node: '>=20'} - - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-installed-globally@1.0.0: - resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} - engines: {node: '>=18'} - - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@4.0.0: - resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} - engines: {node: '>=12'} - - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - is-wsl@3.1.1: - resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} - engines: {node: '>=16'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isexe@4.0.0: - resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} - engines: {node: '>=20'} - - isomorphic.js@0.2.5: - resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - jiti@2.7.0: - resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} - hasBin: true - - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - jsdoc-type-pratt-parser@7.2.0: - resolution: {integrity: sha512-dh140MMgjyg3JhJZY/+iEzW+NO5xR2gpbDFKHqotCmexElVntw7GjWjt511+C/Ef02RU5TKYrJo/Xlzk+OLaTw==} - engines: {node: '>=20.0.0'} - - jsdoc-type-pratt-parser@8.0.0: - resolution: {integrity: sha512-uQu/fXVqVaMg6gM8/E5G5+eygVcZ1NV0Z51CvqhNa2bDWxvHMl484ETr6vph4oPyC+KUcbP/w2W2pewfCiR9aQ==} - engines: {node: '>=20.0.0'} - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-to-typescript-lite@15.0.0: - resolution: {integrity: sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - - klona@2.0.6: - resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} - engines: {node: '>= 8'} - - knitwork@1.3.0: - resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} - - launch-editor@2.14.1: - resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} - - lazystream@1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - lib0@0.2.117: - resolution: {integrity: sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw==} - engines: {node: '>=16'} - hasBin: true - - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-android-arm64@1.33.0: - resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-arm64@1.33.0: - resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-darwin-x64@1.33.0: - resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-freebsd-x64@1.33.0: - resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm-gnueabihf@1.33.0: - resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-gnu@1.33.0: - resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-arm64-musl@1.33.0: - resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-gnu@1.33.0: - resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-musl@1.33.0: - resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-arm64-msvc@1.33.0: - resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss-win32-x64-msvc@1.33.0: - resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - - lightningcss@1.33.0: - resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} - engines: {node: '>= 12.0.0'} - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - linkifyjs@4.3.3: - resolution: {integrity: sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==} - - listhen@1.10.0: - resolution: {integrity: sha512-kfz4C0OrC6IpaVMtYDJtf6PFjurxe9NBBoDAh/o2p587INryFOO4DQ9OetbCdDrWFt1m1CJKvYrzkGsuPHw8nQ==} - hasBin: true - - loader-utils@3.3.1: - resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} - engines: {node: '>= 12.13.0'} - - local-pkg@1.2.1: - resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} - engines: {node: '>=14'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - locate-path@8.0.0: - resolution: {integrity: sha512-XT9ewWAC43tiAV7xDAPflMkG0qOPn2QjHqlgX8FOqmWa/rxnyYDulF9T0F7tRy1u+TVTmK/M//6VIOye+2zDXg==} - engines: {node: '>=20'} - - lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - - lodash.isarguments@3.1.0: - resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - - lodash@4.18.1: - resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@11.4.0: - resolution: {integrity: sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==} - engines: {node: 20 || >=22} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - magic-regexp@0.10.0: - resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} - - magic-string-ast@1.0.3: - resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} - engines: {node: '>=20.19.0'} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magic-string@1.2.2: - resolution: {integrity: sha512-veT/+7iXrXzT39XnEN4lOxtNl72dMgJ8Lp+5Bd6YcMSWpb0n0MjBM8Uuooi6jgJr8dhUW2swQgBmoZVMni5SVg==} - - magicast@0.5.4: - resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} - - make-asynchronous@1.1.0: - resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} - engines: {node: '>=18'} - - marked@17.0.6: - resolution: {integrity: sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA==} - engines: {node: '>= 20'} - hasBin: true - - mdn-data@2.0.28: - resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} - - mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - - mdn-data@2.29.0: - resolution: {integrity: sha512-pVxQFCcaYUEAH853+v7yoI/qzhxXSq1bTb9obMYGYAN1c3Hen+XDCEvr296XhstrwlSTNgOR7mCSD4JPjbJe5A==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - - mime@4.1.0: - resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} - engines: {node: '>=16'} - hasBin: true - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} - - minimatch@5.1.9: - resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} - engines: {node: '>=10'} - - minimatch@9.0.9: - resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - - mocked-exports@0.1.1: - resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} - - motion-dom@13.1.1: - resolution: {integrity: sha512-XSf8VYWSB6G/0IY3rWVbyLcxWXtAVHkN1PQE2agTaCv3u8RGvbwu56TyyR/MNzBqqNavEBTZzErcxI1TxBrjcA==} - - motion-utils@13.0.0: - resolution: {integrity: sha512-7DnN7TmbLcYXcG4RVadXIihWlyuM9afoUww8Y5Agg431kGKiuL2/OMyP4mJ5wLz+pvN3t5ySClLOaVXJ+wekRQ==} - - motion-v@2.4.0: - resolution: {integrity: sha512-kRDGMAZk3nvdjEO36Wo6pezSEIStGXGhVFiwo1QkUDsUg8mB5igjYPXyece8wtu2DrHhmFfA6Y1nOz07+5QH4A==} - peerDependencies: - '@vueuse/core': '>=10.0.0' - vue: '>=3.0.0' - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - - nanoid@3.3.16: - resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanotar@0.3.0: - resolution: {integrity: sha512-Kv2JYYiCzt16Kt5QwAc9BFG89xfPNBx+oQL4GQXD9nLqPkZBiNaqaCWtwnbk/q7UVsTYevvM1b0UF8zmEI4pCg==} - - napi-postinstall@0.3.4: - resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - nitropack@2.13.4: - resolution: {integrity: sha512-tX7bT6zxNeMwkc6hxHiZeUoTOjVrcjoh1Z3cmxOlodIqjl4HISgqfGOmkWSayky3Nv9Z5+KQH52F8nmXJY5AAA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - xml2js: ^0.6.2 - peerDependenciesMeta: - xml2js: - optional: true - - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-forge@1.4.0: - resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} - engines: {node: '>= 6.13.0'} - - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true - - node-mock-http@1.0.4: - resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} - - node-releases@2.0.51: - resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} - engines: {node: '>=18'} - - nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} - hasBin: true - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - nostics@1.2.0: - resolution: {integrity: sha512-FGqEfhQjrvo1lL8KFifdTQiNwwQHJxC1jtYE1Rc54qF/jxONUNL+kC9gS1krX8Q65PgrQ5fCqH/I4NhWBvdSqg==} - - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - npm-run-path@6.0.0: - resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} - engines: {node: '>=18'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - nuxt@4.5.2: - resolution: {integrity: sha512-tR3fcqeHlHmmkLMpIg3V7Y+1ltr302lW8djMw/iy+myfo7QSSz+BVJDuQhg5j73b9oteSyBfOKTDYTgvMtj6TA==} - engines: {node: ^22.19.0 || ^24.11.0 || >=26.0.0} - hasBin: true - peerDependencies: - '@parcel/watcher': ^2.1.0 - '@types/node': '>=18.12.0' - rolldown: ~1.2.1 - peerDependenciesMeta: - '@parcel/watcher': - optional: true - '@types/node': - optional: true - - nypm@0.6.9: - resolution: {integrity: sha512-zxlE2yvSWZWmHcNdT3+5zV2lrCogeE9YOklHrR3dFjqutq5wO7GFDYLFDRXLsYnJzwvy/im9fYoxePvS0VTW0w==} - engines: {node: '>=18'} - hasBin: true - - object-deep-merge@2.0.1: - resolution: {integrity: sha512-aKttDKcU3pyZqKcCkDhsMn70WmZFG2JGDQLP9EcLyTSIFQRCPWLAmBZRLJnrVUrhPG1jETEEbfdgbNtJf1LyMg==} - - object-identity@0.2.3: - resolution: {integrity: sha512-2J8Joz2Tf7aaylhqFvIUJHNgpuGR38Hh75Voq9GzTbStBxJUaOtN0K1aOd3cV5qp+ij1pMqRbPrGCGMOyX303w==} - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - - ofetch@1.5.1: - resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} - - ofetch@2.0.0-alpha.3: - resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==} - - ohash@2.0.12: - resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==} - - on-change@6.0.2: - resolution: {integrity: sha512-08+12qcOVEA0fS9g/VxKS27HaT94nRutUT77J2dr8zv/unzXopvhBuF8tNLWsoLQ5IgrQ6eptGeGqUYat82U1w==} - engines: {node: '>=20'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - - open@11.0.0: - resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} - engines: {node: '>=20'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - orderedmap@2.1.1: - resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} - - oxc-parser@0.140.0: - resolution: {integrity: sha512-h6QFWd6lBMfjESqgQ27GjzrSDb0qbznp7VDQqp2zvgsrWut4vcchyMIzOVXvGQ2GMZgKw9RWrFNWv9WqGL0p7Q==} - engines: {node: ^20.19.0 || >=22.12.0} - - oxc-walker@1.1.1: - resolution: {integrity: sha512-Hwd7dq28zu/Er99+bpWp16CGwFrhyalJh0W3JOB7XpPvgWo3MqMi2ksWGKuzzA9zt50mJ2pIUwR5lpAdZ9ACNQ==} - peerDependencies: - '@oxc-project/types': '>=0.98.0' - oxc-parser: '>=0.98.0' - rolldown: '>=1.0.0' - peerDependenciesMeta: - '@oxc-project/types': - optional: true - oxc-parser: - optional: true - rolldown: - optional: true - - p-event@6.0.1: - resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} - engines: {node: '>=16.17'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-timeout@6.1.4: - resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} - engines: {node: '>=14.16'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - package-manager-detector@1.8.0: - resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} - - parse-imports-exports@0.2.4: - resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} - - parse-statements@1.0.11: - resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - perfect-debounce@2.1.0: - resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} - - picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} - engines: {node: '>=12'} - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - pkg-types@2.3.1: - resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} - - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - postcss-calc@10.1.1: - resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} - engines: {node: ^18.12 || ^20.9 || >=22.0} - peerDependencies: - postcss: ^8.4.38 - - postcss-colormin@8.0.1: - resolution: {integrity: sha512-qBY4ABQ6d8/mk5RRZHwMllrZMxeMey3azVY2dZUEk+RgiUC4ARdPR3/AITzNqqKTbvW/3y/MJKinDrzwqn8RDQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-convert-values@8.0.1: - resolution: {integrity: sha512-IdOSIX3BzfMvCc1TAHIha2gfy17xnb5vfML8e2BIKARnFOghksESfaSAB/3CXgyLfMozZAbTRPVQF5dbuKOidw==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-discard-comments@8.0.1: - resolution: {integrity: sha512-FDvzm3tXlEsQBO2XQgnta5ugsAqwBrgWH+j5QgXpegEIDYA0VPnZg2aP7LtmWtC49POskeIhXesFiU/k3NyFHA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-discard-duplicates@8.0.1: - resolution: {integrity: sha512-stTDXkI8YkCUfADurQhp03oq5ynsgSx6Qrw5B1swds6oTHtAeOZ9I0SHGK8cY/VpWUsIYFDWMs3IWf9jIEfFvA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-discard-empty@8.0.1: - resolution: {integrity: sha512-Zv4fM1Yfhk71tbt6gfiptbL6jDHi+7apSnaMeaO9n1uET+1embrXQw5m93Zp5x28UyQSuv+AVkFY193jdwZ33w==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-discard-overridden@8.0.1: - resolution: {integrity: sha512-ykt4fvrC7yYGzbxKyqBVjDCbsjF/11JgWK8enrdkobRyqqEtb/uDUCbKOGdvrK8X7BrShW8Lv5cCRNbdkNHGkQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-merge-longhand@8.0.1: - resolution: {integrity: sha512-huTfSYgQ13O81SFvAuOi7GWnO48vvybjj3xF+X3qUoPjzvvaLpJH5DcUqqXcwOEulZUcvaV4s0V9WtWs+IAQPA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-merge-rules@8.0.1: - resolution: {integrity: sha512-o3rk4UpnPNg469tklYwbR/NtvKc/f/wJiVDTnNQ/EFPw/LeiPOHUCvV1GIBQIZHGrBAYdPjToK6a+ojYprsrxQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-minify-font-values@8.0.1: - resolution: {integrity: sha512-L8Nzs/PRlBSPrLdY/7rAiU5ZN5800+2J/4LRbfyG8SJnPljmgMaXVmQiCklvRS+yObfVRNtvmk/Ean/eoYcSeg==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-minify-gradients@8.0.1: - resolution: {integrity: sha512-qf+4s/hZMqTwpWN2teqf6+1yvR/SZK5HgHqXYuACeJXV7ABe7AXtBEomgxagUzcN4bSnmqBh5vnIml0dYqykYg==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-minify-params@8.0.1: - resolution: {integrity: sha512-L0h3H59deFfFg0wQN1NVaS/8E/LfGvaMuZKGO7siwlG995zo3OshtQyRkqKdVqcBwAORBvZ1nDZrKPLRapYkQw==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-minify-selectors@8.0.2: - resolution: {integrity: sha512-3icdxc/zght5UAizdwqZBDE2KOWHf1jMQCxET6iLACeNlRxfTPyXS0/COpGk8CQ2cECyaEKTRUd/i/k8Gxmz4g==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-charset@8.0.1: - resolution: {integrity: sha512-xzqr36F8UeIZOvOHsf3aul+RVJCADvSwuwpMLgizqKjisHZpBfztgW0XFLBfJvz9pJgaStaOXAtGb0zLqT6B0w==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-display-values@8.0.1: - resolution: {integrity: sha512-ZDWOijOK1FFMlpgiQCUO9fCNKd7HJ9L7z9HWEq4iyubnUFWzdTSwm/LcrMbNW6iZ1oAtqeLYA0WA3xHszOI08g==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-positions@8.0.1: - resolution: {integrity: sha512-uuivan2poSqbE48ST4do20dGaFUeXey9/H8rhHzoyVHB2I6BmkoVLZ/C9+BRjUlpaAFYVOoDY7epkiidzaYbvA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-repeat-style@8.0.1: - resolution: {integrity: sha512-q2hq5fmKxk29K6DjKA3nZ17Q2dtjhLYFNmFweKALmooUqx6UWAHF1bBoWTu/EqlJ88josb82A/J0Atj9LJUmpQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-string@8.0.1: - resolution: {integrity: sha512-+Wf+kQJhm1WgSGEAuUaswE9rdpR9QbrKRVemcVHs6rhOoOTVIdAbgaicftfYA6vLM346P8onRzkEVbFN29ktKQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-timing-functions@8.0.1: - resolution: {integrity: sha512-W8/tvwRlm3T+yjGkg0IRTF4bvHj0vILYr/LOogCrJKHz2ey2HFRwfsAA8Bk9N4BGR7z7WmmDu/KzzwhJ6FoGPQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-unicode@8.0.1: - resolution: {integrity: sha512-Ad0YHNRBp4WHEOYUM/4wL/8MoL2fimEF8se/0q+Rt/owMzYpbxsypC1P8fN/oluwoRmRKdNVX7X2oycEobPWcQ==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-url@8.0.1: - resolution: {integrity: sha512-tkYcip6pCDY806xuxpJYqMW2M3/623jzGFJmz3m5Us47q8P28+gbRZxaea3Rr/CmwwLUiVlh+BTGYwQ6gvaP8A==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-normalize-whitespace@8.0.1: - resolution: {integrity: sha512-XzORadNfSrKWDZZpgAEHPKINKx8r9r9RIfE9c70g/HThdpbmPHhDYCodHSVESDxmKeySAYw1p4liuBCf7j6LyA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-ordered-values@8.0.1: - resolution: {integrity: sha512-OLXq5lR1yk3KWQ1FPK6aWjFFdktHE9f9kb8cnt4LmIw7w30DnzgD9+sOVYJc5HenkWCX8i1MJhhFwmqc/GYqLg==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-reduce-initial@8.0.1: - resolution: {integrity: sha512-+aQsR6+61KRoIfcFNLP3v9RM7+0iYOTtPnjl1wr6JqMW1zx6S+t2ktHRefXwacFdHIDj5+ETG0KY7K3+SGQ4Nw==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-reduce-transforms@8.0.1: - resolution: {integrity: sha512-x71slHVykiFi5RuKEXM0wgYpY2PngC78x6R8TnZhHF3lhqt+u/w3MGwYLX+2t5O87ssRiMfEAhQH+3J4QwVzCw==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-selector-parser@7.1.4: - resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} - engines: {node: '>=4'} - - postcss-svgo@8.0.1: - resolution: {integrity: sha512-HpnvWii7W0/FPrsejJa6ZTi0kNtTJP/Iba7CUMPX0xPV6QpnndOp+SDP74tFtgjA2cYKYNWJPOlmLXMsvi/9yA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-unique-selectors@8.0.1: - resolution: {integrity: sha512-+xvKI5+/Cl8yYQwxDV39Uhuc4WV951xngFvPPjiPj2NIbIfm6vbbRTXblyw0FioLkIoGlw+7qUcY1h2YhaZYgw==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.5.25: - resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} - engines: {node: ^10 || ^12 || >=14} - - powershell-utils@0.1.0: - resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} - engines: {node: '>=20'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - pretty-bytes@7.1.0: - resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==} - engines: {node: '>=20'} - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - - proper-lockfile@4.1.2: - resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} - - prosemirror-changeset@2.4.1: - resolution: {integrity: sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==} - - prosemirror-commands@1.7.1: - resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} - - prosemirror-dropcursor@1.8.2: - resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} - - prosemirror-gapcursor@1.4.1: - resolution: {integrity: sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==} - - prosemirror-history@1.5.0: - resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} - - prosemirror-inputrules@1.5.1: - resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} - - prosemirror-keymap@1.2.3: - resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} - - prosemirror-model@1.25.7: - resolution: {integrity: sha512-A79aN8QEFUwI6cax8Yq4Rpcx1TJZ3Kagn+ii7qLo4/V8H3mMiHrhFyhTyHHvpSnOgMPpWiDGSwM3etwrxE50ug==} - - prosemirror-schema-list@1.5.1: - resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} - - prosemirror-state@1.4.4: - resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} - - prosemirror-tables@1.8.5: - resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} - - prosemirror-transform@1.12.0: - resolution: {integrity: sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==} - - prosemirror-view@1.41.8: - resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - quote-js-string@0.1.0: - resolution: {integrity: sha512-Y3NoRtprEEZQD8RfxMCfS0ZTqc4e+i18OrXEXAvpM6TfC/3y+0L5rNbZiSnbBBEkDfFzbpd8o+cE8q3/anjMGA==} - engines: {node: '>=22'} - - radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - rc9@3.0.1: - resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - readdir-glob@1.1.3: - resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} - - readdirp@5.0.0: - resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} - engines: {node: '>= 20.19.0'} - - redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} - - redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} - - refa@0.12.1: - resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - regexp-ast-analysis@0.7.1: - resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - - regjsparser@0.13.2: - resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} - hasBin: true - - reka-ui@2.10.3: - resolution: {integrity: sha512-nJGZbwcha8AcP2wbnjodfzsciTKBqp1mIzepC9Pi2xDI/YK3++ej3vpJOSPyxqrkq1Oorj4K+BdJkbVCV6x6ag==} - peerDependencies: - vue: '>= 3.4.0' - - reserved-identifiers@1.2.0: - resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} - engines: {node: '>=18'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} - hasBin: true - - retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rolldown-string@0.3.1: - resolution: {integrity: sha512-dv8GOXkYqUQdI0rsXB8hmzO95pKWSuX2eg5/JSJa9czfEVIFuKNR7ZJDfat8LlmD35RAhWY+evS7/wXXqFDfSg==} - engines: {node: '>=20.19.0'} - peerDependencies: - rolldown: '*' - peerDependenciesMeta: - rolldown: - optional: true - - rolldown@1.2.1: - resolution: {integrity: sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rollup-plugin-visualizer@7.0.1: - resolution: {integrity: sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==} - engines: {node: '>=22'} - hasBin: true - peerDependencies: - rolldown: 1.x || ^1.0.0-beta || ^1.0.0-rc - rollup: 2.x || 3.x || 4.x - peerDependenciesMeta: - rolldown: - optional: true - rollup: - optional: true - - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rope-sequence@1.3.4: - resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} - - rou3@0.9.1: - resolution: {integrity: sha512-z/sSmzvtwMDDnxsPVhfWMuG6F6mbmhFDXoVqLmMfbpDD9qfV3GDmSQpf0+W296/ZDIpW2wcMmBfpVFzcnOi/nA==} - - run-applescript@7.1.0: - resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} - engines: {node: '>=18'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} - engines: {node: '>=11.0.0'} - - scslre@0.3.0: - resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} - engines: {node: ^14.0.0 || >=16.0.0} - - scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} - engines: {node: '>=10'} - hasBin: true - - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - - serialize-javascript@7.0.5: - resolution: {integrity: sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==} - engines: {node: '>=20.0.0'} - - seroval@1.6.2: - resolution: {integrity: sha512-mPT+SD2TrlB6wvte1KkYOYUkubaTbd6pZ/6Kk3C9nxzrHmCZyhxOO7XGAeL7f+yLKZglzGtM9odUVvg/EhO+vQ==} - engines: {node: '>=10'} - - serve-placeholder@2.0.2: - resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} - - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - shell-quote@1.10.0: - resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} - engines: {node: '>= 0.4'} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - simple-git@3.36.0: - resolution: {integrity: sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==} - - sirv@3.0.2: - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} - engines: {node: '>=18'} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - - smob@1.6.2: - resolution: {integrity: sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==} - engines: {node: '>=20.0.0'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - - spdx-exceptions@2.5.0: - resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} - - spdx-expression-parse@5.0.0: - resolution: {integrity: sha512-vngmw3Rgn+o2arXNbnZaj5UtOEBuWBfvaI+Wc8GFfykIhA5/vdK9/Sp/XkLv63dykz2rxKDvKEHupF5P0FORcQ==} - - spdx-license-ids@3.0.23: - resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} - - srvx@0.11.22: - resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==} - engines: {node: '>=20.16.0'} - hasBin: true - - srvx@0.12.4: - resolution: {integrity: sha512-RixzFlMn3dvzDTpKIAXhXrqL4cy6vScNCP0VVwgVbUBU94o+DiXLsFnAZetbyKAEnK6Ox3hzHXWGsyv/Iibv7g==} - engines: {node: '>=20.16.0'} - hasBin: true - - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} - - standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - std-env@4.2.0: - resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} - - streamx@2.25.0: - resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - - strip-indent@4.1.1: - resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} - engines: {node: '>=12'} - - strip-literal@4.0.0: - resolution: {integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==} - - structured-clone-es@2.0.1: - resolution: {integrity: sha512-10ZL5r77LhknxlP1FBiCW+VdnuWOEFLdSS2SKtjyEV+L4qP1hUEIMIZW94LC3jKxRmT/Dj7KkD1mqh/IY6lhKQ==} - - stylehacks@8.0.1: - resolution: {integrity: sha512-Gv095oTD0N+BdJALNFDsxZpETHZLTxbOl5RyIO7y6VAE6sR3z0MnV3Nix7N0IATNldNTrkvSASp2KR1Yt526HA==} - engines: {node: ^22.11.0 || ^24.11.0 || >=26.0} - peerDependencies: - postcss: ^8.5.15 - - super-regex@1.1.0: - resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} - engines: {node: '>=18'} - - supports-color@10.2.2: - resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} - engines: {node: '>=18'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - svgo@4.0.1: - resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} - engines: {node: '>=16'} - hasBin: true - - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - - tailwind-merge@3.6.0: - resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} - - tailwind-variants@3.2.2: - resolution: {integrity: sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==} - engines: {node: '>=16.x', pnpm: '>=7.x'} - peerDependencies: - tailwind-merge: '>=3.0.0' - tailwindcss: '*' - peerDependenciesMeta: - tailwind-merge: - optional: true - - tailwindcss@4.3.3: - resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} - - tapable@2.3.3: - resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} - engines: {node: '>=6'} - - tar-stream@3.2.0: - resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} - - tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} - engines: {node: '>=18'} - - teex@1.0.1: - resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - - terser@5.47.1: - resolution: {integrity: sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==} - engines: {node: '>=10'} - hasBin: true - - text-decoder@1.2.7: - resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} - - time-span@5.1.0: - resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} - engines: {node: '>=12'} - - tiny-inflate@1.0.3: - resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} - - tiny-invariant@1.3.3: - resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - - tinyclip@0.1.15: - resolution: {integrity: sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==} - engines: {node: ^16.14.0 || >= 17.3.0} - - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} - - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - to-valid-identifier@1.0.0: - resolution: {integrity: sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==} - engines: {node: '>=20'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - ts-api-utils@2.5.0: - resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - type-fest@5.6.0: - resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} - engines: {node: '>=20'} - - type-level-regexp@0.1.17: - resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} - - typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} - - ultrahtml@1.7.0: - resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==} - - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - - unctx@2.5.0: - resolution: {integrity: sha512-p+Rz9x0R7X+CYDkT+Xg8/GhpcShTlU8n+cf9OtOEf7zEQsNcCZO1dPKNRDqvUTaq+P32PMMkxWHwfrxkqfqAYg==} - - unctx@3.0.0: - resolution: {integrity: sha512-DoXdZVeyi2jyEsn86i8MO5RTItm1kffUkH9/+DQORn3Q688AMOy2551CIl6AdGL2UpwD675wtbNOl75wIQN/uA==} - peerDependencies: - magic-string: '>=0.30.21' - oxc-parser: '>=0.140.0' - rolldown: ^1.1.5 - unplugin: ^3.3.0 - peerDependenciesMeta: - magic-string: - optional: true - oxc-parser: - optional: true - rolldown: - optional: true - unplugin: - optional: true - - undici@8.10.0: - resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} - engines: {node: '>=22.19.0'} - - unenv@2.0.0-rc.24: - resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} - - unhead@3.4.0: - resolution: {integrity: sha512-OlgpyYjY+NkFyQCaMihg2uTFbbvyr5lZr6TokS68VdFTXJ5jo4JwFtGR8PwKy/wRpjbQYgKF7ZYO+pbRgxtSmw==} - peerDependencies: - vite: '>=6.4.2' - peerDependenciesMeta: - vite: - optional: true - - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - - unicorn-magic@0.4.0: - resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} - engines: {node: '>=20'} - - unifont@0.7.4: - resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} - - unimport@6.4.0: - resolution: {integrity: sha512-JJOOuNMFq8b4ZPBKwQUxEcba4MplskDzYI1Lvrf8rJfWphZTWvPNXWa493qsPngHUmub89w6C7j+SeLWTE/UIQ==} - engines: {node: '>=18.12.0'} - peerDependencies: - oxc-parser: '*' - rolldown: ^1.0.0 - peerDependenciesMeta: - oxc-parser: - optional: true - rolldown: - optional: true - - unplugin-auto-import@21.1.0: - resolution: {integrity: sha512-EzrSqWIBulEqCuP7idADXH+tVKYrbwKlR5+r/lOWik0o+Ksny1kitmtryHGNSv7puzzORlcIwT/x2JStiszlHA==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@nuxt/kit': ^4.0.0 - '@vueuse/core': '*' - peerDependenciesMeta: - '@nuxt/kit': - optional: true - '@vueuse/core': - optional: true - - unplugin-utils@0.3.2: - resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==} - engines: {node: '>=20.19.0'} - - unplugin-vue-components@32.1.0: - resolution: {integrity: sha512-YiUkSxuRjab18XFOrX5VsIxXzccrfmHVGsGeJgSgklb829DQmCy9E4vvDUE4tuvZZdxyFJZX0Oc4TPnnxiiMyg==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@nuxt/kit': ^3.2.2 || ^4.0.0 - vue: ^3.0.0 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - - unplugin@2.3.11: - resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} - engines: {node: '>=18.12.0'} - - unplugin@3.3.0: - resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@farmfe/core': '*' - '@rspack/core': '*' - bun-types-no-globals: '*' - esbuild: '*' - rolldown: '*' - rollup: '*' - unloader: '*' - vite: '*' - webpack: '*' - peerDependenciesMeta: - '@farmfe/core': - optional: true - '@rspack/core': - optional: true - bun-types-no-globals: - optional: true - esbuild: - optional: true - rolldown: - optional: true - rollup: - optional: true - unloader: - optional: true - vite: - optional: true - webpack: - optional: true - - unrouting@0.2.2: - resolution: {integrity: sha512-EoCab68s1o9AWFq9fjKsMEsmjKrPO11SAsvopikks2eEm/KLXgZMCof4cgpVgdy0Vz71OFBJw6DoDqu1oOSFGw==} - - unrs-resolver@1.12.2: - resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} - - unstorage@1.17.5: - resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} - peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6 || ^7 || ^8 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/functions': ^2.2.12 || ^3.0.0 - '@vercel/kv': ^1 || ^2 || ^3 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 - peerDependenciesMeta: - '@azure/app-configuration': - optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/functions': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: - optional: true - - untun@0.1.3: - resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} - hasBin: true - - untyped@2.0.0: - resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} - hasBin: true - - unwasm@0.5.3: - resolution: {integrity: sha512-keBgTSfp3r6+s9ZcSma+0chwxQdmLbB5+dAD9vjtB21UTMYuKAxHXCU1K2CbCtnP09EaWeRvACnXk0EJtUx+hw==} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uqr@0.1.3: - resolution: {integrity: sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - valibot@1.4.2: - resolution: {integrity: sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg==} - peerDependencies: - typescript: '>=5' - peerDependenciesMeta: - typescript: - optional: true - - vaul-vue@0.4.1: - resolution: {integrity: sha512-A6jOWOZX5yvyo1qMn7IveoWN91mJI5L3BUKsIwkg6qrTGgHs1Sb1JF/vyLJgnbN1rH4OOOxFbtqL9A46bOyGUQ==} - peerDependencies: - reka-ui: ^2.0.0 - vue: ^3.3.0 - - verkit@0.3.2: - resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==} - engines: {node: '>=18.12.0'} - - vite-dev-rpc@2.0.0: - resolution: {integrity: sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==} - peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 || ^8.0.0 - - vite-hot-client@2.2.0: - resolution: {integrity: sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==} - peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0 - - vite-node@6.0.0: - resolution: {integrity: sha512-oj4PVrT+pDh6GYf5wfUXkcZyekYS8kKPfLPXVl8qe324Ec6l4K2DUKNadRbZ3LQl0qGcDz+PyOo7ZAh00Y+JjQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - vite-plugin-checker@0.14.5: - resolution: {integrity: sha512-c9lQ92eisUO+F7Fd93aelojmiOS+NQpPgQ1XR2LTQHox1/laZf4yAoQj+L3RA9Vgh10e2nFd9b8r2LLyYZsbpA==} - engines: {node: '>=20.19.0'} - peerDependencies: - '@biomejs/biome': '>=2.4.12' - eslint: '>=9.39.4' - meow: ^13.2.0 || ^14.0.0 - optionator: ^0.9.4 - oxlint: '>=1' - stylelint: '>=16.26.1' - typescript: '*' - vite: '>=5.4.21' - vue-tsc: ~2.2.10 || ^3.0.0 - peerDependenciesMeta: - '@biomejs/biome': - optional: true - eslint: - optional: true - meow: - optional: true - optionator: - optional: true - oxlint: - optional: true - stylelint: - optional: true - typescript: - optional: true - vue-tsc: - optional: true - - vite-plugin-inspect@11.4.1: - resolution: {integrity: sha512-ShOFe2PURXGvRS5OrgmOLZOCwDTD7dEBVt0tMpFPKb9AsvqXKCRGM8QgKrUbRbJYFXScHvDPpGRd28rYidC0tA==} - engines: {node: '>=14'} - peerDependencies: - '@nuxt/kit': '*' - vite: ^6.0.0 || ^7.0.0-0 || ^8.0.0-0 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - - vite-plugin-vue-tracer@1.4.0: - resolution: {integrity: sha512-0tQCjCqZWVSK6UeRW9S4ABbf47lKQ68zvrT2FNvZmiL+alDydCVyH/T3Jlfbdc3T3C2Iuyyl5aVsMbF8IQIoxA==} - peerDependencies: - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 - vue: ^3.5.0 - - vite@8.2.1: - resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.4.0 - esbuild: ^0.27.0 || ^0.28.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 - '@vitejs/devtools': - 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 - - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - - vue-bundle-renderer@2.3.1: - resolution: {integrity: sha512-7F4LNMopUw5RgYWo4zCmVUHCc6aQRC6dCKHUYkM/n+fux4AUGdL1x6m5A515WWyFysRRN7cx3hBzVqoisfRfzw==} - - vue-component-type-helpers@3.3.11: - resolution: {integrity: sha512-LwcxzeliO9fkQcpJG0PoX8X5kmAhKmH9wkpDLxNabwzkQ9Zeib2YVHwFV4pcWmMLfXVfjr/dSV+DaJ3cIPgSNA==} - - vue-demi@0.14.10: - resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} - engines: {node: '>=12'} - hasBin: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - - vue-devtools-stub@0.1.0: - resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} - - vue-eslint-parser@10.4.1: - resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - - vue-router@5.2.0: - resolution: {integrity: sha512-QAC5i0LEb1GLG0LXDQmHu8L7FX12j0KwU/JTKmLQUJMrn04gQdKP6Du+p0QwpHb3iy71vBlqnHQ8WAfOSAWhqw==} - peerDependencies: - '@pinia/colada': '>=0.21.2' - '@vue/compiler-sfc': ^3.5.34 || ^4.0.0 - pinia: ^3.0.4 || ^4.0.2 - vite: ^7.3.0 || ^8.0.0 - vue: ^3.5.34 || ^4.0.0 - peerDependenciesMeta: - '@pinia/colada': - optional: true - '@vue/compiler-sfc': - optional: true - pinia: - optional: true - vite: - optional: true - - vue-tsc@3.3.11: - resolution: {integrity: sha512-gOb0B9rtU2+f1dszwPqSH5kAieIF9ReeLhD3kSRNHv5WZZUQz/JdVXW0RTdqhNTMlQkqKzrTTviqKr/4FYZraQ==} - hasBin: true - peerDependencies: - typescript: '>=5.0.0' - - vue@3.5.40: - resolution: {integrity: sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - - web-worker@1.5.0: - resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - wheel-gestures@2.2.48: - resolution: {integrity: sha512-f+Gy33Oa5Z14XY9679Zze+7VFhbsQfBFXodnU2x589l4kxGM9L5Y8zETTmcMR5pWOPQyRv4Z0lNax6xCO0NSlA==} - engines: {node: '>=18'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - which@6.0.1: - resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - - ws@8.21.3: - resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} - 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 - - wsl-utils@0.3.1: - resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} - engines: {node: '>=20'} - - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - y-protocols@1.0.7: - resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - peerDependencies: - yjs: ^13.0.0 - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - - yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@22.0.0: - resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - yargs@18.0.0: - resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - yjs@13.6.30: - resolution: {integrity: sha512-vv/9h42eCMC81ZHDFswuu/MKzkl/vyq1BhaNGfHyOonwlG4CJbQF4oiBBJPvfdeCt/PlVDWh7Nov9D34YY09uQ==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} - - youch-core@0.3.3: - resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - - youch@4.1.1: - resolution: {integrity: sha512-mxW3qiSnl+GRxXsaUMzv2Mbada1Y8CDltET9UxejDQe6DBYlSekghl5U5K0ReAikcHDi0G1vKZEmmo/NWAGKLA==} - - zigpty@0.2.1: - resolution: {integrity: sha512-MR9JqJx2wf5f4wz8zpx050AlqrmWeIW+1h0SO5iEyhG3HFRjY5luC3szS2ux2EGuPjE5OU9ZAuiCBeMWBTrqZw==} - - zip-stream@6.0.1: - resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} - engines: {node: '>= 14'} - - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} - -snapshots: - - '@alloc/quick-lru@5.2.0': {} - - '@antfu/install-pkg@1.1.0': - dependencies: - package-manager-detector: 1.8.0 - tinyexec: 1.2.4 - - '@antfu/install-pkg@2.0.1': - dependencies: - package-manager-detector: 1.8.0 - tinyexec: 1.2.4 - - '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': - dependencies: - '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 - - '@babel/code-frame@7.29.7': - dependencies: - '@babel/helper-validator-identifier': 7.29.7 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.29.3': {} - - '@babel/core@7.29.0(supports-color@10.2.2)': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.7 - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) - '@babel/types': 7.29.7 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@10.2.2) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.29.7': - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/generator@8.0.0': - dependencies: - '@babel/parser': 8.0.4 - '@babel/types': 8.0.4 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@types/jsesc': 2.5.1 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@7.29.7': - dependencies: - '@babel/types': 7.29.7 - - '@babel/helper-compilation-targets@7.28.6': - dependencies: - '@babel/compat-data': 7.29.3 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.7 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2)': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-member-expression-to-functions': 7.29.7(supports-color@10.2.2) - '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2) - '@babel/helper-skip-transparent-expression-wrappers': 7.29.7(supports-color@10.2.2) - '@babel/traverse': 7.29.7(supports-color@10.2.2) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-globals@7.29.7': {} - - '@babel/helper-member-expression-to-functions@7.29.7(supports-color@10.2.2)': - dependencies: - '@babel/traverse': 7.29.7(supports-color@10.2.2) - '@babel/types': 7.29.7 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-imports@7.28.6(supports-color@10.2.2)': - dependencies: - '@babel/traverse': 7.29.7(supports-color@10.2.2) - '@babel/types': 7.29.7 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2)': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-module-imports': 7.28.6(supports-color@10.2.2) - '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - '@babel/helper-optimise-call-expression@7.29.7': - dependencies: - '@babel/types': 7.29.7 - - '@babel/helper-plugin-utils@7.29.7': {} - - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2)': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-member-expression-to-functions': 7.29.7(supports-color@10.2.2) - '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.29.7(supports-color@10.2.2)': - dependencies: - '@babel/traverse': 7.29.7(supports-color@10.2.2) - '@babel/types': 7.29.7 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.29.7': {} - - '@babel/helper-string-parser@8.0.0': {} - - '@babel/helper-validator-identifier@7.29.7': {} - - '@babel/helper-validator-identifier@8.0.4': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.29.2': - dependencies: - '@babel/template': 7.29.7 - '@babel/types': 7.29.7 - - '@babel/parser@7.29.7': - dependencies: - '@babel/types': 7.29.7 - - '@babel/parser@8.0.4': - dependencies: - '@babel/types': 8.0.4 - - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2))': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-plugin-utils': 7.29.7 - - '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2))': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-plugin-utils': 7.29.7 - - '@babel/plugin-transform-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2)': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.29.7(supports-color@10.2.2) - '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.0(supports-color@10.2.2)) - transitivePeerDependencies: - - supports-color - - '@babel/template@7.29.7': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - - '@babel/traverse@7.29.7(supports-color@10.2.2)': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/helper-globals': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/template': 7.29.7 - '@babel/types': 7.29.7 - debug: 4.4.3(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - '@babel/types@7.29.7': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - - '@babel/types@8.0.4': - dependencies: - '@babel/helper-string-parser': 8.0.0 - '@babel/helper-validator-identifier': 8.0.4 - - '@bomb.sh/tab@0.0.19(cac@7.0.0)(citty@0.2.2)': - optionalDependencies: - cac: 7.0.0 - citty: 0.2.2 - - '@capsizecss/unpack@4.0.0': - dependencies: - fontkitten: 1.0.3 - - '@clack/core@1.4.3': - dependencies: - fast-wrap-ansi: 0.2.0 - sisteransi: 1.0.5 - - '@clack/prompts@1.7.0': - dependencies: - '@clack/core': 1.4.3 - fast-string-width: 3.0.2 - fast-wrap-ansi: 0.2.0 - sisteransi: 1.0.5 - - '@cloudflare/kv-asset-handler@0.4.2': {} - - '@colordx/core@5.4.3': {} - - '@devframes/hub@0.7.15(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': - dependencies: - birpc: 4.0.0 - destr: 2.0.5 - devframe: 0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) - nostics: 1.2.0 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - tinyexec: 1.2.4 - zigpty: 0.2.1 - optional: true - - '@devframes/json-render@0.7.15(@devframes/hub@0.7.15(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': - dependencies: - '@json-render/core': 0.19.0(zod@4.4.3) - devframe: 0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) - nostics: 1.2.0 - zod: 4.4.3 - optionalDependencies: - '@devframes/hub': 0.7.15(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) - optional: true - - '@dxup/nuxt@0.5.6(esbuild@0.28.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - '@dxup/unimport': 0.1.2 - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@vue/compiler-dom': 3.5.40 - chokidar: 5.0.0 - knitwork: 1.3.0 - magic-string: 1.2.2 - pathe: 2.0.3 - tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - magicast - - oxc-parser - - rolldown - - rollup - - unloader - - vite - - webpack - - '@dxup/unimport@0.1.2': {} - - '@emnapi/core@1.10.0': - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - optional: true - - '@emnapi/core@1.11.2': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - - '@emnapi/core@2.0.0-alpha.3': - dependencies: - '@emnapi/wasi-threads': 2.0.1 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.10.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.11.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@2.0.0-alpha.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@2.0.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@es-joy/jsdoccomment@0.91.0': - dependencies: - '@types/estree': 1.0.9 - '@typescript-eslint/types': 8.66.0 - comment-parser: 1.4.7 - esquery: 1.7.0 - jsdoc-type-pratt-parser: 8.0.0 - - '@es-joy/resolve.exports@1.2.0': {} - - '@esbuild/aix-ppc64@0.27.7': - optional: true - - '@esbuild/aix-ppc64@0.28.0': - optional: true - - '@esbuild/android-arm64@0.27.7': - optional: true - - '@esbuild/android-arm64@0.28.0': - optional: true - - '@esbuild/android-arm@0.27.7': - optional: true - - '@esbuild/android-arm@0.28.0': - optional: true - - '@esbuild/android-x64@0.27.7': - optional: true - - '@esbuild/android-x64@0.28.0': - optional: true - - '@esbuild/darwin-arm64@0.27.7': - optional: true - - '@esbuild/darwin-arm64@0.28.0': - optional: true - - '@esbuild/darwin-x64@0.27.7': - optional: true - - '@esbuild/darwin-x64@0.28.0': - optional: true - - '@esbuild/freebsd-arm64@0.27.7': - optional: true - - '@esbuild/freebsd-arm64@0.28.0': - optional: true - - '@esbuild/freebsd-x64@0.27.7': - optional: true - - '@esbuild/freebsd-x64@0.28.0': - optional: true - - '@esbuild/linux-arm64@0.27.7': - optional: true - - '@esbuild/linux-arm64@0.28.0': - optional: true - - '@esbuild/linux-arm@0.27.7': - optional: true - - '@esbuild/linux-arm@0.28.0': - optional: true - - '@esbuild/linux-ia32@0.27.7': - optional: true - - '@esbuild/linux-ia32@0.28.0': - optional: true - - '@esbuild/linux-loong64@0.27.7': - optional: true - - '@esbuild/linux-loong64@0.28.0': - optional: true - - '@esbuild/linux-mips64el@0.27.7': - optional: true - - '@esbuild/linux-mips64el@0.28.0': - optional: true - - '@esbuild/linux-ppc64@0.27.7': - optional: true - - '@esbuild/linux-ppc64@0.28.0': - optional: true - - '@esbuild/linux-riscv64@0.27.7': - optional: true - - '@esbuild/linux-riscv64@0.28.0': - optional: true - - '@esbuild/linux-s390x@0.27.7': - optional: true - - '@esbuild/linux-s390x@0.28.0': - optional: true - - '@esbuild/linux-x64@0.27.7': - optional: true - - '@esbuild/linux-x64@0.28.0': - optional: true - - '@esbuild/netbsd-arm64@0.27.7': - optional: true - - '@esbuild/netbsd-arm64@0.28.0': - optional: true - - '@esbuild/netbsd-x64@0.27.7': - optional: true - - '@esbuild/netbsd-x64@0.28.0': - optional: true - - '@esbuild/openbsd-arm64@0.27.7': - optional: true - - '@esbuild/openbsd-arm64@0.28.0': - optional: true - - '@esbuild/openbsd-x64@0.27.7': - optional: true - - '@esbuild/openbsd-x64@0.28.0': - optional: true - - '@esbuild/openharmony-arm64@0.27.7': - optional: true - - '@esbuild/openharmony-arm64@0.28.0': - optional: true - - '@esbuild/sunos-x64@0.27.7': - optional: true - - '@esbuild/sunos-x64@0.28.0': - optional: true - - '@esbuild/win32-arm64@0.27.7': - optional: true - - '@esbuild/win32-arm64@0.28.0': - optional: true - - '@esbuild/win32-ia32@0.27.7': - optional: true - - '@esbuild/win32-ia32@0.28.0': - optional: true - - '@esbuild/win32-x64@0.27.7': - optional: true - - '@esbuild/win32-x64@0.28.0': - optional: true - - '@eslint-community/eslint-utils@4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))': - dependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/compat@2.1.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))': - dependencies: - '@eslint/core': 1.2.1 - optionalDependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - - '@eslint/config-array@0.23.5(supports-color@10.2.2)': - dependencies: - '@eslint/object-schema': 3.0.5 - debug: 4.4.3(supports-color@10.2.2) - minimatch: 10.2.5 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.5.5': - dependencies: - '@eslint/core': 1.2.1 - - '@eslint/config-helpers@0.7.0': - dependencies: - '@eslint/core': 1.2.1 - - '@eslint/config-inspector@3.2.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(srvx@0.11.22)': - dependencies: - ansis: 4.3.1 - cac: 7.0.0 - chokidar: 5.0.0 - devframe: 0.8.2(cac@7.0.0)(srvx@0.11.22) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - jiti: 2.7.0 - tinyglobby: 0.2.17 - transitivePeerDependencies: - - '@modelcontextprotocol/client' - - '@modelcontextprotocol/server' - - srvx - - '@eslint/core@1.2.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/css-tree@4.0.5': - dependencies: - mdn-data: 2.29.0 - source-map-js: 1.2.1 - - '@eslint/js@10.0.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))': - optionalDependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - - '@eslint/object-schema@3.0.5': {} - - '@eslint/plugin-kit@0.7.2': - dependencies: - '@eslint/core': 1.2.1 - levn: 0.4.1 - - '@floating-ui/core@1.8.0': - dependencies: - '@floating-ui/utils': 0.2.12 - - '@floating-ui/dom@1.8.0': - dependencies: - '@floating-ui/core': 1.8.0 - '@floating-ui/utils': 0.2.12 - - '@floating-ui/utils@0.2.12': {} - - '@floating-ui/vue@1.1.11(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@floating-ui/dom': 1.8.0 - '@floating-ui/utils': 0.2.12 - vue-demi: 0.14.10(vue@3.5.40(typescript@6.0.3)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@humanfs/core@0.19.2': - dependencies: - '@humanfs/types': 0.15.0 - - '@humanfs/node@0.16.8': - dependencies: - '@humanfs/core': 0.19.2 - '@humanfs/types': 0.15.0 - '@humanwhocodes/retry': 0.4.3 - - '@humanfs/types@0.15.0': {} - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@iconify-json/lucide@1.2.127': - dependencies: - '@iconify/types': 2.0.0 - - '@iconify-json/simple-icons@1.2.94': - dependencies: - '@iconify/types': 2.0.0 - - '@iconify/collections@1.0.727': - dependencies: - '@iconify/types': 2.0.0 - - '@iconify/types@2.0.0': {} - - '@iconify/utils@3.1.4': - dependencies: - '@antfu/install-pkg': 1.1.0 - '@iconify/types': 2.0.0 - import-meta-resolve: 4.2.0 - - '@iconify/vue@5.0.1(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@iconify/types': 2.0.0 - vue: 3.5.40(typescript@6.0.3) - - '@internationalized/date@3.12.1': - dependencies: - '@swc/helpers': 0.5.21 - - '@internationalized/number@3.6.6': - dependencies: - '@swc/helpers': 0.5.21 - - '@ioredis/commands@1.5.1': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.2.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@isaacs/fs-minipass@4.0.1': - dependencies: - minipass: 7.1.3 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/source-map@0.3.11': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@json-render/core@0.19.0(zod@4.4.3)': - dependencies: - zod: 4.4.3 - optional: true - - '@kwsites/file-exists@1.1.1(supports-color@10.2.2)': - dependencies: - debug: 4.4.3(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - '@kwsites/promise-deferred@1.1.1': {} - - '@mapbox/node-pre-gyp@2.0.3(supports-color@10.2.2)': - dependencies: - consola: 3.4.2 - detect-libc: 2.1.2 - https-proxy-agent: 7.0.6(supports-color@10.2.2) - node-fetch: 2.7.0 - nopt: 8.1.0 - semver: 7.8.5 - tar: 7.5.15 - transitivePeerDependencies: - - encoding - - supports-color - - '@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@napi-rs/wasm-runtime@1.2.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': - dependencies: - '@emnapi/core': 2.0.0-alpha.3 - '@emnapi/runtime': 2.0.0-alpha.3 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@nuxt/cli@3.37.0(@nuxt/schema@4.5.2)(cac@7.0.0)(magicast@0.5.4)(supports-color@10.2.2)': - dependencies: - '@bomb.sh/tab': 0.0.19(cac@7.0.0)(citty@0.2.2) - '@clack/prompts': 1.7.0 - c12: 3.3.4(magicast@0.5.4) - citty: 0.2.2 - confbox: 0.2.4 - consola: 3.4.2 - debug: 4.4.3(supports-color@10.2.2) - defu: 6.1.7 - exsolve: 1.1.1 - fuse.js: 7.5.0 - fzf: 0.5.2 - giget: 3.3.1 - jiti: 2.7.0 - listhen: 1.10.0(srvx@0.11.22) - nypm: 0.6.9 - ofetch: 1.5.1 - ohash: 2.0.12 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.1 - scule: 1.3.0 - semver: 7.8.5 - srvx: 0.11.22 - std-env: 4.2.0 - tinyclip: 0.1.15 - tinyexec: 1.2.4 - ufo: 1.6.4 - youch: 4.1.1 - optionalDependencies: - '@nuxt/schema': 4.5.2 - transitivePeerDependencies: - - cac - - commander - - magicast - - supports-color - - '@nuxt/devalue@2.0.2': {} - - '@nuxt/devtools-kit@3.4.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - execa: 8.0.1 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - magic-string - - magicast - - oxc-parser - - rolldown - - unplugin - - '@nuxt/devtools-wizard@3.4.1': - dependencies: - '@clack/prompts': 1.7.0 - consola: 3.4.2 - diff: 8.0.4 - execa: 8.0.1 - magicast: 0.5.4 - pathe: 2.0.3 - pkg-types: 2.3.1 - semver: 7.8.5 - - '@nuxt/devtools@3.4.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.2.2)(oxc-parser@0.140.0)(rolldown@1.2.1)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@nuxt/devtools-kit': 3.4.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@nuxt/devtools-wizard': 3.4.1 - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@vue/devtools-core': 8.2.1(vue@3.5.40(typescript@6.0.3)) - '@vue/devtools-kit': 8.2.1 - birpc: 4.0.0 - consola: 3.4.2 - destr: 2.0.5 - error-stack-parser-es: 2.0.1 - execa: 8.0.1 - fast-npm-meta: 2.2.0 - get-port-please: 3.2.0 - hookable: 6.1.1 - image-meta: 0.2.2 - is-installed-globally: 1.0.0 - launch-editor: 2.14.1 - local-pkg: 1.2.1 - magicast: 0.5.4 - nypm: 0.6.9 - ohash: 2.0.12 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.1 - semver: 7.8.5 - simple-git: 3.36.0(supports-color@10.2.2) - sirv: 3.0.2 - structured-clone-es: 2.0.1 - tinyglobby: 0.2.17 - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2)) - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vite-plugin-inspect: 11.4.1(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - vite-plugin-vue-tracer: 1.4.0(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - which: 6.0.1 - ws: 8.21.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - idb-keyval - - ioredis - - magic-string - - oxc-parser - - rolldown - - supports-color - - unplugin - - uploadthing - - utf-8-validate - - vue - - '@nuxt/eslint-config@1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.40)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@antfu/install-pkg': 2.0.1 - '@clack/prompts': 1.7.0 - '@eslint/js': 10.0.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@nuxt/eslint-plugin': 1.17.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@stylistic/eslint-plugin': 5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@typescript-eslint/eslint-plugin': 8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/parser': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - eslint-config-flat-gitignore: 2.3.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint-flat-config-utils: 3.2.0 - eslint-merge-processors: 2.0.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint-plugin-import-lite: 0.6.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint-plugin-import-x: 4.17.1(@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) - eslint-plugin-jsdoc: 63.3.3(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) - eslint-plugin-regexp: 3.1.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint-plugin-unicorn: 73.0.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint-plugin-vue: 10.10.0(@stylistic/eslint-plugin@5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)))(@typescript-eslint/parser@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(vue-eslint-parser@10.4.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.40)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - globals: 17.9.0 - local-pkg: 1.2.1 - pathe: 2.0.3 - vue-eslint-parser: 10.4.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) - transitivePeerDependencies: - - '@typescript-eslint/utils' - - '@vue/compiler-sfc' - - eslint-import-resolver-node - - supports-color - - typescript - - '@nuxt/eslint-plugin@1.17.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/utils': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - typescript - - '@nuxt/eslint@1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(srvx@0.11.22)(supports-color@10.2.2)(typescript@6.0.3)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - '@eslint/config-inspector': 3.2.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(srvx@0.11.22) - '@nuxt/devtools-kit': 3.4.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@nuxt/eslint-config': 1.17.0(@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(@vue/compiler-sfc@3.5.40)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@nuxt/eslint-plugin': 1.17.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - chokidar: 5.0.0 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - eslint-flat-config-utils: 3.2.0 - eslint-typegen: 2.3.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - find-up: 8.0.0 - get-port-please: 3.2.0 - mlly: 1.8.2 - pathe: 2.0.3 - unimport: 6.4.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - transitivePeerDependencies: - - '@farmfe/core' - - '@modelcontextprotocol/client' - - '@modelcontextprotocol/server' - - '@rspack/core' - - '@typescript-eslint/utils' - - '@vue/compiler-sfc' - - bun-types-no-globals - - esbuild - - eslint-import-resolver-node - - eslint-plugin-format - - magic-string - - magicast - - oxc-parser - - rolldown - - rollup - - srvx - - supports-color - - typescript - - unloader - - unplugin - - vite - - webpack - - '@nuxt/fonts@0.14.0(db0@0.3.4)(esbuild@0.28.0)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - '@nuxt/devtools-kit': 3.4.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - consola: 3.4.2 - defu: 6.1.7 - fontless: 0.2.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - h3: 1.15.11 - magic-regexp: 0.10.0 - ofetch: 1.5.1 - pathe: 2.0.3 - sirv: 3.0.2 - tinyglobby: 0.2.17 - ufo: 1.6.4 - unifont: 0.7.4 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2)) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@farmfe/core' - - '@netlify/blobs' - - '@planetscale/database' - - '@rspack/core' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bun-types-no-globals - - db0 - - esbuild - - idb-keyval - - ioredis - - magic-string - - magicast - - oxc-parser - - rolldown - - rollup - - unloader - - uploadthing - - vite - - webpack - - '@nuxt/icon@2.5.0(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@iconify/collections': 1.0.727 - '@iconify/types': 2.0.0 - '@iconify/utils': 3.1.4 - '@iconify/vue': 5.0.1(vue@3.5.40(typescript@6.0.3)) - '@nuxt/devtools-kit': 3.4.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - consola: 3.4.2 - local-pkg: 1.2.1 - mlly: 1.8.2 - ohash: 2.0.12 - picomatch: 4.0.5 - std-env: 4.2.0 - tinyglobby: 0.2.17 - ufo: 1.6.4 - transitivePeerDependencies: - - magic-string - - magicast - - oxc-parser - - rolldown - - unplugin - - vite - - vue - - '@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))': - dependencies: - c12: 3.3.4(magicast@0.5.4) - consola: 3.4.2 - defu: 6.1.7 - destr: 2.0.5 - errx: 0.1.2 - exsolve: 1.1.1 - ignore: 7.0.6 - jiti: 2.7.0 - klona: 2.0.6 - mlly: 1.8.2 - nostics: 1.2.0 - ohash: 2.0.12 - pathe: 2.0.3 - pkg-types: 2.3.1 - rc9: 3.0.1 - scule: 1.3.0 - tinyglobby: 0.2.17 - ufo: 1.6.4 - unctx: 3.0.0(magic-string@1.2.2)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - untyped: 2.0.0 - verkit: 0.3.2 - transitivePeerDependencies: - - magic-string - - magicast - - oxc-parser - - rolldown - - unplugin - - '@nuxt/nitro-server@4.5.2(1faf410aca872ebb6f154eab8d23cc95)': - dependencies: - '@nuxt/devalue': 2.0.2 - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@unhead/vue': 3.4.0(@oxc-project/types@0.142.0)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(esbuild@0.28.0)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@vue/shared': 3.5.40 - consola: 3.4.2 - defu: 6.1.7 - destr: 2.0.5 - devalue: 5.9.0 - errx: 0.1.2 - escape-string-regexp: 5.0.0 - exsolve: 1.1.1 - h3: 1.15.11 - impound: 1.1.6(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - klona: 2.0.6 - mocked-exports: 0.1.1 - nitropack: 2.13.4(oxc-parser@0.140.0)(rolldown@1.2.1)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - nostics: 1.2.0 - nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@oxc-project/types@0.142.0)(@parcel/watcher@2.5.6)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(@vue/compiler-sfc@3.5.40)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.1)(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue-tsc@3.3.11(typescript@6.0.3))(yaml@2.9.0) - nypm: 0.6.9 - ohash: 2.0.12 - pathe: 2.0.3 - rou3: 0.9.1 - std-env: 4.2.0 - ufo: 1.6.4 - unctx: 3.0.0(magic-string@1.2.2)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2)) - vue: 3.5.40(typescript@6.0.3) - vue-bundle-renderer: 2.3.1 - vue-devtools-stub: 0.1.0 - optionalDependencies: - '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.0(supports-color@10.2.2)) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@farmfe/core' - - '@libsql/client' - - '@netlify/blobs' - - '@oxc-project/types' - - '@planetscale/database' - - '@rspack/core' - - '@unhead/cli' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@vitejs/devtools-kit' - - aws4fetch - - bare-abort-controller - - bare-buffer - - better-sqlite3 - - bun-types-no-globals - - db0 - - drizzle-orm - - encoding - - esbuild - - idb-keyval - - ioredis - - lightningcss - - magic-string - - magicast - - mysql2 - - oxc-parser - - react-native-b4a - - rolldown - - rollup - - sqlite3 - - srvx - - supports-color - - typescript - - unloader - - unplugin - - uploadthing - - vite - - webpack - - xml2js - - '@nuxt/schema@4.5.2': - dependencies: - '@vue/shared': 3.5.40 - defu: 6.1.7 - nostics: 1.2.0 - pathe: 2.0.3 - pkg-types: 2.3.1 - std-env: 4.2.0 - - '@nuxt/telemetry@2.8.0(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))': - dependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - citty: 0.2.2 - consola: 3.4.2 - ofetch: 2.0.0-alpha.3 - rc9: 3.0.1 - std-env: 4.2.0 - - '@nuxt/ui@4.11.0(2cb0382fb94ddb82dc3bbb00dab71962)': - dependencies: - '@floating-ui/dom': 1.8.0 - '@iconify/vue': 5.0.1(vue@3.5.40(typescript@6.0.3)) - '@nuxt/fonts': 0.14.0(db0@0.3.4)(esbuild@0.28.0)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@nuxt/icon': 2.5.0(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@nuxt/schema': 4.5.2 - '@nuxtjs/color-mode': 4.0.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@standard-schema/spec': 1.1.0 - '@tailwindcss/postcss': 4.3.3 - '@tailwindcss/vite': 4.3.3(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@tanstack/vue-table': 8.21.3(vue@3.5.40(typescript@6.0.3)) - '@tanstack/vue-virtual': 3.13.36(vue@3.5.40(typescript@6.0.3)) - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/extension-bubble-menu': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-code': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-collaboration': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30) - '@tiptap/extension-drag-handle': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/extension-collaboration@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30))(@tiptap/extension-node-range@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)) - '@tiptap/extension-drag-handle-vue-3': 3.24.0(@tiptap/extension-drag-handle@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/extension-collaboration@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30))(@tiptap/extension-node-range@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)))(@tiptap/pm@3.24.0)(@tiptap/vue-3@3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(vue@3.5.40(typescript@6.0.3)))(vue@3.5.40(typescript@6.0.3)) - '@tiptap/extension-floating-menu': 3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-horizontal-rule': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-image': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-mention': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/suggestion@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-node-range': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-placeholder': 3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/markdown': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - '@tiptap/starter-kit': 3.24.0 - '@tiptap/suggestion': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/vue-3': 3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(vue@3.5.40(typescript@6.0.3)) - '@unhead/vue': 3.4.0(@oxc-project/types@0.142.0)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(esbuild@0.28.0)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@vueuse/core': 14.4.0(vue@3.5.40(typescript@6.0.3)) - '@vueuse/integrations': 14.4.0(change-case@5.4.4)(fuse.js@7.5.0)(vue@3.5.40(typescript@6.0.3)) - '@vueuse/shared': 14.4.0(vue@3.5.40(typescript@6.0.3)) - colortranslator: 5.0.0 - consola: 3.4.2 - defu: 6.1.7 - embla-carousel-auto-height: 8.6.0(embla-carousel@8.6.0) - embla-carousel-auto-scroll: 8.6.0(embla-carousel@8.6.0) - embla-carousel-autoplay: 8.6.0(embla-carousel@8.6.0) - embla-carousel-class-names: 8.6.0(embla-carousel@8.6.0) - embla-carousel-fade: 8.6.0(embla-carousel@8.6.0) - embla-carousel-vue: 8.6.0(vue@3.5.40(typescript@6.0.3)) - embla-carousel-wheel-gestures: 8.1.0(embla-carousel@8.6.0) - fuse.js: 7.5.0 - hookable: 6.1.1 - knitwork: 1.3.0 - magic-string: 1.2.2 - mlly: 1.8.2 - motion-v: 2.4.0(@vueuse/core@14.4.0(vue@3.5.40(typescript@6.0.3)))(vue@3.5.40(typescript@6.0.3)) - ohash: 2.0.12 - pathe: 2.0.3 - reka-ui: 2.10.3(vue@3.5.40(typescript@6.0.3)) - scule: 1.3.0 - tailwind-merge: 3.6.0 - tailwind-variants: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.3) - tailwindcss: 4.3.3 - tinyglobby: 0.2.17 - typescript: 6.0.3 - ufo: 1.6.4 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-auto-import: 21.1.0(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))(@vueuse/core@14.4.0(vue@3.5.40(typescript@6.0.3)))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-vue-components: 32.1.0(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - vaul-vue: 0.4.1(reka-ui@2.10.3(vue@3.5.40(typescript@6.0.3)))(vue@3.5.40(typescript@6.0.3)) - vue-component-type-helpers: 3.3.11 - optionalDependencies: - '@internationalized/date': 3.12.1 - '@internationalized/number': 3.6.6 - valibot: 1.4.2(typescript@6.0.3) - vue-router: 5.2.0(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - zod: 4.4.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@farmfe/core' - - '@netlify/blobs' - - '@oxc-project/types' - - '@planetscale/database' - - '@rspack/core' - - '@unhead/cli' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@vitejs/devtools-kit' - - '@vue/composition-api' - - async-validator - - aws4fetch - - axios - - bun-types-no-globals - - change-case - - db0 - - drauu - - embla-carousel - - esbuild - - focus-trap - - idb-keyval - - ioredis - - jwt-decode - - lightningcss - - magicast - - nprogress - - oxc-parser - - qrcode - - react - - react-dom - - rolldown - - rollup - - sortablejs - - universal-cookie - - unloader - - uploadthing - - vite - - vue - - webpack - - '@nuxt/vite-builder@4.5.2(521f6102c765bb8970dc9d69c7b33187)': - dependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@vitejs/plugin-vue': 6.0.8(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@vitejs/plugin-vue-jsx': 5.1.6(supports-color@10.2.2)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - autoprefixer: 10.5.4(postcss@8.5.25) - consola: 3.4.2 - cssnano: 8.0.2(postcss@8.5.25) - defu: 6.1.7 - escape-string-regexp: 5.0.0 - exsolve: 1.1.1 - generic-names: 4.0.0 - get-port-please: 3.2.0 - jiti: 2.7.0 - js-tokens: 10.0.0 - knitwork: 1.3.0 - mlly: 1.8.2 - mocked-exports: 0.1.1 - nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@oxc-project/types@0.142.0)(@parcel/watcher@2.5.6)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(@vue/compiler-sfc@3.5.40)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.1)(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue-tsc@3.3.11(typescript@6.0.3))(yaml@2.9.0) - nypm: 0.6.9 - pathe: 2.0.3 - pkg-types: 2.3.1 - postcss: 8.5.25 - rolldown-string: 0.3.1(rolldown@1.2.1) - seroval: 1.6.2 - std-env: 4.2.0 - ufo: 1.6.4 - unenv: 2.0.0-rc.24 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vite-node: 6.0.0(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vite-plugin-checker: 0.14.5(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(optionator@0.9.4)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue-tsc@3.3.11(typescript@6.0.3)) - vue: 3.5.40(typescript@6.0.3) - vue-bundle-renderer: 2.3.1 - optionalDependencies: - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0(supports-color@10.2.2)) - rolldown: 1.2.1 - rollup-plugin-visualizer: 7.0.1(rolldown@1.2.1)(rollup@4.60.4) - transitivePeerDependencies: - - '@biomejs/biome' - - '@farmfe/core' - - '@rspack/core' - - '@types/node' - - '@vitejs/devtools' - - bun-types-no-globals - - esbuild - - eslint - - less - - magic-string - - magicast - - meow - - optionator - - oxc-parser - - oxlint - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - unloader - - vue-tsc - - webpack - - yaml - - '@nuxtjs/color-mode@4.0.1(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))': - dependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - exsolve: 1.1.1 - pathe: 2.0.3 - pkg-types: 2.3.1 - semver: 7.8.5 - transitivePeerDependencies: - - magic-string - - magicast - - oxc-parser - - rolldown - - unplugin - - '@oxc-parser/binding-android-arm-eabi@0.140.0': - optional: true - - '@oxc-parser/binding-android-arm64@0.140.0': - optional: true - - '@oxc-parser/binding-darwin-arm64@0.140.0': - optional: true - - '@oxc-parser/binding-darwin-x64@0.140.0': - optional: true - - '@oxc-parser/binding-freebsd-x64@0.140.0': - optional: true - - '@oxc-parser/binding-linux-arm-gnueabihf@0.140.0': - optional: true - - '@oxc-parser/binding-linux-arm-musleabihf@0.140.0': - optional: true - - '@oxc-parser/binding-linux-arm64-gnu@0.140.0': - optional: true - - '@oxc-parser/binding-linux-arm64-musl@0.140.0': - optional: true - - '@oxc-parser/binding-linux-ppc64-gnu@0.140.0': - optional: true - - '@oxc-parser/binding-linux-riscv64-gnu@0.140.0': - optional: true - - '@oxc-parser/binding-linux-riscv64-musl@0.140.0': - optional: true - - '@oxc-parser/binding-linux-s390x-gnu@0.140.0': - optional: true - - '@oxc-parser/binding-linux-x64-gnu@0.140.0': - optional: true - - '@oxc-parser/binding-linux-x64-musl@0.140.0': - optional: true - - '@oxc-parser/binding-openharmony-arm64@0.140.0': - optional: true - - '@oxc-parser/binding-wasm32-wasi@0.140.0': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@napi-rs/wasm-runtime': 1.2.0(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) - optional: true - - '@oxc-parser/binding-win32-arm64-msvc@0.140.0': - optional: true - - '@oxc-parser/binding-win32-ia32-msvc@0.140.0': - optional: true - - '@oxc-parser/binding-win32-x64-msvc@0.140.0': - optional: true - - '@oxc-project/types@0.140.0': - optional: true - - '@oxc-project/types@0.142.0': {} - - '@parcel/watcher-android-arm64@2.5.6': - optional: true - - '@parcel/watcher-darwin-arm64@2.5.6': - optional: true - - '@parcel/watcher-darwin-x64@2.5.6': - optional: true - - '@parcel/watcher-freebsd-x64@2.5.6': - optional: true - - '@parcel/watcher-linux-arm-glibc@2.5.6': - optional: true - - '@parcel/watcher-linux-arm-musl@2.5.6': - optional: true - - '@parcel/watcher-linux-arm64-glibc@2.5.6': - optional: true - - '@parcel/watcher-linux-arm64-musl@2.5.6': - optional: true - - '@parcel/watcher-linux-x64-glibc@2.5.6': - optional: true - - '@parcel/watcher-linux-x64-musl@2.5.6': - optional: true - - '@parcel/watcher-wasm@2.5.6': - dependencies: - is-glob: 4.0.3 - picomatch: 4.0.5 - - '@parcel/watcher-win32-arm64@2.5.6': - optional: true - - '@parcel/watcher-win32-ia32@2.5.6': - optional: true - - '@parcel/watcher-win32-x64@2.5.6': - optional: true - - '@parcel/watcher@2.5.6': - dependencies: - detect-libc: 2.1.2 - is-glob: 4.0.3 - node-addon-api: 7.1.1 - picomatch: 4.0.5 - optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.6 - '@parcel/watcher-darwin-arm64': 2.5.6 - '@parcel/watcher-darwin-x64': 2.5.6 - '@parcel/watcher-freebsd-x64': 2.5.6 - '@parcel/watcher-linux-arm-glibc': 2.5.6 - '@parcel/watcher-linux-arm-musl': 2.5.6 - '@parcel/watcher-linux-arm64-glibc': 2.5.6 - '@parcel/watcher-linux-arm64-musl': 2.5.6 - '@parcel/watcher-linux-x64-glibc': 2.5.6 - '@parcel/watcher-linux-x64-musl': 2.5.6 - '@parcel/watcher-win32-arm64': 2.5.6 - '@parcel/watcher-win32-ia32': 2.5.6 - '@parcel/watcher-win32-x64': 2.5.6 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@polka/url@1.0.0-next.29': {} - - '@poppinss/colors@4.1.6': - dependencies: - kleur: 4.1.5 - - '@poppinss/dumper@0.7.0': - dependencies: - '@poppinss/colors': 4.1.6 - '@sindresorhus/is': 7.2.0 - supports-color: 10.2.2 - - '@poppinss/exception@1.2.3': {} - - '@rolldown/binding-android-arm64@1.2.1': - optional: true - - '@rolldown/binding-darwin-arm64@1.2.1': - optional: true - - '@rolldown/binding-darwin-x64@1.2.1': - optional: true - - '@rolldown/binding-freebsd-x64@1.2.1': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.2.1': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.2.1': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.2.1': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.2.1': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.2.1': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.2.1': - optional: true - - '@rolldown/binding-linux-x64-musl@1.2.1': - optional: true - - '@rolldown/binding-openharmony-arm64@1.2.1': - optional: true - - '@rolldown/binding-wasm32-wasi@1.2.1': - dependencies: - '@emnapi/core': 2.0.0-alpha.3 - '@emnapi/runtime': 2.0.0-alpha.3 - '@napi-rs/wasm-runtime': 1.2.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.2.1': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.2.1': - optional: true - - '@rolldown/pluginutils@1.0.1': {} - - '@rollup/plugin-alias@6.0.0(rollup@4.60.4)': - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-commonjs@29.0.2(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - commondir: 1.0.1 - estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.5) - is-reference: 1.2.1 - magic-string: 0.30.21 - picomatch: 4.0.5 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-inject@5.0.5(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - estree-walker: 2.0.2 - magic-string: 0.30.21 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-json@6.1.0(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.12 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-replace@6.0.3(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - magic-string: 0.30.21 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-terser@1.0.0(rollup@4.60.4)': - dependencies: - serialize-javascript: 7.0.5 - smob: 1.6.2 - terser: 5.47.1 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/pluginutils@5.3.0(rollup@4.60.4)': - dependencies: - '@types/estree': 1.0.9 - estree-walker: 2.0.2 - picomatch: 4.0.5 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/rollup-android-arm-eabi@4.60.4': - optional: true - - '@rollup/rollup-android-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-x64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-arm64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-x64@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-musl@4.60.4': - optional: true - - '@rollup/rollup-openbsd-x64@4.60.4': - optional: true - - '@rollup/rollup-openharmony-arm64@4.60.4': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.60.4': - optional: true - - '@simple-git/args-pathspec@1.0.3': {} - - '@simple-git/argv-parser@1.1.1': - dependencies: - '@simple-git/args-pathspec': 1.0.3 - - '@sindresorhus/base62@1.0.0': {} - - '@sindresorhus/is@7.2.0': {} - - '@sindresorhus/merge-streams@4.0.0': {} - - '@speed-highlight/core@1.2.15': {} - - '@standard-schema/spec@1.1.0': {} - - '@stylistic/eslint-plugin@5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@typescript-eslint/types': 8.66.0 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - estraverse: 5.3.0 - picomatch: 4.0.5 - - '@swc/helpers@0.5.21': - dependencies: - tslib: 2.8.1 - - '@tailwindcss/node@4.3.3': - dependencies: - '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.24.5 - jiti: 2.7.0 - lightningcss: 1.32.0 - magic-string: 0.30.21 - source-map-js: 1.2.1 - tailwindcss: 4.3.3 - - '@tailwindcss/oxide-android-arm64@4.3.3': - optional: true - - '@tailwindcss/oxide-darwin-arm64@4.3.3': - optional: true - - '@tailwindcss/oxide-darwin-x64@4.3.3': - optional: true - - '@tailwindcss/oxide-freebsd-x64@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-arm64-musl@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-x64-gnu@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-x64-musl@4.3.3': - optional: true - - '@tailwindcss/oxide-wasm32-wasi@4.3.3': - optional: true - - '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': - optional: true - - '@tailwindcss/oxide-win32-x64-msvc@4.3.3': - optional: true - - '@tailwindcss/oxide@4.3.3': - optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.3.3 - '@tailwindcss/oxide-darwin-arm64': 4.3.3 - '@tailwindcss/oxide-darwin-x64': 4.3.3 - '@tailwindcss/oxide-freebsd-x64': 4.3.3 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 - '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 - '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 - '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 - '@tailwindcss/oxide-linux-x64-musl': 4.3.3 - '@tailwindcss/oxide-wasm32-wasi': 4.3.3 - '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 - '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 - - '@tailwindcss/postcss@4.3.3': - dependencies: - '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.3.3 - '@tailwindcss/oxide': 4.3.3 - postcss: 8.5.25 - tailwindcss: 4.3.3 - - '@tailwindcss/vite@4.3.3(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - '@tailwindcss/node': 4.3.3 - '@tailwindcss/oxide': 4.3.3 - tailwindcss: 4.3.3 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - - '@tanstack/table-core@8.21.3': {} - - '@tanstack/virtual-core@3.17.8': {} - - '@tanstack/vue-table@8.21.3(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@tanstack/table-core': 8.21.3 - vue: 3.5.40(typescript@6.0.3) - - '@tanstack/vue-virtual@3.13.36(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@tanstack/virtual-core': 3.17.8 - vue: 3.5.40(typescript@6.0.3) - - '@tiptap/core@3.24.0(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-blockquote@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-bold@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-bubble-menu@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-bullet-list@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-code-block@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-code@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-collaboration@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - '@tiptap/y-tiptap': 3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) - yjs: 13.6.30 - - '@tiptap/extension-document@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-drag-handle-vue-3@3.24.0(@tiptap/extension-drag-handle@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/extension-collaboration@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30))(@tiptap/extension-node-range@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)))(@tiptap/pm@3.24.0)(@tiptap/vue-3@3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(vue@3.5.40(typescript@6.0.3)))(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@tiptap/extension-drag-handle': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/extension-collaboration@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30))(@tiptap/extension-node-range@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)) - '@tiptap/pm': 3.24.0 - '@tiptap/vue-3': 3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(vue@3.5.40(typescript@6.0.3)) - vue: 3.5.40(typescript@6.0.3) - - '@tiptap/extension-drag-handle@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/extension-collaboration@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30))(@tiptap/extension-node-range@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))': - dependencies: - '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/extension-collaboration': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30))(yjs@13.6.30) - '@tiptap/extension-node-range': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - '@tiptap/y-tiptap': 3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30) - - '@tiptap/extension-dropcursor@3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-floating-menu@3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-gapcursor@3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-hard-break@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-heading@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-horizontal-rule@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-image@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-italic@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - linkifyjs: 4.3.3 - - '@tiptap/extension-list-item@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-list-keymap@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-mention@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@tiptap/suggestion@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - '@tiptap/suggestion': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-node-range@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/extension-ordered-list@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-paragraph@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-placeholder@3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/extension-strike@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-text@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extension-underline@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - - '@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/markdown@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - marked: 17.0.6 - - '@tiptap/pm@3.24.0': - dependencies: - prosemirror-changeset: 2.4.1 - prosemirror-commands: 1.7.1 - prosemirror-dropcursor: 1.8.2 - prosemirror-gapcursor: 1.4.1 - prosemirror-history: 1.5.0 - prosemirror-inputrules: 1.5.1 - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.7 - prosemirror-schema-list: 1.5.1 - prosemirror-state: 1.4.4 - prosemirror-tables: 1.8.5 - prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 - - '@tiptap/starter-kit@3.24.0': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/extension-blockquote': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-bold': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-bullet-list': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-code': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-code-block': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-document': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-dropcursor': 3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-gapcursor': 3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-hard-break': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-heading': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-horizontal-rule': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-italic': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-link': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-list-item': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-list-keymap': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-ordered-list': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)) - '@tiptap/extension-paragraph': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-strike': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-text': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extension-underline': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)) - '@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/suggestion@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)': - dependencies: - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - - '@tiptap/vue-3@3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@floating-ui/dom': 1.8.0 - '@tiptap/core': 3.24.0(@tiptap/pm@3.24.0) - '@tiptap/pm': 3.24.0 - vue: 3.5.40(typescript@6.0.3) - optionalDependencies: - '@tiptap/extension-bubble-menu': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - '@tiptap/extension-floating-menu': 3.24.0(@floating-ui/dom@1.8.0)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0) - - '@tiptap/y-tiptap@3.0.7(prosemirror-model@1.25.7)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8)(y-protocols@1.0.7(yjs@13.6.30))(yjs@13.6.30)': - dependencies: - lib0: 0.2.117 - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 - y-protocols: 1.0.7(yjs@13.6.30) - yjs: 13.6.30 - - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/esrecurse@4.3.1': {} - - '@types/estree@1.0.8': {} - - '@types/estree@1.0.9': {} - - '@types/jsesc@2.5.1': {} - - '@types/json-schema@7.0.15': {} - - '@types/resolve@1.20.2': {} - - '@types/web-bluetooth@0.0.20': {} - - '@types/web-bluetooth@0.0.21': {} - - '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/type-utils': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.66.0 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - ignore: 7.0.6 - natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.66.0 - debug: 4.4.3(supports-color@10.2.2) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.66.0(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) - '@typescript-eslint/types': 8.66.0 - debug: 4.4.3(supports-color@10.2.2) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.66.0': - dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/visitor-keys': 8.66.0 - - '@typescript-eslint/tsconfig-utils@8.66.0(typescript@6.0.3)': - dependencies: - typescript: 6.0.3 - - '@typescript-eslint/type-utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - debug: 4.4.3(supports-color@10.2.2) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.66.0': {} - - '@typescript-eslint/typescript-estree@8.66.0(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@typescript-eslint/project-service': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/visitor-keys': 8.66.0 - debug: 4.4.3(supports-color@10.2.2) - minimatch: 10.2.5 - semver: 7.8.5 - tinyglobby: 0.2.17 - ts-api-utils: 2.5.0(typescript@6.0.3) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@10.2.2)(typescript@6.0.3) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.66.0': - dependencies: - '@typescript-eslint/types': 8.66.0 - eslint-visitor-keys: 5.0.1 - - '@unhead/bundler@3.4.0(@oxc-project/types@0.142.0)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(esbuild@0.28.0)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(unhead@3.4.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - magic-string: 1.2.2 - oxc-walker: 1.1.1(@oxc-project/types@0.142.0)(oxc-parser@0.140.0)(rolldown@1.2.1) - unhead: 3.4.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - optionalDependencies: - '@vitejs/devtools-kit': 0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - esbuild: 0.28.0 - lightningcss: 1.33.0 - oxc-parser: 0.140.0 - rolldown: 1.2.1 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@farmfe/core' - - '@oxc-project/types' - - '@rspack/core' - - bun-types-no-globals - - rollup - - unloader - - '@unhead/vue@3.4.0(@oxc-project/types@0.142.0)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(esbuild@0.28.0)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@unhead/bundler': 3.4.0(@oxc-project/types@0.142.0)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(esbuild@0.28.0)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(unhead@3.4.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - hookable: 6.1.1 - unhead: 3.4.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - vue: 3.5.40(typescript@6.0.3) - optionalDependencies: - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@farmfe/core' - - '@oxc-project/types' - - '@rspack/core' - - '@unhead/cli' - - '@vitejs/devtools-kit' - - bun-types-no-globals - - esbuild - - lightningcss - - oxc-parser - - rolldown - - rollup - - unloader - - '@unrs/resolver-binding-android-arm-eabi@1.12.2': - optional: true - - '@unrs/resolver-binding-android-arm64@1.12.2': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.12.2': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.12.2': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-loong64-musl@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.12.2': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.12.2': - optional: true - - '@unrs/resolver-binding-openharmony-arm64@1.12.2': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.12.2': - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.2.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.12.2': - optional: true - - '@valibot/to-json-schema@1.7.1(valibot@1.4.2(typescript@6.0.3))': - dependencies: - valibot: 1.4.2(typescript@6.0.3) - optional: true - - '@vercel/nft@1.5.0(rollup@4.60.4)(supports-color@10.2.2)': - dependencies: - '@mapbox/node-pre-gyp': 2.0.3(supports-color@10.2.2) - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - acorn: 8.18.0 - acorn-import-attributes: 1.9.5(acorn@8.18.0) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 13.0.6 - graceful-fs: 4.2.11 - node-gyp-build: 4.8.4 - picomatch: 4.0.5 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))': - dependencies: - '@devframes/hub': 0.7.15(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) - '@devframes/json-render': 0.7.15(@devframes/hub@0.7.15(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) - devframe: 0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) - local-pkg: 1.2.1 - mlly: 1.8.2 - nostics: 1.2.0 - nypm: 0.6.9 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@modelcontextprotocol/sdk' - - cac - - srvx - - typescript - optional: true - - '@vitejs/plugin-vue-jsx@5.1.6(supports-color@10.2.2)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.0(supports-color@10.2.2)) - '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2) - '@rolldown/pluginutils': 1.0.1 - '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2) - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vue: 3.5.40(typescript@6.0.3) - transitivePeerDependencies: - - supports-color - - '@vitejs/plugin-vue@6.0.8(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@rolldown/pluginutils': 1.0.1 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vue: 3.5.40(typescript@6.0.3) - - '@volar/language-core@2.4.28': - dependencies: - '@volar/source-map': 2.4.28 - - '@volar/source-map@2.4.28': {} - - '@volar/typescript@2.4.28(typescript@6.0.3)': - dependencies: - '@volar/language-core': 2.4.28 - path-browserify: 1.0.1 - vscode-uri: 3.1.0 - optionalDependencies: - typescript: 6.0.3 - - '@vue-macros/common@3.1.4(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@vue/compiler-sfc': 3.5.40 - ast-kit: 2.2.0 - local-pkg: 1.2.1 - magic-string-ast: 1.0.3 - unplugin-utils: 0.3.2 - optionalDependencies: - vue: 3.5.40(typescript@6.0.3) - - '@vue/babel-helper-vue-transform-on@2.0.1': {} - - '@vue/babel-plugin-jsx@2.0.1(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2)': - dependencies: - '@babel/helper-module-imports': 7.28.6(supports-color@10.2.2) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0(supports-color@10.2.2)) - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7(supports-color@10.2.2) - '@babel/types': 7.29.7 - '@vue/babel-helper-vue-transform-on': 2.0.1 - '@vue/babel-plugin-resolve-type': 2.0.1(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2) - '@vue/shared': 3.5.40 - optionalDependencies: - '@babel/core': 7.29.0(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - '@vue/babel-plugin-resolve-type@2.0.1(@babel/core@7.29.0(supports-color@10.2.2))(supports-color@10.2.2)': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/core': 7.29.0(supports-color@10.2.2) - '@babel/helper-module-imports': 7.28.6(supports-color@10.2.2) - '@babel/helper-plugin-utils': 7.29.7 - '@babel/parser': 7.29.7 - '@vue/compiler-sfc': 3.5.40 - transitivePeerDependencies: - - supports-color - - '@vue/compiler-core@3.5.40': - dependencies: - '@babel/parser': 7.29.7 - '@vue/shared': 3.5.40 - entities: 7.0.1 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.40': - dependencies: - '@vue/compiler-core': 3.5.40 - '@vue/shared': 3.5.40 - - '@vue/compiler-sfc@3.5.40': - dependencies: - '@babel/parser': 7.29.7 - '@vue/compiler-core': 3.5.40 - '@vue/compiler-dom': 3.5.40 - '@vue/compiler-ssr': 3.5.40 - '@vue/shared': 3.5.40 - estree-walker: 2.0.2 - magic-string: 0.30.21 - postcss: 8.5.25 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.40': - dependencies: - '@vue/compiler-dom': 3.5.40 - '@vue/shared': 3.5.40 - - '@vue/devtools-api@8.2.1': - dependencies: - '@vue/devtools-kit': 8.2.1 - - '@vue/devtools-core@8.2.1(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@vue/devtools-kit': 8.2.1 - '@vue/devtools-shared': 8.2.1 - vue: 3.5.40(typescript@6.0.3) - - '@vue/devtools-kit@8.2.1': - dependencies: - '@vue/devtools-shared': 8.2.1 - birpc: 2.9.0 - hookable: 5.5.3 - perfect-debounce: 2.1.0 - - '@vue/devtools-shared@8.2.1': {} - - '@vue/language-core@3.3.11': - dependencies: - '@volar/language-core': 2.4.28 - '@vue/compiler-dom': 3.5.40 - '@vue/shared': 3.5.40 - alien-signals: 3.2.1 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - picomatch: 4.0.5 - - '@vue/reactivity@3.5.40': - dependencies: - '@vue/shared': 3.5.40 - - '@vue/runtime-core@3.5.40': - dependencies: - '@vue/reactivity': 3.5.40 - '@vue/shared': 3.5.40 - - '@vue/runtime-dom@3.5.40': - dependencies: - '@vue/reactivity': 3.5.40 - '@vue/runtime-core': 3.5.40 - '@vue/shared': 3.5.40 - csstype: 3.2.3 - - '@vue/server-renderer@3.5.40': - dependencies: - '@vue/compiler-ssr': 3.5.40 - '@vue/runtime-dom': 3.5.40 - '@vue/shared': 3.5.40 - - '@vue/shared@3.5.40': {} - - '@vueuse/core@10.11.1(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.40(typescript@6.0.3)) - vue-demi: 0.14.10(vue@3.5.40(typescript@6.0.3)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@vueuse/core@14.4.0(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 14.4.0 - '@vueuse/shared': 14.4.0(vue@3.5.40(typescript@6.0.3)) - vue: 3.5.40(typescript@6.0.3) - - '@vueuse/integrations@14.4.0(change-case@5.4.4)(fuse.js@7.5.0)(vue@3.5.40(typescript@6.0.3))': - dependencies: - '@vueuse/core': 14.4.0(vue@3.5.40(typescript@6.0.3)) - '@vueuse/shared': 14.4.0(vue@3.5.40(typescript@6.0.3)) - vue: 3.5.40(typescript@6.0.3) - optionalDependencies: - change-case: 5.4.4 - fuse.js: 7.5.0 - - '@vueuse/metadata@10.11.1': {} - - '@vueuse/metadata@14.4.0': {} - - '@vueuse/shared@10.11.1(vue@3.5.40(typescript@6.0.3))': - dependencies: - vue-demi: 0.14.10(vue@3.5.40(typescript@6.0.3)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - - '@vueuse/shared@14.4.0(vue@3.5.40(typescript@6.0.3))': - dependencies: - vue: 3.5.40(typescript@6.0.3) - - abbrev@3.0.1: {} - - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - - acorn-import-attributes@1.9.5(acorn@8.18.0): - dependencies: - acorn: 8.18.0 - - acorn-jsx@5.3.2(acorn@8.18.0): - dependencies: - acorn: 8.18.0 - - acorn@8.18.0: {} - - agent-base@7.1.4: {} - - ajv@6.15.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - alien-signals@3.2.1: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.2.2: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.3: {} - - ansis@4.3.1: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.2 - - archiver-utils@5.0.2: - dependencies: - glob: 10.5.0 - graceful-fs: 4.2.11 - is-stream: 2.0.1 - lazystream: 1.0.1 - lodash: 4.18.1 - normalize-path: 3.0.0 - readable-stream: 4.7.0 - - archiver@7.0.1: - dependencies: - archiver-utils: 5.0.2 - async: 3.2.6 - buffer-crc32: 1.0.0 - readable-stream: 4.7.0 - readdir-glob: 1.1.3 - tar-stream: 3.2.0 - zip-stream: 6.0.1 - transitivePeerDependencies: - - bare-abort-controller - - bare-buffer - - react-native-b4a - - are-docs-informative@0.0.2: {} - - argparse@2.0.1: {} - - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - - ast-kit@2.2.0: - dependencies: - '@babel/parser': 7.29.7 - pathe: 2.0.3 - - ast-walker-scope@0.9.0: - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - ast-kit: 2.2.0 - - async-sema@3.1.1: {} - - async@3.2.6: {} - - autoprefixer@10.5.4(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - caniuse-lite: 1.0.30001806 - fraction.js: 5.3.4 - picocolors: 1.1.1 - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - b4a@1.8.1: {} - - balanced-match@1.0.2: {} - - balanced-match@4.0.4: {} - - bare-events@2.8.3: {} - - bare-fs@4.7.1: - dependencies: - bare-events: 2.8.3 - bare-path: 3.0.0 - bare-stream: 2.13.1(bare-events@2.8.3) - bare-url: 2.4.3 - fast-fifo: 1.3.2 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - bare-os@3.9.1: {} - - bare-path@3.0.0: - dependencies: - bare-os: 3.9.1 - - bare-stream@2.13.1(bare-events@2.8.3): - dependencies: - streamx: 2.25.0 - teex: 1.0.1 - optionalDependencies: - bare-events: 2.8.3 - transitivePeerDependencies: - - react-native-b4a - - bare-url@2.4.3: - dependencies: - bare-path: 3.0.0 - - base64-js@1.5.1: {} - - baseline-browser-mapping@2.11.7: {} - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - - birpc@2.9.0: {} - - birpc@4.0.0: {} - - boolbase@1.0.0: {} - - brace-expansion@2.1.0: - dependencies: - balanced-match: 1.0.2 - - brace-expansion@5.0.6: - dependencies: - balanced-match: 4.0.4 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.28.7: - dependencies: - baseline-browser-mapping: 2.11.7 - caniuse-lite: 1.0.30001806 - electron-to-chromium: 1.5.398 - node-releases: 2.0.51 - update-browserslist-db: 1.2.3(browserslist@4.28.7) - - buffer-crc32@1.0.0: {} - - buffer-from@1.1.2: {} - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - builtin-modules@5.2.0: {} - - bundle-name@4.1.0: - dependencies: - run-applescript: 7.1.0 - - c12@3.3.4(magicast@0.5.4): - dependencies: - chokidar: 5.0.0 - confbox: 0.2.4 - defu: 6.1.7 - dotenv: 17.4.2 - exsolve: 1.1.1 - giget: 3.3.1 - jiti: 2.7.0 - ohash: 2.0.12 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.1 - rc9: 3.0.1 - optionalDependencies: - magicast: 0.5.4 - - cac@7.0.0: {} - - caniuse-api@4.0.0: - dependencies: - browserslist: 4.28.7 - caniuse-lite: 1.0.30001806 - - caniuse-lite@1.0.30001806: {} - - change-case@5.4.4: {} - - chokidar@5.0.0: - dependencies: - readdirp: 5.0.0 - - chownr@3.0.0: {} - - ci-info@4.4.0: {} - - citty@0.1.6: - dependencies: - consola: 3.4.2 - - citty@0.2.2: {} - - cliui@9.0.1: - dependencies: - string-width: 7.2.0 - strip-ansi: 7.2.0 - wrap-ansi: 9.0.2 - - cluster-key-slot@1.1.2: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - colortranslator@5.0.0: {} - - commander@11.1.0: {} - - commander@2.20.3: {} - - comment-parser@1.4.7: {} - - commondir@1.0.1: {} - - compatx@0.2.0: {} - - compress-commons@6.0.2: - dependencies: - crc-32: 1.2.2 - crc32-stream: 6.0.0 - is-stream: 2.0.1 - normalize-path: 3.0.0 - readable-stream: 4.7.0 - - confbox@0.1.8: {} - - confbox@0.2.4: {} - - consola@3.4.2: {} - - convert-hrtime@5.0.0: {} - - convert-source-map@2.0.0: {} - - cookie-es@1.2.3: {} - - cookie-es@2.0.1: {} - - cookie-es@3.1.1: {} - - core-js-compat@3.49.0: - dependencies: - browserslist: 4.28.7 - - core-util-is@1.0.3: {} - - crc-32@1.2.2: {} - - crc32-stream@6.0.0: - dependencies: - crc-32: 1.2.2 - readable-stream: 4.7.0 - - croner@10.0.1: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - crossws@0.3.5: - dependencies: - uncrypto: 0.1.3 - - crossws@0.4.10(srvx@0.11.22): - optionalDependencies: - srvx: 0.11.22 - - css-select@5.2.2: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - - css-tree@2.2.1: - dependencies: - mdn-data: 2.0.28 - source-map-js: 1.2.1 - - css-tree@3.2.1: - dependencies: - mdn-data: 2.27.1 - source-map-js: 1.2.1 - - css-what@6.2.2: {} - - cssesc@3.0.0: {} - - cssnano-preset-default@8.0.2(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - cssnano-utils: 6.0.1(postcss@8.5.25) - postcss: 8.5.25 - postcss-calc: 10.1.1(postcss@8.5.25) - postcss-colormin: 8.0.1(postcss@8.5.25) - postcss-convert-values: 8.0.1(postcss@8.5.25) - postcss-discard-comments: 8.0.1(postcss@8.5.25) - postcss-discard-duplicates: 8.0.1(postcss@8.5.25) - postcss-discard-empty: 8.0.1(postcss@8.5.25) - postcss-discard-overridden: 8.0.1(postcss@8.5.25) - postcss-merge-longhand: 8.0.1(postcss@8.5.25) - postcss-merge-rules: 8.0.1(postcss@8.5.25) - postcss-minify-font-values: 8.0.1(postcss@8.5.25) - postcss-minify-gradients: 8.0.1(postcss@8.5.25) - postcss-minify-params: 8.0.1(postcss@8.5.25) - postcss-minify-selectors: 8.0.2(postcss@8.5.25) - postcss-normalize-charset: 8.0.1(postcss@8.5.25) - postcss-normalize-display-values: 8.0.1(postcss@8.5.25) - postcss-normalize-positions: 8.0.1(postcss@8.5.25) - postcss-normalize-repeat-style: 8.0.1(postcss@8.5.25) - postcss-normalize-string: 8.0.1(postcss@8.5.25) - postcss-normalize-timing-functions: 8.0.1(postcss@8.5.25) - postcss-normalize-unicode: 8.0.1(postcss@8.5.25) - postcss-normalize-url: 8.0.1(postcss@8.5.25) - postcss-normalize-whitespace: 8.0.1(postcss@8.5.25) - postcss-ordered-values: 8.0.1(postcss@8.5.25) - postcss-reduce-initial: 8.0.1(postcss@8.5.25) - postcss-reduce-transforms: 8.0.1(postcss@8.5.25) - postcss-svgo: 8.0.1(postcss@8.5.25) - postcss-unique-selectors: 8.0.1(postcss@8.5.25) - - cssnano-utils@6.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - - cssnano@8.0.2(postcss@8.5.25): - dependencies: - cssnano-preset-default: 8.0.2(postcss@8.5.25) - lilconfig: 3.1.3 - postcss: 8.5.25 - - csso@5.0.5: - dependencies: - css-tree: 2.2.1 - - csstype@3.2.3: {} - - db0@0.3.4: {} - - debug@4.4.3(supports-color@10.2.2): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 10.2.2 - - deep-is@0.1.4: {} - - deepmerge@4.3.1: {} - - default-browser-id@5.0.1: {} - - default-browser@5.5.0: - dependencies: - bundle-name: 4.1.0 - default-browser-id: 5.0.1 - - define-lazy-prop@3.0.0: {} - - defu@6.1.7: {} - - denque@2.1.0: {} - - depd@2.0.0: {} - - destr@2.0.5: {} - - detect-indent@7.0.2: {} - - detect-libc@2.1.2: {} - - devalue@5.9.0: {} - - devframe@0.7.15(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3): - dependencies: - '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) - birpc: 4.0.0 - crossws: 0.4.10(srvx@0.11.22) - destr: 2.0.5 - h3: 2.0.1-rc.26(crossws@0.4.10(srvx@0.11.22)) - mrmime: 2.0.1 - nostics: 1.2.0 - pathe: 2.0.3 - ufo: 1.6.4 - valibot: 1.4.2(typescript@6.0.3) - optionalDependencies: - cac: 7.0.0 - transitivePeerDependencies: - - srvx - - typescript - optional: true - - devframe@0.8.2(cac@7.0.0)(srvx@0.11.22): - dependencies: - '@standard-schema/spec': 1.1.0 - birpc: 4.0.0 - crossws: 0.4.10(srvx@0.11.22) - destr: 2.0.5 - h3: 2.0.1-rc.26(crossws@0.4.10(srvx@0.11.22)) - mrmime: 2.0.1 - nostics: 1.2.0 - pathe: 2.0.3 - ufo: 1.6.4 - optionalDependencies: - cac: 7.0.0 - transitivePeerDependencies: - - srvx - - diff@8.0.4: {} - - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - - domelementtype@2.3.0: {} - - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - - dot-prop@10.1.0: - dependencies: - type-fest: 5.6.0 - - dotenv@17.4.2: {} - - duplexer@0.1.2: {} - - eastasianwidth@0.2.0: {} - - ee-first@1.1.1: {} - - electron-to-chromium@1.5.398: {} - - embla-carousel-auto-height@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel-auto-scroll@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel-autoplay@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel-class-names@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel-fade@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - - embla-carousel-vue@8.6.0(vue@3.5.40(typescript@6.0.3)): - dependencies: - embla-carousel: 8.6.0 - embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) - vue: 3.5.40(typescript@6.0.3) - - embla-carousel-wheel-gestures@8.1.0(embla-carousel@8.6.0): - dependencies: - embla-carousel: 8.6.0 - wheel-gestures: 2.2.48 - - embla-carousel@8.6.0: {} - - emoji-regex@10.6.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - encodeurl@2.0.0: {} - - enhanced-resolve@5.24.5: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - - entities@4.5.0: {} - - entities@7.0.1: {} - - error-stack-parser-es@1.0.5: {} - - error-stack-parser-es@2.0.1: {} - - errx@0.1.2: {} - - es-errors@1.3.0: {} - - es-module-lexer@2.1.0: {} - - esbuild@0.27.7: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.7 - '@esbuild/android-arm': 0.27.7 - '@esbuild/android-arm64': 0.27.7 - '@esbuild/android-x64': 0.27.7 - '@esbuild/darwin-arm64': 0.27.7 - '@esbuild/darwin-x64': 0.27.7 - '@esbuild/freebsd-arm64': 0.27.7 - '@esbuild/freebsd-x64': 0.27.7 - '@esbuild/linux-arm': 0.27.7 - '@esbuild/linux-arm64': 0.27.7 - '@esbuild/linux-ia32': 0.27.7 - '@esbuild/linux-loong64': 0.27.7 - '@esbuild/linux-mips64el': 0.27.7 - '@esbuild/linux-ppc64': 0.27.7 - '@esbuild/linux-riscv64': 0.27.7 - '@esbuild/linux-s390x': 0.27.7 - '@esbuild/linux-x64': 0.27.7 - '@esbuild/netbsd-arm64': 0.27.7 - '@esbuild/netbsd-x64': 0.27.7 - '@esbuild/openbsd-arm64': 0.27.7 - '@esbuild/openbsd-x64': 0.27.7 - '@esbuild/openharmony-arm64': 0.27.7 - '@esbuild/sunos-x64': 0.27.7 - '@esbuild/win32-arm64': 0.27.7 - '@esbuild/win32-ia32': 0.27.7 - '@esbuild/win32-x64': 0.27.7 - - esbuild@0.28.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.0 - '@esbuild/android-arm': 0.28.0 - '@esbuild/android-arm64': 0.28.0 - '@esbuild/android-x64': 0.28.0 - '@esbuild/darwin-arm64': 0.28.0 - '@esbuild/darwin-x64': 0.28.0 - '@esbuild/freebsd-arm64': 0.28.0 - '@esbuild/freebsd-x64': 0.28.0 - '@esbuild/linux-arm': 0.28.0 - '@esbuild/linux-arm64': 0.28.0 - '@esbuild/linux-ia32': 0.28.0 - '@esbuild/linux-loong64': 0.28.0 - '@esbuild/linux-mips64el': 0.28.0 - '@esbuild/linux-ppc64': 0.28.0 - '@esbuild/linux-riscv64': 0.28.0 - '@esbuild/linux-s390x': 0.28.0 - '@esbuild/linux-x64': 0.28.0 - '@esbuild/netbsd-arm64': 0.28.0 - '@esbuild/netbsd-x64': 0.28.0 - '@esbuild/openbsd-arm64': 0.28.0 - '@esbuild/openbsd-x64': 0.28.0 - '@esbuild/openharmony-arm64': 0.28.0 - '@esbuild/sunos-x64': 0.28.0 - '@esbuild/win32-arm64': 0.28.0 - '@esbuild/win32-ia32': 0.28.0 - '@esbuild/win32-x64': 0.28.0 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@4.0.0: {} - - escape-string-regexp@5.0.0: {} - - eslint-config-flat-gitignore@2.3.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - '@eslint/compat': 2.1.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - - eslint-flat-config-utils@3.2.0: - dependencies: - '@eslint/config-helpers': 0.5.5 - pathe: 2.0.3 - - eslint-import-context@0.1.9(unrs-resolver@1.12.2): - dependencies: - get-tsconfig: 4.14.0 - stable-hash-x: 0.2.0 - optionalDependencies: - unrs-resolver: 1.12.2 - - eslint-merge-processors@2.0.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - - eslint-plugin-import-lite@0.6.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - - eslint-plugin-import-x@4.17.1(@typescript-eslint/utils@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2): - dependencies: - '@typescript-eslint/types': 8.66.0 - comment-parser: 1.4.7 - debug: 4.4.3(supports-color@10.2.2) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - eslint-import-context: 0.1.9(unrs-resolver@1.12.2) - is-glob: 4.0.3 - minimatch: 10.2.5 - semver: 7.8.5 - stable-hash-x: 0.2.0 - unrs-resolver: 1.12.2 - optionalDependencies: - '@typescript-eslint/utils': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - transitivePeerDependencies: - - supports-color - - eslint-plugin-jsdoc@63.3.3(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2): - dependencies: - '@es-joy/jsdoccomment': 0.91.0 - '@es-joy/resolve.exports': 1.2.0 - are-docs-informative: 0.0.2 - comment-parser: 1.4.7 - debug: 4.4.3(supports-color@10.2.2) - escape-string-regexp: 4.0.0 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - espree: 11.2.0 - esquery: 1.7.0 - html-entities: 2.6.0 - object-deep-merge: 2.0.1 - parse-imports-exports: 0.2.4 - semver: 7.8.5 - spdx-expression-parse: 5.0.0 - to-valid-identifier: 1.0.0 - transitivePeerDependencies: - - supports-color - - eslint-plugin-regexp@3.1.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@eslint-community/regexpp': 4.12.2 - comment-parser: 1.4.7 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - jsdoc-type-pratt-parser: 7.2.0 - refa: 0.12.1 - regexp-ast-analysis: 0.7.1 - scslre: 0.3.0 - - eslint-plugin-unicorn@73.0.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@eslint/css-tree': 4.0.5 - browserslist: 4.28.7 - change-case: 5.4.4 - ci-info: 4.4.0 - core-js-compat: 3.49.0 - detect-indent: 7.0.2 - entities: 4.5.0 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - find-up-simple: 1.0.1 - globals: 17.9.0 - indent-string: 5.0.0 - is-builtin-module: 5.0.0 - is-identifier: 1.1.0 - pluralize: 8.0.0 - quote-js-string: 0.1.0 - regjsparser: 0.13.2 - reserved-identifiers: 1.2.0 - semver: 7.8.5 - strip-indent: 4.1.1 - yaml: 2.9.0 - - eslint-plugin-vue@10.10.0(@stylistic/eslint-plugin@5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)))(@typescript-eslint/parser@8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(vue-eslint-parser@10.4.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - natural-compare: 1.4.0 - nth-check: 2.1.1 - postcss-selector-parser: 7.1.4 - semver: 7.8.5 - vue-eslint-parser: 10.4.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2) - xml-name-validator: 5.0.0 - optionalDependencies: - '@stylistic/eslint-plugin': 5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@typescript-eslint/parser': 8.66.0(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) - - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.40)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - '@vue/compiler-sfc': 3.5.40 - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - - eslint-scope@9.1.2: - dependencies: - '@types/esrecurse': 4.3.1 - '@types/estree': 1.0.9 - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-typegen@2.3.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)): - dependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - json-schema-to-typescript-lite: 15.0.0 - ohash: 2.0.12 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint-visitor-keys@5.0.1: {} - - eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2)) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.5(supports-color@10.2.2) - '@eslint/config-helpers': 0.7.0 - '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.2 - '@humanfs/node': 0.16.8 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.9 - ajv: 6.15.0 - cross-spawn: 7.0.6 - debug: 4.4.3(supports-color@10.2.2) - escape-string-regexp: 4.0.0 - eslint-scope: 9.1.2 - eslint-visitor-keys: 5.0.1 - espree: 11.2.0 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - minimatch: 10.2.5 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.7.0 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.18.0 - acorn-jsx: 5.3.2(acorn@8.18.0) - eslint-visitor-keys: 4.2.1 - - espree@11.2.0: - dependencies: - acorn: 8.18.0 - acorn-jsx: 5.3.2(acorn@8.18.0) - eslint-visitor-keys: 5.0.1 - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@2.0.2: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.9 - - esutils@2.0.3: {} - - etag@1.8.1: {} - - event-target-shim@5.0.1: {} - - events-universal@1.0.1: - dependencies: - bare-events: 2.8.3 - transitivePeerDependencies: - - bare-abort-controller - - events@3.3.0: {} - - execa@8.0.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - - exsolve@1.1.1: {} - - fast-deep-equal@3.1.3: {} - - fast-fifo@1.3.2: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-npm-meta@2.2.0: - dependencies: - cac: 7.0.0 - - fast-string-truncated-width@3.0.3: {} - - fast-string-width@3.0.2: - dependencies: - fast-string-truncated-width: 3.0.3 - - fast-wrap-ansi@0.2.0: - dependencies: - fast-string-width: 3.0.2 - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.5): - optionalDependencies: - picomatch: 4.0.5 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - file-uri-to-path@1.0.0: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up-simple@1.0.1: {} - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - find-up@8.0.0: - dependencies: - locate-path: 8.0.0 - unicorn-magic: 0.3.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.4.2 - keyv: 4.5.4 - - flatted@3.4.2: {} - - fnv1a-64@0.1.2: {} - - fontaine@0.8.0: - dependencies: - '@capsizecss/unpack': 4.0.0 - css-tree: 3.2.1 - magic-regexp: 0.10.0 - magic-string: 0.30.21 - pathe: 2.0.3 - ufo: 1.6.4 - unplugin: 2.3.11 - - fontkitten@1.0.3: - dependencies: - tiny-inflate: 1.0.3 - - fontless@0.2.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - consola: 3.4.2 - css-tree: 3.2.1 - defu: 6.1.7 - esbuild: 0.27.7 - fontaine: 0.8.0 - jiti: 2.7.0 - lightningcss: 1.33.0 - magic-string: 0.30.21 - ohash: 2.0.12 - pathe: 2.0.3 - ufo: 1.6.4 - unifont: 0.7.4 - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2)) - optionalDependencies: - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - db0 - - idb-keyval - - ioredis - - uploadthing - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - fraction.js@5.3.4: {} - - framer-motion@13.1.1: - dependencies: - motion-dom: 13.1.1 - motion-utils: 13.0.0 - tslib: 2.8.1 - - fresh@2.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - function-timeout@1.0.2: {} - - fuse.js@7.5.0: {} - - fzf@0.5.2: {} - - generic-names@4.0.0: - dependencies: - loader-utils: 3.3.1 - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-east-asian-width@1.6.0: {} - - get-port-please@3.2.0: {} - - get-stream@8.0.1: {} - - get-tsconfig@4.14.0: - dependencies: - resolve-pkg-maps: 1.0.0 - - giget@3.3.1: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.5.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.9 - minipass: 7.1.3 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - glob@13.0.6: - dependencies: - minimatch: 10.2.5 - minipass: 7.1.3 - path-scurry: 2.0.2 - - global-directory@4.0.1: - dependencies: - ini: 4.1.1 - - globals@17.9.0: {} - - globby@16.2.0: - dependencies: - '@sindresorhus/merge-streams': 4.0.0 - fast-glob: 3.3.3 - ignore: 7.0.6 - is-path-inside: 4.0.0 - slash: 5.1.0 - unicorn-magic: 0.4.0 - - graceful-fs@4.2.11: {} - - gzip-size@7.0.0: - dependencies: - duplexer: 0.1.2 - - h3@1.15.11: - dependencies: - cookie-es: 1.2.3 - crossws: 0.3.5 - defu: 6.1.7 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.4 - radix3: 1.1.2 - ufo: 1.6.4 - uncrypto: 0.1.3 - - h3@2.0.1-rc.26(crossws@0.4.10(srvx@0.11.22)): - dependencies: - rou3: 0.9.1 - srvx: 0.12.4 - optionalDependencies: - crossws: 0.4.10(srvx@0.11.22) - - hasown@2.0.3: - dependencies: - function-bind: 1.1.2 - - hey-listen@1.0.8: {} - - hookable@5.5.3: {} - - hookable@6.1.1: {} - - html-entities@2.6.0: {} - - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 - - http-shutdown@1.2.2: {} - - https-proxy-agent@7.0.6(supports-color@10.2.2): - dependencies: - agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - httpxy@0.5.1: {} - - human-signals@5.0.0: {} - - identifier-regex@1.1.0: - dependencies: - reserved-identifiers: 1.2.0 - - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - ignore@7.0.6: {} - - image-meta@0.2.2: {} - - import-meta-resolve@4.2.0: {} - - impound@1.1.6(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - es-module-lexer: 2.1.0 - pathe: 2.0.3 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-utils: 0.3.2 - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rolldown - - rollup - - unloader - - vite - - webpack - - imurmurhash@0.1.4: {} - - indent-string@5.0.0: {} - - inherits@2.0.4: {} - - ini@4.1.1: {} - - ioredis@5.10.1(supports-color@10.2.2): - dependencies: - '@ioredis/commands': 1.5.1 - cluster-key-slot: 1.1.2 - debug: 4.4.3(supports-color@10.2.2) - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - - iron-webcrypto@1.2.1: {} - - is-builtin-module@5.0.0: - dependencies: - builtin-modules: 5.2.0 - - is-core-module@2.16.2: - dependencies: - hasown: 2.0.3 - - is-docker@3.0.0: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-identifier@1.1.0: - dependencies: - identifier-regex: 1.1.0 - super-regex: 1.1.0 - - is-in-ssh@1.0.0: {} - - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-installed-globally@1.0.0: - dependencies: - global-directory: 4.0.1 - is-path-inside: 4.0.0 - - is-module@1.0.0: {} - - is-number@7.0.0: {} - - is-path-inside@4.0.0: {} - - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.9 - - is-stream@2.0.1: {} - - is-stream@3.0.0: {} - - is-wsl@3.1.1: - dependencies: - is-inside-container: 1.0.0 - - isarray@1.0.0: {} - - isexe@2.0.0: {} - - isexe@4.0.0: {} - - isomorphic.js@0.2.5: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jiti@2.7.0: {} - - js-tokens@10.0.0: {} - - js-tokens@4.0.0: {} - - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 - - jsdoc-type-pratt-parser@7.2.0: {} - - jsdoc-type-pratt-parser@8.0.0: {} - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-schema-to-typescript-lite@15.0.0: - dependencies: - '@apidevtools/json-schema-ref-parser': 14.2.1(@types/json-schema@7.0.15) - '@types/json-schema': 7.0.15 - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@2.2.3: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kleur@4.1.5: {} - - klona@2.0.6: {} - - knitwork@1.3.0: {} - - launch-editor@2.14.1: - dependencies: - picocolors: 1.1.1 - shell-quote: 1.10.0 - - lazystream@1.0.1: - dependencies: - readable-stream: 2.3.8 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lib0@0.2.117: - dependencies: - isomorphic.js: 0.2.5 - - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-android-arm64@1.33.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.33.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.33.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.33.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.33.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.33.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.33.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.33.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.33.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.33.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.33.0: - optional: true - - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - - lightningcss@1.33.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.33.0 - lightningcss-darwin-arm64: 1.33.0 - lightningcss-darwin-x64: 1.33.0 - lightningcss-freebsd-x64: 1.33.0 - lightningcss-linux-arm-gnueabihf: 1.33.0 - lightningcss-linux-arm64-gnu: 1.33.0 - lightningcss-linux-arm64-musl: 1.33.0 - lightningcss-linux-x64-gnu: 1.33.0 - lightningcss-linux-x64-musl: 1.33.0 - lightningcss-win32-arm64-msvc: 1.33.0 - lightningcss-win32-x64-msvc: 1.33.0 - - lilconfig@3.1.3: {} - - linkifyjs@4.3.3: {} - - listhen@1.10.0(srvx@0.11.22): - dependencies: - '@parcel/watcher': 2.5.6 - '@parcel/watcher-wasm': 2.5.6 - citty: 0.2.2 - consola: 3.4.2 - crossws: 0.4.10(srvx@0.11.22) - defu: 6.1.7 - get-port-please: 3.2.0 - h3: 1.15.11 - http-shutdown: 1.2.2 - jiti: 2.7.0 - mlly: 1.8.2 - node-forge: 1.4.0 - pathe: 2.0.3 - std-env: 4.2.0 - tinyclip: 0.1.15 - ufo: 1.6.4 - untun: 0.1.3 - uqr: 0.1.3 - transitivePeerDependencies: - - srvx - - loader-utils@3.3.1: {} - - local-pkg@1.2.1: - dependencies: - mlly: 1.8.2 - pkg-types: 2.3.1 - quansync: 0.2.11 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - locate-path@8.0.0: - dependencies: - p-locate: 6.0.0 - - lodash.defaults@4.2.0: {} - - lodash.isarguments@3.1.0: {} - - lodash@4.18.1: {} - - lru-cache@10.4.3: {} - - lru-cache@11.4.0: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - magic-regexp@0.10.0: - dependencies: - estree-walker: 3.0.3 - magic-string: 0.30.21 - mlly: 1.8.2 - regexp-tree: 0.1.27 - type-level-regexp: 0.1.17 - ufo: 1.6.4 - unplugin: 2.3.11 - - magic-string-ast@1.0.3: - dependencies: - magic-string: 0.30.21 - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - magic-string@1.2.2: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - magicast@0.5.4: - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - source-map-js: 1.2.1 - - make-asynchronous@1.1.0: - dependencies: - p-event: 6.0.1 - type-fest: 4.41.0 - web-worker: 1.5.0 - - marked@17.0.6: {} - - mdn-data@2.0.28: {} - - mdn-data@2.27.1: {} - - mdn-data@2.29.0: {} - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.2 - - mime-db@1.54.0: {} - - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - - mime@4.1.0: {} - - mimic-fn@4.0.0: {} - - minimatch@10.2.5: - dependencies: - brace-expansion: 5.0.6 - - minimatch@5.1.9: - dependencies: - brace-expansion: 2.1.0 - - minimatch@9.0.9: - dependencies: - brace-expansion: 2.1.0 - - minipass@7.1.3: {} - - minizlib@3.1.0: - dependencies: - minipass: 7.1.3 - - mlly@1.8.2: - dependencies: - acorn: 8.18.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.4 - - mocked-exports@0.1.1: {} - - motion-dom@13.1.1: - dependencies: - motion-utils: 13.0.0 - - motion-utils@13.0.0: {} - - motion-v@2.4.0(@vueuse/core@14.4.0(vue@3.5.40(typescript@6.0.3)))(vue@3.5.40(typescript@6.0.3)): - dependencies: - '@vueuse/core': 14.4.0(vue@3.5.40(typescript@6.0.3)) - framer-motion: 13.1.1 - hey-listen: 1.0.8 - motion-dom: 13.1.1 - motion-utils: 13.0.0 - vue: 3.5.40(typescript@6.0.3) - transitivePeerDependencies: - - react - - react-dom - - mrmime@2.0.1: {} - - ms@2.1.3: {} - - muggle-string@0.4.1: {} - - nanoid@3.3.16: {} - - nanotar@0.3.0: {} - - napi-postinstall@0.3.4: {} - - natural-compare@1.4.0: {} - - nitropack@2.13.4(oxc-parser@0.140.0)(rolldown@1.2.1)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - '@cloudflare/kv-asset-handler': 0.4.2 - '@rollup/plugin-alias': 6.0.0(rollup@4.60.4) - '@rollup/plugin-commonjs': 29.0.2(rollup@4.60.4) - '@rollup/plugin-inject': 5.0.5(rollup@4.60.4) - '@rollup/plugin-json': 6.1.0(rollup@4.60.4) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.4) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) - '@rollup/plugin-terser': 1.0.0(rollup@4.60.4) - '@vercel/nft': 1.5.0(rollup@4.60.4)(supports-color@10.2.2) - archiver: 7.0.1 - c12: 3.3.4(magicast@0.5.4) - chokidar: 5.0.0 - citty: 0.2.2 - compatx: 0.2.0 - confbox: 0.2.4 - consola: 3.4.2 - cookie-es: 2.0.1 - croner: 10.0.1 - crossws: 0.3.5 - db0: 0.3.4 - defu: 6.1.7 - destr: 2.0.5 - dot-prop: 10.1.0 - esbuild: 0.28.0 - escape-string-regexp: 5.0.0 - etag: 1.8.1 - exsolve: 1.1.1 - globby: 16.2.0 - gzip-size: 7.0.0 - h3: 1.15.11 - hookable: 5.5.3 - httpxy: 0.5.1 - ioredis: 5.10.1(supports-color@10.2.2) - jiti: 2.7.0 - klona: 2.0.6 - knitwork: 1.3.0 - listhen: 1.10.0(srvx@0.11.22) - magic-string: 0.30.21 - magicast: 0.5.4 - mime: 4.1.0 - mlly: 1.8.2 - node-fetch-native: 1.6.7 - node-mock-http: 1.0.4 - ofetch: 1.5.1 - ohash: 2.0.12 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.1 - pretty-bytes: 7.1.0 - radix3: 1.1.2 - rollup: 4.60.4 - rollup-plugin-visualizer: 7.0.1(rolldown@1.2.1)(rollup@4.60.4) - scule: 1.3.0 - semver: 7.8.5 - serve-placeholder: 2.0.2 - serve-static: 2.2.1(supports-color@10.2.2) - source-map: 0.7.6 - std-env: 4.2.0 - ufo: 1.6.4 - ultrahtml: 1.7.0 - uncrypto: 0.1.3 - unctx: 2.5.0 - unenv: 2.0.0-rc.24 - unimport: 6.4.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-utils: 0.3.2 - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2)) - untyped: 2.0.0 - unwasm: 0.5.3 - youch: 4.1.1 - youch-core: 0.3.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@farmfe/core' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@rspack/core' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bare-abort-controller - - bare-buffer - - better-sqlite3 - - bun-types-no-globals - - drizzle-orm - - encoding - - idb-keyval - - mysql2 - - oxc-parser - - react-native-b4a - - rolldown - - sqlite3 - - srvx - - supports-color - - unloader - - uploadthing - - vite - - webpack - - node-addon-api@7.1.1: {} - - node-fetch-native@1.6.7: {} - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-forge@1.4.0: {} - - node-gyp-build@4.8.4: {} - - node-mock-http@1.0.4: {} - - node-releases@2.0.51: {} - - nopt@8.1.0: - dependencies: - abbrev: 3.0.1 - - normalize-path@3.0.0: {} - - nostics@1.2.0: {} - - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - - npm-run-path@6.0.0: - dependencies: - path-key: 4.0.0 - unicorn-magic: 0.3.0 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - nuxt@4.5.2(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@oxc-project/types@0.142.0)(@parcel/watcher@2.5.6)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(@vue/compiler-sfc@3.5.40)(cac@7.0.0)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.33.0)(magicast@0.5.4)(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.1)(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue-tsc@3.3.11(typescript@6.0.3))(yaml@2.9.0): - dependencies: - '@dxup/nuxt': 0.5.6(esbuild@0.28.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - '@nuxt/cli': 3.37.0(@nuxt/schema@4.5.2)(cac@7.0.0)(magicast@0.5.4)(supports-color@10.2.2) - '@nuxt/devtools': 3.4.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.2.2)(oxc-parser@0.140.0)(rolldown@1.2.1)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@nuxt/nitro-server': 4.5.2(1faf410aca872ebb6f154eab8d23cc95) - '@nuxt/schema': 4.5.2 - '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))) - '@nuxt/vite-builder': 4.5.2(521f6102c765bb8970dc9d69c7b33187) - '@unhead/vue': 3.4.0(@oxc-project/types@0.142.0)(@vitejs/devtools-kit@0.4.10(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(esbuild@0.28.0)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@vue/shared': 3.5.40 - chokidar: 5.0.0 - compatx: 0.2.0 - consola: 3.4.2 - cookie-es: 3.1.1 - defu: 6.1.7 - devalue: 5.9.0 - errx: 0.1.2 - escape-string-regexp: 5.0.0 - exsolve: 1.1.1 - fnv1a-64: 0.1.2 - hookable: 6.1.1 - ignore: 7.0.6 - impound: 1.1.6(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - jiti: 2.7.0 - klona: 2.0.6 - knitwork: 1.3.0 - magic-string: 1.2.2 - mlly: 1.8.2 - nanotar: 0.3.0 - nostics: 1.2.0 - nypm: 0.6.9 - object-identity: 0.2.3 - ofetch: 1.5.1 - ohash: 2.0.12 - on-change: 6.0.2 - oxc-walker: 1.1.1(@oxc-project/types@0.142.0)(oxc-parser@0.140.0)(rolldown@1.2.1) - pathe: 2.0.3 - perfect-debounce: 2.1.0 - picomatch: 4.0.5 - pkg-types: 2.3.1 - rolldown: 1.2.1 - rolldown-string: 0.3.1(rolldown@1.2.1) - rou3: 0.9.1 - scule: 1.3.0 - std-env: 4.2.0 - tinyglobby: 0.2.17 - ufo: 1.6.4 - ultrahtml: 1.7.0 - uncrypto: 0.1.3 - unctx: 3.0.0(magic-string@1.2.2)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - undici: 8.10.0 - unhead: 3.4.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unimport: 6.4.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unrouting: 0.2.2 - untyped: 2.0.0 - verkit: 0.3.2 - vue: 3.5.40(typescript@6.0.3) - vue-component-type-helpers: 3.3.11 - vue-router: 5.2.0(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - optionalDependencies: - '@parcel/watcher': 2.5.6 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@babel/plugin-proposal-decorators' - - '@babel/plugin-syntax-jsx' - - '@babel/plugin-syntax-typescript' - - '@biomejs/biome' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@farmfe/core' - - '@libsql/client' - - '@netlify/blobs' - - '@oxc-project/types' - - '@pinia/colada' - - '@planetscale/database' - - '@rollup/plugin-babel' - - '@rspack/core' - - '@unhead/cli' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@vitejs/devtools' - - '@vitejs/devtools-kit' - - '@vue/compiler-sfc' - - aws4fetch - - bare-abort-controller - - bare-buffer - - better-sqlite3 - - bufferutil - - bun-types-no-globals - - cac - - commander - - db0 - - drizzle-orm - - encoding - - esbuild - - eslint - - idb-keyval - - ioredis - - less - - lightningcss - - magicast - - meow - - mysql2 - - optionator - - oxc-parser - - oxlint - - pinia - - react-native-b4a - - rollup - - rollup-plugin-visualizer - - sass - - sass-embedded - - sqlite3 - - srvx - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - unloader - - uploadthing - - utf-8-validate - - vite - - vue-tsc - - webpack - - xml2js - - yaml - - nypm@0.6.9: - dependencies: - citty: 0.2.2 - pathe: 2.0.3 - tinyexec: 1.2.4 - - object-deep-merge@2.0.1: {} - - object-identity@0.2.3: {} - - obug@2.1.1: {} - - ofetch@1.5.1: - dependencies: - destr: 2.0.5 - node-fetch-native: 1.6.7 - ufo: 1.6.4 - - ofetch@2.0.0-alpha.3: {} - - ohash@2.0.12: {} - - on-change@6.0.2: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - - open@11.0.0: - dependencies: - default-browser: 5.5.0 - define-lazy-prop: 3.0.0 - is-in-ssh: 1.0.0 - is-inside-container: 1.0.0 - powershell-utils: 0.1.0 - wsl-utils: 0.3.1 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - orderedmap@2.1.1: {} - - oxc-parser@0.140.0: - dependencies: - '@oxc-project/types': 0.140.0 - optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.140.0 - '@oxc-parser/binding-android-arm64': 0.140.0 - '@oxc-parser/binding-darwin-arm64': 0.140.0 - '@oxc-parser/binding-darwin-x64': 0.140.0 - '@oxc-parser/binding-freebsd-x64': 0.140.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.140.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.140.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.140.0 - '@oxc-parser/binding-linux-arm64-musl': 0.140.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.140.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.140.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.140.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.140.0 - '@oxc-parser/binding-linux-x64-gnu': 0.140.0 - '@oxc-parser/binding-linux-x64-musl': 0.140.0 - '@oxc-parser/binding-openharmony-arm64': 0.140.0 - '@oxc-parser/binding-wasm32-wasi': 0.140.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.140.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.140.0 - '@oxc-parser/binding-win32-x64-msvc': 0.140.0 - optional: true - - oxc-walker@1.1.1(@oxc-project/types@0.142.0)(oxc-parser@0.140.0)(rolldown@1.2.1): - optionalDependencies: - '@oxc-project/types': 0.142.0 - oxc-parser: 0.140.0 - rolldown: 1.2.1 - - p-event@6.0.1: - dependencies: - p-timeout: 6.1.4 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-limit@4.0.0: - dependencies: - yocto-queue: 1.2.2 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-locate@6.0.0: - dependencies: - p-limit: 4.0.0 - - p-timeout@6.1.4: {} - - package-json-from-dist@1.0.1: {} - - package-manager-detector@1.8.0: {} - - parse-imports-exports@0.2.4: - dependencies: - parse-statements: 1.0.11 - - parse-statements@1.0.11: {} - - parseurl@1.3.3: {} - - path-browserify@1.0.1: {} - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.3 - - path-scurry@2.0.2: - dependencies: - lru-cache: 11.4.0 - minipass: 7.1.3 - - pathe@1.1.2: {} - - pathe@2.0.3: {} - - perfect-debounce@2.1.0: {} - - picocolors@1.1.1: {} - - picomatch@2.3.2: {} - - picomatch@4.0.5: {} - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - - pkg-types@2.3.1: - dependencies: - confbox: 0.2.4 - exsolve: 1.1.1 - pathe: 2.0.3 - - pluralize@8.0.0: {} - - postcss-calc@10.1.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-selector-parser: 7.1.4 - postcss-value-parser: 4.2.0 - - postcss-colormin@8.0.1(postcss@8.5.25): - dependencies: - '@colordx/core': 5.4.3 - browserslist: 4.28.7 - caniuse-api: 4.0.0 - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-convert-values@8.0.1(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-discard-comments@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-selector-parser: 7.1.4 - - postcss-discard-duplicates@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - - postcss-discard-empty@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - - postcss-discard-overridden@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - - postcss-merge-longhand@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - stylehacks: 8.0.1(postcss@8.5.25) - - postcss-merge-rules@8.0.1(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - caniuse-api: 4.0.0 - cssnano-utils: 6.0.1(postcss@8.5.25) - postcss: 8.5.25 - postcss-selector-parser: 7.1.4 - - postcss-minify-font-values@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-minify-gradients@8.0.1(postcss@8.5.25): - dependencies: - '@colordx/core': 5.4.3 - cssnano-utils: 6.0.1(postcss@8.5.25) - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-minify-params@8.0.1(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - cssnano-utils: 6.0.1(postcss@8.5.25) - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-minify-selectors@8.0.2(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - caniuse-api: 4.0.0 - cssesc: 3.0.0 - postcss: 8.5.25 - postcss-selector-parser: 7.1.4 - - postcss-normalize-charset@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - - postcss-normalize-display-values@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-positions@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-repeat-style@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-string@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-timing-functions@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-unicode@8.0.1(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-url@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-normalize-whitespace@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-ordered-values@8.0.1(postcss@8.5.25): - dependencies: - cssnano-utils: 6.0.1(postcss@8.5.25) - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-reduce-initial@8.0.1(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - caniuse-api: 4.0.0 - postcss: 8.5.25 - - postcss-reduce-transforms@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - - postcss-selector-parser@7.1.4: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-svgo@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-value-parser: 4.2.0 - svgo: 4.0.1 - - postcss-unique-selectors@8.0.1(postcss@8.5.25): - dependencies: - postcss: 8.5.25 - postcss-selector-parser: 7.1.4 - - postcss-value-parser@4.2.0: {} - - postcss@8.5.25: - dependencies: - nanoid: 3.3.16 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - powershell-utils@0.1.0: {} - - prelude-ls@1.2.1: {} - - pretty-bytes@7.1.0: {} - - process-nextick-args@2.0.1: {} - - process@0.11.10: {} - - proper-lockfile@4.1.2: - dependencies: - graceful-fs: 4.2.11 - retry: 0.12.0 - signal-exit: 3.0.7 - - prosemirror-changeset@2.4.1: - dependencies: - prosemirror-transform: 1.12.0 - - prosemirror-commands@1.7.1: - dependencies: - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - - prosemirror-dropcursor@1.8.2: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 - - prosemirror-gapcursor@1.4.1: - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.8 - - prosemirror-history@1.5.0: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 - rope-sequence: 1.3.4 - - prosemirror-inputrules@1.5.1: - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - - prosemirror-keymap@1.2.3: - dependencies: - prosemirror-state: 1.4.4 - w3c-keyname: 2.2.8 - - prosemirror-model@1.25.7: - dependencies: - orderedmap: 2.1.1 - - prosemirror-schema-list@1.5.1: - dependencies: - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - - prosemirror-state@1.4.4: - dependencies: - prosemirror-model: 1.25.7 - prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 - - prosemirror-tables@1.8.5: - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - prosemirror-view: 1.41.8 - - prosemirror-transform@1.12.0: - dependencies: - prosemirror-model: 1.25.7 - - prosemirror-view@1.41.8: - dependencies: - prosemirror-model: 1.25.7 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.12.0 - - punycode@2.3.1: {} - - quansync@0.2.11: {} - - queue-microtask@1.2.3: {} - - quote-js-string@0.1.0: {} - - radix3@1.1.2: {} - - range-parser@1.2.1: {} - - rc9@3.0.1: - dependencies: - defu: 6.1.7 - destr: 2.0.5 - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@4.7.0: - dependencies: - abort-controller: 3.0.0 - buffer: 6.0.3 - events: 3.3.0 - process: 0.11.10 - string_decoder: 1.3.0 - - readdir-glob@1.1.3: - dependencies: - minimatch: 5.1.9 - - readdirp@5.0.0: {} - - redis-errors@1.2.0: {} - - redis-parser@3.0.0: - dependencies: - redis-errors: 1.2.0 - - refa@0.12.1: - dependencies: - '@eslint-community/regexpp': 4.12.2 - - regexp-ast-analysis@0.7.1: - dependencies: - '@eslint-community/regexpp': 4.12.2 - refa: 0.12.1 - - regexp-tree@0.1.27: {} - - regjsparser@0.13.2: - dependencies: - jsesc: 3.1.0 - - reka-ui@2.10.3(vue@3.5.40(typescript@6.0.3)): - dependencies: - '@floating-ui/dom': 1.8.0 - '@floating-ui/vue': 1.1.11(vue@3.5.40(typescript@6.0.3)) - '@internationalized/date': 3.12.1 - '@internationalized/number': 3.6.6 - '@tanstack/vue-virtual': 3.13.36(vue@3.5.40(typescript@6.0.3)) - '@vueuse/core': 14.4.0(vue@3.5.40(typescript@6.0.3)) - '@vueuse/shared': 14.4.0(vue@3.5.40(typescript@6.0.3)) - aria-hidden: 1.2.6 - defu: 6.1.7 - ohash: 2.0.12 - vue: 3.5.40(typescript@6.0.3) - transitivePeerDependencies: - - '@vue/composition-api' - - reserved-identifiers@1.2.0: {} - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve@1.22.12: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - retry@0.12.0: {} - - reusify@1.1.0: {} - - rolldown-string@0.3.1(rolldown@1.2.1): - dependencies: - magic-string: 1.2.2 - optionalDependencies: - rolldown: 1.2.1 - - rolldown@1.2.1: - dependencies: - '@oxc-project/types': 0.142.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.1 - '@rolldown/binding-darwin-arm64': 1.2.1 - '@rolldown/binding-darwin-x64': 1.2.1 - '@rolldown/binding-freebsd-x64': 1.2.1 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.1 - '@rolldown/binding-linux-arm64-gnu': 1.2.1 - '@rolldown/binding-linux-arm64-musl': 1.2.1 - '@rolldown/binding-linux-ppc64-gnu': 1.2.1 - '@rolldown/binding-linux-s390x-gnu': 1.2.1 - '@rolldown/binding-linux-x64-gnu': 1.2.1 - '@rolldown/binding-linux-x64-musl': 1.2.1 - '@rolldown/binding-openharmony-arm64': 1.2.1 - '@rolldown/binding-wasm32-wasi': 1.2.1 - '@rolldown/binding-win32-arm64-msvc': 1.2.1 - '@rolldown/binding-win32-x64-msvc': 1.2.1 - - rollup-plugin-visualizer@7.0.1(rolldown@1.2.1)(rollup@4.60.4): - dependencies: - open: 11.0.0 - picomatch: 4.0.5 - source-map: 0.7.6 - yargs: 18.0.0 - optionalDependencies: - rolldown: 1.2.1 - rollup: 4.60.4 - - rollup@4.60.4: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 - fsevents: 2.3.3 - - rope-sequence@1.3.4: {} - - rou3@0.9.1: {} - - run-applescript@7.1.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - sax@1.6.0: {} - - scslre@0.3.0: - dependencies: - '@eslint-community/regexpp': 4.12.2 - refa: 0.12.1 - regexp-ast-analysis: 0.7.1 - - scule@1.3.0: {} - - semver@6.3.1: {} - - semver@7.8.5: {} - - send@1.2.1(supports-color@10.2.2): - dependencies: - debug: 4.4.3(supports-color@10.2.2) - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serialize-javascript@7.0.5: {} - - seroval@1.6.2: {} - - serve-placeholder@2.0.2: - dependencies: - defu: 6.1.7 - - serve-static@2.2.1(supports-color@10.2.2): - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - setprototypeof@1.2.0: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - shell-quote@1.10.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - simple-git@3.36.0(supports-color@10.2.2): - dependencies: - '@kwsites/file-exists': 1.1.1(supports-color@10.2.2) - '@kwsites/promise-deferred': 1.1.1 - '@simple-git/args-pathspec': 1.0.3 - '@simple-git/argv-parser': 1.1.1 - debug: 4.4.3(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - sirv@3.0.2: - dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - sisteransi@1.0.5: {} - - slash@5.1.0: {} - - smob@1.6.2: {} - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - source-map@0.7.6: {} - - spdx-exceptions@2.5.0: {} - - spdx-expression-parse@5.0.0: - dependencies: - spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.23 - - spdx-license-ids@3.0.23: {} - - srvx@0.11.22: {} - - srvx@0.12.4: {} - - stable-hash-x@0.2.0: {} - - standard-as-callback@2.1.0: {} - - statuses@2.0.2: {} - - std-env@4.2.0: {} - - streamx@2.25.0: - dependencies: - events-universal: 1.0.1 - fast-fifo: 1.3.2 - text-decoder: 1.2.7 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.2.0 - - string-width@7.2.0: - dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 - strip-ansi: 7.2.0 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.2.0: - dependencies: - ansi-regex: 6.2.2 - - strip-final-newline@3.0.0: {} - - strip-indent@4.1.1: {} - - strip-literal@4.0.0: - dependencies: - js-tokens: 10.0.0 - - structured-clone-es@2.0.1: {} - - stylehacks@8.0.1(postcss@8.5.25): - dependencies: - browserslist: 4.28.7 - postcss: 8.5.25 - postcss-selector-parser: 7.1.4 - - super-regex@1.1.0: - dependencies: - function-timeout: 1.0.2 - make-asynchronous: 1.1.0 - time-span: 5.1.0 - - supports-color@10.2.2: {} - - supports-preserve-symlinks-flag@1.0.0: {} - - svgo@4.0.1: - dependencies: - commander: 11.1.0 - css-select: 5.2.2 - css-tree: 3.2.1 - css-what: 6.2.2 - csso: 5.0.5 - picocolors: 1.1.1 - sax: 1.6.0 - - tagged-tag@1.0.0: {} - - tailwind-merge@3.6.0: {} - - tailwind-variants@3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.3): - dependencies: - tailwindcss: 4.3.3 - optionalDependencies: - tailwind-merge: 3.6.0 - - tailwindcss@4.3.3: {} - - tapable@2.3.3: {} - - tar-stream@3.2.0: - dependencies: - b4a: 1.8.1 - bare-fs: 4.7.1 - fast-fifo: 1.3.2 - streamx: 2.25.0 - transitivePeerDependencies: - - bare-abort-controller - - bare-buffer - - react-native-b4a - - tar@7.5.15: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.3 - minizlib: 3.1.0 - yallist: 5.0.0 - - teex@1.0.1: - dependencies: - streamx: 2.25.0 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - terser@5.47.1: - dependencies: - '@jridgewell/source-map': 0.3.11 - acorn: 8.18.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - text-decoder@1.2.7: - dependencies: - b4a: 1.8.1 - transitivePeerDependencies: - - react-native-b4a - - time-span@5.1.0: - dependencies: - convert-hrtime: 5.0.0 - - tiny-inflate@1.0.3: {} - - tiny-invariant@1.3.3: {} - - tinyclip@0.1.15: {} - - tinyexec@1.2.4: {} - - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - to-valid-identifier@1.0.0: - dependencies: - '@sindresorhus/base62': 1.0.0 - reserved-identifiers: 1.2.0 - - toidentifier@1.0.1: {} - - totalist@3.0.1: {} - - tr46@0.0.3: {} - - ts-api-utils@2.5.0(typescript@6.0.3): - dependencies: - typescript: 6.0.3 - - tslib@2.8.1: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@4.41.0: {} - - type-fest@5.6.0: - dependencies: - tagged-tag: 1.0.0 - - type-level-regexp@0.1.17: {} - - typescript@6.0.3: {} - - ufo@1.6.4: {} - - ultrahtml@1.7.0: {} - - uncrypto@0.1.3: {} - - unctx@2.5.0: - dependencies: - acorn: 8.18.0 - estree-walker: 3.0.3 - magic-string: 0.30.21 - unplugin: 2.3.11 - - unctx@3.0.0(magic-string@1.2.2)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))): - optionalDependencies: - magic-string: 1.2.2 - oxc-parser: 0.140.0 - rolldown: 1.2.1 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - - undici@8.10.0: {} - - unenv@2.0.0-rc.24: - dependencies: - pathe: 2.0.3 - - unhead@3.4.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - hookable: 6.1.1 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - optionalDependencies: - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rolldown - - rollup - - unloader - - webpack - - unicorn-magic@0.3.0: {} - - unicorn-magic@0.4.0: {} - - unifont@0.7.4: - dependencies: - css-tree: 3.2.1 - ofetch: 1.5.1 - ohash: 2.0.12 - - unimport@6.4.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - acorn: 8.18.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - local-pkg: 1.2.1 - magic-string: 1.2.2 - mlly: 1.8.2 - pathe: 2.0.3 - picomatch: 4.0.5 - pkg-types: 2.3.1 - scule: 1.3.0 - strip-literal: 4.0.0 - tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-utils: 0.3.2 - optionalDependencies: - oxc-parser: 0.140.0 - rolldown: 1.2.1 - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rollup - - unloader - - vite - - webpack - - unplugin-auto-import@21.1.0(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))(@vueuse/core@14.4.0(vue@3.5.40(typescript@6.0.3)))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - local-pkg: 1.2.1 - magic-string: 1.2.2 - picomatch: 4.0.5 - unimport: 6.4.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-utils: 0.3.2 - optionalDependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - '@vueuse/core': 14.4.0(vue@3.5.40(typescript@6.0.3)) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - oxc-parser - - rolldown - - rollup - - unloader - - vite - - webpack - - unplugin-utils@0.3.2: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.5 - - unplugin-vue-components@32.1.0(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)): - dependencies: - chokidar: 5.0.0 - local-pkg: 1.2.1 - magic-string: 0.30.21 - mlly: 1.8.2 - obug: 2.1.1 - picomatch: 4.0.5 - tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-utils: 0.3.2 - vue: 3.5.40(typescript@6.0.3) - optionalDependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rolldown - - rollup - - unloader - - vite - - webpack - - unplugin@2.3.11: - dependencies: - '@jridgewell/remapping': 2.3.5 - acorn: 8.18.0 - picomatch: 4.0.5 - webpack-virtual-modules: 0.6.2 - - unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - '@jridgewell/remapping': 2.3.5 - picomatch: 4.0.5 - webpack-virtual-modules: 0.6.2 - optionalDependencies: - esbuild: 0.28.0 - rolldown: 1.2.1 - rollup: 4.60.4 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - - unrouting@0.2.2: - dependencies: - escape-string-regexp: 5.0.0 - ufo: 1.6.4 - - unrs-resolver@1.12.2: - dependencies: - napi-postinstall: 0.3.4 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.12.2 - '@unrs/resolver-binding-android-arm64': 1.12.2 - '@unrs/resolver-binding-darwin-arm64': 1.12.2 - '@unrs/resolver-binding-darwin-x64': 1.12.2 - '@unrs/resolver-binding-freebsd-x64': 1.12.2 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 - '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 - '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 - '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 - '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 - '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 - '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 - '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 - '@unrs/resolver-binding-linux-x64-musl': 1.12.2 - '@unrs/resolver-binding-openharmony-arm64': 1.12.2 - '@unrs/resolver-binding-wasm32-wasi': 1.12.2 - '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 - '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 - '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 - - unstorage@1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2)): - dependencies: - anymatch: 3.1.3 - chokidar: 5.0.0 - destr: 2.0.5 - h3: 1.15.11 - lru-cache: 11.4.0 - node-fetch-native: 1.6.7 - ofetch: 1.5.1 - ufo: 1.6.4 - optionalDependencies: - db0: 0.3.4 - ioredis: 5.10.1(supports-color@10.2.2) - - untun@0.1.3: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - pathe: 1.1.2 - - untyped@2.0.0: - dependencies: - citty: 0.1.6 - defu: 6.1.7 - jiti: 2.7.0 - knitwork: 1.3.0 - scule: 1.3.0 - - unwasm@0.5.3: - dependencies: - exsolve: 1.1.1 - knitwork: 1.3.0 - magic-string: 0.30.21 - mlly: 1.8.2 - pathe: 2.0.3 - pkg-types: 2.3.1 - - update-browserslist-db@1.2.3(browserslist@4.28.7): - dependencies: - browserslist: 4.28.7 - escalade: 3.2.0 - picocolors: 1.1.1 - - uqr@0.1.3: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - valibot@1.4.2(typescript@6.0.3): - optionalDependencies: - typescript: 6.0.3 - optional: true - - vaul-vue@0.4.1(reka-ui@2.10.3(vue@3.5.40(typescript@6.0.3)))(vue@3.5.40(typescript@6.0.3)): - dependencies: - '@vueuse/core': 10.11.1(vue@3.5.40(typescript@6.0.3)) - reka-ui: 2.10.3(vue@3.5.40(typescript@6.0.3)) - vue: 3.5.40(typescript@6.0.3) - transitivePeerDependencies: - - '@vue/composition-api' - - verkit@0.3.2: {} - - vite-dev-rpc@2.0.0(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - birpc: 4.0.0 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vite-hot-client: 2.2.0(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - - vite-hot-client@2.2.0(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - - vite-node@6.0.0(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0): - dependencies: - cac: 7.0.0 - es-module-lexer: 2.1.0 - obug: 2.1.1 - pathe: 2.0.3 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@types/node' - - '@vitejs/devtools' - - esbuild - - jiti - - less - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - - vite-plugin-checker@0.14.5(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(optionator@0.9.4)(typescript@6.0.3)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue-tsc@3.3.11(typescript@6.0.3)): - dependencies: - '@babel/code-frame': 7.29.7 - chokidar: 5.0.0 - npm-run-path: 6.0.0 - picocolors: 1.1.1 - picomatch: 4.0.5 - proper-lockfile: 4.1.2 - tiny-invariant: 1.3.3 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - optionalDependencies: - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - optionator: 0.9.4 - typescript: 6.0.3 - vue-tsc: 3.3.11(typescript@6.0.3) - - vite-plugin-inspect@11.4.1(@nuxt/kit@4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))))(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)): - dependencies: - ansis: 4.3.1 - error-stack-parser-es: 1.0.5 - obug: 2.1.1 - ohash: 2.0.12 - open: 11.0.0 - perfect-debounce: 2.1.0 - sirv: 3.0.2 - unplugin-utils: 0.3.2 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vite-dev-rpc: 2.0.0(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - optionalDependencies: - '@nuxt/kit': 4.5.2(magic-string@1.2.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.1)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))) - - vite-plugin-vue-tracer@1.4.0(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)): - dependencies: - estree-walker: 3.0.3 - exsolve: 1.1.1 - magic-string: 0.30.21 - pathe: 2.0.3 - source-map-js: 1.2.1 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - vue: 3.5.40(typescript@6.0.3) - - vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0): - dependencies: - lightningcss: 1.33.0 - picomatch: 4.0.5 - postcss: 8.5.25 - rolldown: 1.2.1 - tinyglobby: 0.2.17 - optionalDependencies: - esbuild: 0.28.0 - fsevents: 2.3.3 - jiti: 2.7.0 - terser: 5.47.1 - yaml: 2.9.0 - - vscode-uri@3.1.0: {} - - vue-bundle-renderer@2.3.1: - dependencies: - ufo: 1.6.4 - - vue-component-type-helpers@3.3.11: {} - - vue-demi@0.14.10(vue@3.5.40(typescript@6.0.3)): - dependencies: - vue: 3.5.40(typescript@6.0.3) - - vue-devtools-stub@0.1.0: {} - - vue-eslint-parser@10.4.1(eslint@10.9.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2): - dependencies: - debug: 4.4.3(supports-color@10.2.2) - eslint: 10.9.1(jiti@2.7.0)(supports-color@10.2.2) - eslint-scope: 9.1.2 - eslint-visitor-keys: 5.0.1 - espree: 11.2.0 - esquery: 1.7.0 - semver: 7.8.5 - transitivePeerDependencies: - - supports-color - - vue-router@5.2.0(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)): - dependencies: - '@babel/generator': 8.0.0 - '@vue-macros/common': 3.1.4(vue@3.5.40(typescript@6.0.3)) - '@vue/devtools-api': 8.2.1 - ast-walker-scope: 0.9.0 - chokidar: 5.0.0 - json5: 2.2.3 - local-pkg: 1.2.1 - magic-string: 0.30.21 - mlly: 1.8.2 - muggle-string: 0.4.1 - nostics: 1.2.0 - pathe: 2.0.3 - picomatch: 4.0.5 - scule: 1.3.0 - tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.1)(rollup@4.60.4)(vite@8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) - unplugin-utils: 0.3.2 - vue: 3.5.40(typescript@6.0.3) - yaml: 2.9.0 - optionalDependencies: - '@vue/compiler-sfc': 3.5.40 - vite: 8.2.1(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rolldown - - rollup - - unloader - - webpack - - vue-tsc@3.3.11(typescript@6.0.3): - dependencies: - '@volar/typescript': 2.4.28(typescript@6.0.3) - '@vue/language-core': 3.3.11 - typescript: 6.0.3 - - vue@3.5.40(typescript@6.0.3): - dependencies: - '@vue/compiler-dom': 3.5.40 - '@vue/compiler-sfc': 3.5.40 - '@vue/runtime-dom': 3.5.40 - '@vue/server-renderer': 3.5.40 - '@vue/shared': 3.5.40 - optionalDependencies: - typescript: 6.0.3 - - w3c-keyname@2.2.8: {} - - web-worker@1.5.0: {} - - webidl-conversions@3.0.1: {} - - webpack-virtual-modules@0.6.2: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - wheel-gestures@2.2.48: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - which@6.0.1: - dependencies: - isexe: 4.0.0 - - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 5.1.2 - strip-ansi: 7.2.0 - - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.2.0 - - ws@8.21.3: {} - - wsl-utils@0.3.1: - dependencies: - is-wsl: 3.1.1 - powershell-utils: 0.1.0 - - xml-name-validator@5.0.0: {} - - y-protocols@1.0.7(yjs@13.6.30): - dependencies: - lib0: 0.2.117 - yjs: 13.6.30 - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yallist@5.0.0: {} - - yaml@2.9.0: {} - - yargs-parser@22.0.0: {} - - yargs@18.0.0: - dependencies: - cliui: 9.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - string-width: 7.2.0 - y18n: 5.0.8 - yargs-parser: 22.0.0 - - yjs@13.6.30: - dependencies: - lib0: 0.2.117 - - yocto-queue@0.1.0: {} - - yocto-queue@1.2.2: {} - - youch-core@0.3.3: - dependencies: - '@poppinss/exception': 1.2.3 - error-stack-parser-es: 1.0.5 - - youch@4.1.1: - dependencies: - '@poppinss/colors': 4.1.6 - '@poppinss/dumper': 0.7.0 - '@speed-highlight/core': 1.2.15 - cookie-es: 3.1.1 - youch-core: 0.3.3 - - zigpty@0.2.1: - optional: true - - zip-stream@6.0.1: - dependencies: - archiver-utils: 5.0.2 - compress-commons: 6.0.2 - readable-stream: 4.7.0 - - zod@4.4.3: - optional: true diff --git a/code/link-site/link-nuxt/pnpm-workspace.yaml b/code/link-site/link-nuxt/pnpm-workspace.yaml deleted file mode 100644 index 92640afe..00000000 --- a/code/link-site/link-nuxt/pnpm-workspace.yaml +++ /dev/null @@ -1,6 +0,0 @@ -allowBuilds: - '@parcel/watcher': false - '@tailwindcss/oxide': false - esbuild: false - unrs-resolver: false - vue-demi: false diff --git a/code/link-site/link-nuxt/public/favicon.ico b/code/link-site/link-nuxt/public/favicon.ico deleted file mode 100644 index 18993ad9..00000000 Binary files a/code/link-site/link-nuxt/public/favicon.ico and /dev/null differ diff --git a/code/link-site/link-nuxt/renovate.json b/code/link-site/link-nuxt/renovate.json deleted file mode 100644 index 1342f21a..00000000 --- a/code/link-site/link-nuxt/renovate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["github>nuxt/renovate-config-nuxt"] -} diff --git a/code/link-site/link-nuxt/skills-lock.json b/code/link-site/link-nuxt/skills-lock.json deleted file mode 100644 index 8f4e43e6..00000000 --- a/code/link-site/link-nuxt/skills-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "skills": { - "nuxt-ui": { - "source": "nuxt/ui", - "sourceType": "github", - "skillPath": "skills/nuxt-ui/SKILL.md", - "computedHash": "08c32bda980ee1ba0c520cbfe9c452098391b8011d4b85f6c5b84ad9a00bcec4" - } - } -} diff --git a/code/link-site/link-nuxt/tsconfig.json b/code/link-site/link-nuxt/tsconfig.json deleted file mode 100644 index 103ec507..00000000 --- a/code/link-site/link-nuxt/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // https://nuxt.com/docs/guide/concepts/typescript - "files": [], - "references": [ - { "path": "./.nuxt/tsconfig.app.json" }, - { "path": "./.nuxt/tsconfig.server.json" }, - { "path": "./.nuxt/tsconfig.shared.json" }, - { "path": "./.nuxt/tsconfig.node.json" } - ] -} diff --git a/code/link-site/需求分析.md b/code/link-site/需求分析.md deleted file mode 100644 index a237f455..00000000 --- a/code/link-site/需求分析.md +++ /dev/null @@ -1,210 +0,0 @@ -# 需求分析 — 物流企业连接平台 - -> 状态:需求梳理阶段(v1.0,2026-08-31,按新定位重写) -> 说明:本文档为项目需求基线,后续数据库设计、API 设计、开发排期均以此为基础。 - -## 一、项目定位 - -> **物流行业的 B2B 企业连接平台。** 各物流企业在平台内建立自己的企业空间(主页、关于、文章、服务等),平台提供企业目录、搜索发现、资讯内容和企业间沟通(私信、行业群聊)能力,帮助企业找到彼此、建立联系、开展业务交流。 - -一句话概括:**物流企业目录 + 企业内容社区 + 企业间沟通网络**。 - -关键认知:平台是主角,企业是平台内的成员。企业页面**不是独立官网**,而是平台内的标准化企业空间——产品的核心价值是「连接」(企业越多、越容易找到对方,平台越有价值),而非「建站」。 - -### 1.1 与建站 SaaS 的关系 - -本项目一期**不做**自由建站:企业空间采用固定页面结构的标准化模板,企业只填表单、发内容。块级可视化编辑作为**二期付费增强能力**预留(见 6.2),数据模型上预留页面配置的扩展点。 - -## 二、核心模式 - -```text - 物流连接平台 www.demo.com - │ - ┌───────────┬───────┴───────┬────────────┐ - ↓ ↓ ↓ ↓ - 企业目录 资讯流 搜索 消息(IM) - │ │ │ │ - └─────┬─────┴───────┬───────┘ │ - ↓ ↓ │ - /company/abc /company/xyz ← 企业空间 │ - │ │ │ - └─────────────┴────────────────────┘ - 企业间私信 / 行业群聊 -``` - -- 企业空间是企业对外展示的窗口(模板化主页 + 内容); -- 目录、搜索、资讯流负责「发现」,IM 负责「连接」; -- 平台导航全站常驻,企业空间是平台内的子区域,不是独立网站。 - -## 三、用户角色 - -| 角色 | 说明 | 主要诉求 | -|---|---|---| -| 个人用户 | 注册登录的平台账号,可归属于某企业(成员/管理员)或独立存在 | 浏览、搜索、关注、聊天、(企业成员)维护本企业空间 | -| 企业管理员 | 企业空间的管理者(企业认证通过后获得) | 维护企业信息、发布文章、管理成员、处理消息 | -| 平台管理员 | 平台运营方 | 企业审核认证、内容审核、群组管理、行业数据维护 | -| 访客 / 搜索引擎 | 未登录访问者 | 浏览企业空间与文章;搜索引擎收录 | - -## 四、功能需求 - -### 4.1 企业目录与搜索(流量入口) - -- 企业列表页:按**地区、航线/线路(美线/欧线/东南亚…)、服务类型(海运/空运/陆运/报关/仓储…)、认证状态**等维度筛选与排序; -- 关键词搜索:企业名、服务、线路(二期可扩展文章全文搜索); -- 企业详情卡片:Logo、名称、认证标识、主营线路、服务标签、地区。 - -> 目录的检索维度(线路、服务类型)是物流平台最有价值的检索轴,筛选器的数据模型需要可运营维护(平台管理员维护线路/服务字典)。 - -### 4.2 企业空间(标准化模板) - -固定页面结构,企业通过表单配置内容: - -```text -/company/abc -├── 主页:企业封面、简介、主营服务、优势线路、最新文章 -├── 关于:公司介绍、资质证照、发展历程、团队 -├── 文章:企业发布的资讯/案例(列表 + 详情) -├── 服务:服务项目与线路明细 -└── 联系:联系方式、地址、地图、(登录后)在线沟通入口 -``` - -- 页面结构一期固定,企业只填内容(文字、图片、标签选择); -- 数据模型上为页面配置预留结构化扩展点(JSON 配置字段),二期接入块编辑器时平滑升级; -- 企业空间内导航为页内 tab(非独立导航栏),平台导航全站常驻。 - -### 4.3 用户体系与认证 - -- 个人账号注册/登录(手机号/邮箱); -- 个人可申请绑定企业成为成员,企业管理员可邀请/管理成员与角色; -- **企业认证**:提交营业执照等材料,平台管理员审核;认证通过后获得认证标识并可管理企业空间; -- 个人侧「我的」:个人资料、我的消息、我的企业、浏览/关注记录。 - -### 4.4 企业间交流(IM) - -- **一对一私信**:用户(企业成员)之间的点对点聊天; -- **行业群聊**:按线路/航线/服务主题建群(如「美线交流群」「华南拖车群」),支持平台建群(官方群)与企业用户建群; -- 消息能力:文字、图片(一期);未读提醒、离线消息、消息记录; -- 会话入口:企业空间「在线沟通」按钮、目录卡片、消息中心; -- 内容安全:消息与文章需可审计(平台管理员可依规处置违规内容)。 - -> 结构化询价/报价单(起运地→目的地、柜型、时效)未列入一期,作为后续业务化方向在 6.2 预留。 - -### 4.5 资讯流 - -- 各企业发布文章的聚合流,按时间/标签浏览; -- 文章类型:行业资讯、公司动态、案例分享(可由平台设定分类字典); -- 平台管理员可置顶/推荐文章。 - -### 4.6 SEO(平台级能力) - -- 企业空间页、文章详情页 SSR 渲染,搜索引擎可见完整 HTML; -- 平台自动生成每页 Title/Description/Open Graph;企业名、线路类关键词(如「美线 海运 物流公司」)是天然长尾流量来源; -- `/sitemap.xml` 聚合企业空间与文章页;robots.txt 自动生成。 - -### 4.7 管理端(平台运营后台) - -- 企业管理与认证审核 -- 用户管理 -- 内容(文章)审核与管理 -- 群组管理与违规处置 -- 字典维护:线路/航线、服务类型、文章分类等运营数据 -- 平台数据看板(企业数、活跃、消息量) - -管理端形态:Vue 3 + Vite 独立后台,对接 Spring Boot API。 - -## 五、总体布局与信息架构 - -```text -┌─────────────────────────────────────────┐ -│ 平台导航(全站常驻) │ -│ 首页 / 企业目录 / 资讯 / [搜索框] / 消息 / 我的 │ -├─────────────────────────────────────────┤ -│ │ -│ 当前页面内容 │ -│ · 平台页面:首页、目录、资讯流、搜索结果 │ -│ · 企业空间 /company/abc: │ -│ 企业头部(封面/Logo/名称/认证/关注/沟通) │ -│ 页内 tab:主页 | 关于 | 文章 | 服务 | 联系 │ -│ │ -├─────────────────────────────────────────┤ -│ 平台页脚 │ -└─────────────────────────────────────────┘ -``` - -原则: - -- **一个平台,一套导航**。平台导航不因进入企业空间而消失——访客始终知道自己在哪,搜索、消息入口随时可达; -- 企业空间的「企业头部 + tab 页签」承载企业识别,不做第二套全站导航栏; -- 企业空间主色调等轻量主题可配置,但整体视觉框架与平台一致。 - -## 六、总体技术架构 - -```text - 用户 / 搜索引擎 - │ - www.demo.com - │ - ┌───────┴────────┐ - │ Nuxt 4 │ - │ 企业空间 SSR │ - │ SEO / 目录/资讯 │ - └───────┬────────┘ - │ - API Server(Spring Boot) - │ - ┌───────────────┼───────────────┐ - ↓ ↓ ↓ - Database Redis OSS - │ │ │ - 用户/企业/认证 会话/缓存 图片素材 - 文章/字典数据 IM 在线状态 - │ - IM 服务(WebSocket,Spring 生态内实现或独立网关) - 私信 / 群聊 / 离线消息 / 未读推送 -``` - -| 层 | 技术选型 | 职责 | -|---|---|---| -| 网站端 | Nuxt 4 + Nuxt UI v4(本仓库 `link-nuxt`) | 平台门户、目录、资讯、企业空间 SSR、SEO | -| 管理端 | Vue 3 + Vite | 平台运营后台 | -| API 层 | Spring Boot | 业务接口、认证鉴权、审核流 | -| IM 层 | Spring 生态 WebSocket(或独立网关) | 私信、群聊、消息存储与推送 | -| 数据层 | Database / Redis / OSS | 业务数据、缓存与在线状态、素材 | - -架构要点: - -- 企业空间页面为**运行时 SSR**(数据在库、构建时不可知),部署形态为 Node 服务器或支持 SSR 的运行时; -- IM 与业务 API 分离部署,长连接不占用业务请求线程;消息先落库再推送,保证可靠性与离线消息; -- Redis 承担会话缓存、IM 在线状态、热门目录/文章缓存。 - -## 七、边界与非目标(一期) - -| 事项 | 一期决策 | 说明 | -|---|---|---| -| 可视化建站(块编辑器) | 不做,二期付费增强 | 一期标准化模板 + 表单;数据模型预留 JSON 配置扩展点 | -| 自定义域名 | 不做 | 企业空间始终在平台域名下,无独立域名诉求 | -| 询价/报价单 | 不做,预留 | 私信中先以文字沟通,结构化询价为后续业务化方向 | -| 文章全文搜索 | 不做,预留 | 一期关键词匹配,后续接入搜索引擎(如 ES) | -| 多语言 / 国际化 | 不做 | 视运营需要后置 | - -## 八、建议实施顺序 - -1. **基础链路**:用户/企业数据模型 + 企业空间标准化模板页,跑通 `/company/abc` 的 SSR 渲染; -2. **目录与搜索**:企业列表、筛选器、线路/服务字典; -3. **用户体系**:注册登录、企业认证流、成员角色; -4. **资讯流与文章**:企业发文、聚合流、文章详情 SSR + SEO(sitemap/meta); -5. **IM**:私信 → 群聊 → 离线/未读,独立 WebSocket 服务; -6. **管理端**:审核流、字典维护、数据看板; -7. **二期**:块级可视化编辑器(付费)、结构化询价、全文搜索。 - -## 九、术语表 - -| 术语 | 含义 | -|---|---| -| 企业空间(Company Space) | 企业在平台内的展示空间:主页/关于/文章/服务/联系,URL 为 `/company/{slug}` | -| 企业认证 | 企业提交营业执照等材料、平台审核后获得认证标识与空间管理权 | -| 目录(Directory) | 企业列表与筛选检索,平台的流量入口 | -| 字典 | 平台运营维护的枚举数据:线路/航线、服务类型、文章分类等 | -| IM | 站内即时通讯:一对一私信与行业群聊 | -| 行业群 | 按线路/服务主题组建的群聊,官方或用户创建 | -| SEO 层 | 平台自动为企业空间与文章生成的 meta、sitemap 等收录能力 | diff --git a/code/one-designer/.gitignore b/code/one-designer/.gitignore deleted file mode 100644 index 5e9853a1..00000000 --- a/code/one-designer/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules/ -dist/ -coverage/ -*.tsbuildinfo -.turbo/ -.DS_Store -*.log -.vite/ diff --git a/code/one-designer/.playwright-cli/page-2026-09-20T08-38-59-933Z.yml b/code/one-designer/.playwright-cli/page-2026-09-20T08-38-59-933Z.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/code/one-designer/.playwright-cli/page-2026-09-20T08-39-03-959Z.yml b/code/one-designer/.playwright-cli/page-2026-09-20T08-39-03-959Z.yml deleted file mode 100644 index 031e1e7a..00000000 --- a/code/one-designer/.playwright-cli/page-2026-09-20T08-39-03-959Z.yml +++ /dev/null @@ -1,61 +0,0 @@ -- generic [ref=e3]: - - banner [ref=e4]: - - generic [ref=e5]: Web Report Designer · Demo - - button "🌙 暗色" [ref=e6] [cursor=pointer] - - main [ref=e7]: - - generic [ref=e8]: - - toolbar "工具栏" [ref=e9]: - - generic [ref=e10]: - - button "撤销" [disabled] [ref=e11] - - button "重做" [disabled] [ref=e12] - - generic [ref=e13]: - - button "缩小" [ref=e14] [cursor=pointer]: − - - generic [ref=e15]: 100% - - button "放大" [ref=e16] [cursor=pointer]: + - - button "预览" [ref=e18] [cursor=pointer] - - generic [ref=e19]: - - complementary "工具箱" [ref=e20]: - - generic [ref=e21]: 元素 - - button "文本" [ref=e22] [cursor=pointer] - - button "矩形" [ref=e23] [cursor=pointer] - - generic [ref=e24]: - - generic [ref=e25]: mm - - generic [aria-hidden] [ref=e26]: - - generic [ref=e27]: "0" - - generic [ref=e32]: "20" - - generic [ref=e37]: "40" - - generic [ref=e42]: "60" - - generic [ref=e47]: "80" - - generic [ref=e52]: "100" - - generic [ref=e57]: "120" - - generic [ref=e62]: "140" - - generic [ref=e67]: "160" - - generic [ref=e72]: "180" - - generic [ref=e77]: "200" - - generic [aria-hidden] [ref=e81]: - - generic [ref=e82]: "0" - - generic [ref=e87]: "20" - - generic [ref=e92]: "40" - - generic [ref=e97]: "60" - - generic [ref=e102]: "80" - - generic [ref=e107]: "100" - - generic [ref=e112]: "120" - - generic [ref=e117]: "140" - - generic [ref=e122]: "160" - - generic [ref=e127]: "180" - - generic [ref=e132]: "200" - - generic [ref=e137]: "220" - - generic [ref=e142]: "240" - - generic [ref=e147]: "260" - - generic [ref=e152]: "280" - - generic [ref=e159]: - - generic [ref=e160]: 销售出库单 - - generic [ref=e163]: 客户:示例公司 - - generic [ref=e165]: 日期:2025-01-01 - - generic [ref=e167]: 在左侧工具箱添加元素,点击画布元素可在右侧编辑属性,工具栏支持撤销/重做与缩放。 - - complementary "属性面板" [ref=e169]: - - generic [ref=e170]: 未选中元素 - - status [ref=e171]: - - generic [ref=e172]: 缩放 100% - - generic [ref=e173]: 单位 mm - - generic [ref=e174]: 元素 5 \ No newline at end of file diff --git a/code/one-designer/.playwright-cli/page-2026-09-20T08-40-02-544Z.yml b/code/one-designer/.playwright-cli/page-2026-09-20T08-40-02-544Z.yml deleted file mode 100644 index 75a0b309..00000000 --- a/code/one-designer/.playwright-cli/page-2026-09-20T08-40-02-544Z.yml +++ /dev/null @@ -1,76 +0,0 @@ -- generic [ref=e3]: - - banner [ref=e4]: - - generic [ref=e5]: Web Report Designer · Demo - - button "🌙 暗色" [ref=e6] [cursor=pointer] - - main [ref=e7]: - - generic [ref=e8]: - - toolbar "工具栏" [ref=e9]: - - generic [ref=e10]: - - button "撤销" [active] [ref=e11] [cursor=pointer] - - button "重做" [ref=e12] [cursor=pointer] - - generic [ref=e13]: - - button "缩小" [ref=e14] [cursor=pointer]: − - - generic [ref=e15]: 100% - - button "放大" [ref=e16] [cursor=pointer]: + - - button "预览" [ref=e18] [cursor=pointer] - - generic [ref=e19]: - - complementary "工具箱" [ref=e20]: - - generic [ref=e21]: 元素 - - button "文本" [ref=e22] [cursor=pointer] - - button "矩形" [ref=e23] [cursor=pointer] - - generic [ref=e24]: - - generic [ref=e25]: mm - - generic [aria-hidden] [ref=e26]: - - generic [ref=e27]: "0" - - generic [ref=e32]: "20" - - generic [ref=e37]: "40" - - generic [ref=e42]: "60" - - generic [ref=e47]: "80" - - generic [ref=e52]: "100" - - generic [ref=e57]: "120" - - generic [ref=e62]: "140" - - generic [ref=e67]: "160" - - generic [ref=e72]: "180" - - generic [ref=e77]: "200" - - generic [aria-hidden] [ref=e81]: - - generic [ref=e82]: "0" - - generic [ref=e87]: "20" - - generic [ref=e92]: "40" - - generic [ref=e97]: "60" - - generic [ref=e102]: "80" - - generic [ref=e107]: "100" - - generic [ref=e112]: "120" - - generic [ref=e117]: "140" - - generic [ref=e122]: "160" - - generic [ref=e127]: "180" - - generic [ref=e132]: "200" - - generic [ref=e137]: "220" - - generic [ref=e142]: "240" - - generic [ref=e147]: "260" - - generic [ref=e152]: "280" - - generic [ref=e159]: - - generic [ref=e160]: 销售出库单 - - generic [ref=e163]: 客户:示例公司 - - generic [ref=e165]: 日期:2025-01-01 - - generic [ref=e167]: 在左侧工具箱添加元素,点击画布元素可在右侧编辑属性,工具栏支持撤销/重做与缩放。 - - complementary "属性面板" [ref=e169]: - - generic [ref=e175]: 属性 - - generic [ref=e176]: - - generic [ref=e177]: ID - - generic [ref=e178]: title-1 - - generic [ref=e179]: - - generic [ref=e180]: 类型 - - generic [ref=e181]: text - - generic [ref=e182]: - - generic [ref=e183]: 位置 - - generic [ref=e184]: x23 y13 - - generic [ref=e185]: - - generic [ref=e186]: 尺寸 - - generic [ref=e187]: 120 × 12 - - generic [ref=e188]: - - generic [ref=e189]: 文本 - - textbox "文本" [ref=e190]: 销售出库单 - - status [ref=e171]: - - generic [ref=e172]: 缩放 100% - - generic [ref=e173]: 单位 mm - - generic [ref=e174]: 元素 5 \ No newline at end of file diff --git a/code/one-designer/.playwright-cli/page-2026-09-20T08-47-10-494Z.yml b/code/one-designer/.playwright-cli/page-2026-09-20T08-47-10-494Z.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/code/one-designer/Web Report Designer 初期架构设计方案 V1.md b/code/one-designer/Web Report Designer 初期架构设计方案 V1.md deleted file mode 100644 index 9d560ccf..00000000 --- a/code/one-designer/Web Report Designer 初期架构设计方案 V1.md +++ /dev/null @@ -1,915 +0,0 @@ -# Web Report Designer 初期架构设计方案 V1 - -> 文档状态:初期架构设计 -> -> 本版本目标是先建立稳定的文档模型、布局管线和编辑器边界,不在第一阶段一次性实现所有复杂报表能力。 - -## 1. 项目定位 - -项目暂定名称: - -~~~text -Web Report Designer -~~~ - -包名暂定: - -~~~text -@xxx/report-core -@xxx/report-expression -@xxx/report-layout -@xxx/report-renderer -@xxx/report-designer -@xxx/report-designer-vue -~~~ - -项目定位: - -> 一个面向业务系统的、纯 Web 的、可嵌入、可扩展、插件式的报表设计与渲染平台。 - -重点解决: - -- 固定版式业务报表 -- 打印单据 -- A4/A5/自定义纸张 -- 主表 + 子表 -- 动态明细 -- 多页打印 -- 页眉页脚 -- 基础分组和合计 -- 数据绑定 -- 受限表达式 -- HTML、SVG 和浏览器打印 -- 可扩展的 PDF 输出接口 - -明确不包含: - -~~~text -BI -Dashboard -OLAP -数据分析 -数据立方体 -指标体系 -大屏 -~~~ - -### 1.1 V1 初期范围 - -V1 优先保证以下能力可用: - -1. 文本、图片、线条、矩形等固定元素。 -2. A4、A5 和自定义纸张。 -3. 基础数据绑定和明细表。 -4. 页眉、页脚和基础分页。 -5. HTML、SVG 预览以及浏览器打印。 -6. 文档序列化、校验和版本迁移。 -7. 可注册的元素插件接口。 - -以下能力先预留模型和接口,放到后续迭代: - -- 行列合并、跨页合计的分页级精细控制。 -- 图表、条码、二维码等插件实现。 -- 服务端 PDF 的具体实现。 -- 协同编辑、权限体系和 BI 能力。 - -> 实现进度补充:基础分组(group-header / group-footer、多级分组、组内聚合) -> 已提前完成,详见 §16 阶段 3。 - -## 2. 总体架构 - -整体采用 Monorepo。 - -~~~text -report-designer/ -│ -├── apps/ -│ └── report-designer/ -│ -├── packages/ -│ ├── report-core/ -│ ├── report-expression/ -│ ├── report-layout/ -│ ├── report-renderer/ -│ │ └── src/ -│ │ ├── html/ -│ │ ├── svg/ -│ │ └── pdf/ -│ ├── report-designer/ -│ ├── report-designer-vue/ -│ └── plugins/ -│ ├── qrcode/ -│ ├── barcode/ -│ ├── chart/ -│ └── ... -│ -├── examples/ -├── pnpm-workspace.yaml -├── package.json -└── README.md -~~~ - -### 2.1 依赖方向 - -~~~text -report-expression ──> report-core -report-layout ──> report-core + report-expression -report-renderer ──> report-core + report-layout -report-designer ──> report-core + report-layout -report-designer-vue ──> report-designer -~~~ - -上图箭头表示“依赖”。Core 不依赖上述任何实现包。 - -Renderer 只消费布局结果,不重新计算分页。插件实现可以依赖 Core、Layout、Renderer 或 Designer 的适配器,但 Core 不反向依赖任何具体插件。 - -~~~text -plugin-qrcode -├── core element contract -├── layout adapter -├── renderer adapter -└── designer adapter(可选) -~~~ - -### 2.2 运行时主流程 - -~~~text -ReportDocument - │ - ▼ -数据提供与参数注入 - │ - ▼ -表达式解析与绑定求值 - │ - ▼ -LayoutEngine(测量、展开、换行、分页) - │ - ▼ -LayoutDocument(统一的分页结果) - │ - ├── HTML Renderer - ├── SVG Renderer - └── PDF Renderer -~~~ - -## 3. 核心架构原则 - -### 3.1 Core 与 UI 完全分离 - -report-core: - -~~~text -纯 TypeScript -无 Vue -无 React -无 DOM -无浏览器 API -无 UI 框架 -~~~ - -Core 可以在 Browser、Node.js、Electron、Server 和 CLI 中复用。 - -### 3.2 文档模型与运行时状态分离 - -ReportDocument 只保存可序列化的报表定义,不保存以下编辑器状态: - -- 当前选中项。 -- 缩放比例和画布滚动位置。 -- 辅助线、吸附线和临时选区。 -- 撤销栈和 redo 栈。 -- 已加载的数据和网络连接。 - -### 3.3 Layout 与 Renderer 分离 - -Layout 负责: - -~~~text -尺寸计算 -文本测量 -换行 -表格展开 -动态高度 -分页 -~~~ - -Renderer 负责: - -~~~text -把 LayoutDocument 绘制成 HTML、SVG 或 PDF -~~~ - -这样可以保证不同输出目标使用同一套分页结果。 - -### 3.4 运行时数据由外部注入 - -Core 不负责 fetch、数据库连接或 Token 管理。数据源定义和运行时数据提供器分开,避免把敏感配置写入报表文件。 - -### 3.5 文档必须可校验、可迁移 - -所有文档都必须带 schemaVersion,反序列化时先校验,再按版本逐步迁移。文档 JSON 中不能保存函数、DOM 节点或运行时对象。 - -## 4. 包职责 - -### 4.1 report-core - -- 报表文档模型。 -- 页面、区域、元素和样式模型。 -- 数据源、数据集、参数契约。 -- 插件契约和注册表。 -- 文档创建、克隆、规范化。 -- 序列化、反序列化、校验和迁移。 - -### 4.2 report-expression - -- 表达式词法和语法解析。 -- AST 和受限求值器。 -- 字段、参数、行、分组和页面作用域。 -- 表达式错误和诊断信息。 - -禁止通过 eval 或 new Function 执行任意 JavaScript。 - -### 4.3 report-layout - -- 元素尺寸测量。 -- 文本换行和动态高度。 -- 明细数据展开。 -- 分页和分页诊断。 -- 生成统一的 LayoutDocument。 - -Layout 通过 TextMeasurer、FontResolver 等接口获得环境能力,不直接依赖 DOM。 - -### 4.4 report-renderer - -- 消费 LayoutDocument。 -- 提供 HTML、SVG 和 PDF Renderer。 -- 处理目标格式相关的颜色、字体和资源输出。 - -PDF 的具体实现可以运行在浏览器或 Node/服务端,但必须遵循统一的 Renderer 接口。 - -### 4.5 report-designer - -- 画布和坐标转换。 -- 选择、拖拽、缩放、对齐和吸附。 -- 属性编辑。 -- 复制粘贴。 -- 命令、事务和撤销重做。 -- 快捷键和编辑器状态。 - -Designer 通过 Core 的命令接口修改文档,不直接实现报表业务规则。 - -### 4.6 report-designer-vue - -只负责 Vue 组件、面板和 UI 适配,不向 Core 泄漏 Vue 类型。 - -## 5. report-core 目录 - -~~~text -packages/report-core/ -│ -├── src/ -│ ├── model/ -│ │ ├── report.ts -│ │ ├── page.ts -│ │ ├── section.ts -│ │ ├── element.ts -│ │ ├── table.ts -│ │ ├── style.ts -│ │ ├── dataset.ts -│ │ ├── datasource.ts -│ │ ├── parameter.ts -│ │ └── common.ts -│ │ -│ ├── plugin/ -│ │ ├── plugin.ts -│ │ ├── context.ts -│ │ ├── registry.ts -│ │ ├── element-plugin.ts -│ │ ├── datasource-plugin.ts -│ │ └── exporter-plugin.ts -│ │ -│ ├── document/ -│ │ ├── create.ts -│ │ ├── clone.ts -│ │ └── normalize.ts -│ │ -│ ├── serialization/ -│ │ ├── serialize.ts -│ │ ├── deserialize.ts -│ │ └── migrate.ts -│ │ -│ ├── schema/ -│ │ ├── version.ts -│ │ ├── defaults.ts -│ │ └── validation.ts -│ │ -│ ├── diagnostics/ -│ │ └── diagnostic.ts -│ ├── utils/ -│ │ ├── id.ts -│ │ └── deep.ts -│ └── index.ts -│ -└── tests/ -~~~ - -## 6. Report 文档模型 - -报表采用“文档 + 区域 + 元素树”模型,不把所有元素平铺在根节点上。 - -~~~ts -export interface ReportDocument { - schemaVersion: number - - id: string - name: string - - page: PageSettings - - styles: Record - - dataSources: Record - datasets: Record - parameters: Record - - sections: ReportSection[] - - plugins?: ReportPluginReference[] - metadata?: ReportMetadata -} -~~~ - -### 6.1 报表区域 - -~~~ts -export type ReportSectionKind = - | "report-header" - | "page-header" - | "detail" - | "group-header" - | "group-footer" - | "summary" - | "page-footer" - -export interface ReportSection { - id: string - kind: ReportSectionKind - - datasetId?: string - children: ReportElement[] - - options?: { - repeatOnEachPage?: boolean - keepTogether?: boolean - allowSplit?: boolean - } -} -~~~ - -V1 先实现 page-header、detail 和 page-footer,其他区域只保留模型扩展点。 - -> 实现进度:group-header / group-footer 已可用(含多级分组与组内聚合)。 -> report-header 与 summary 仍只保留模型扩展点。 -> -> 分组区域通过 `groupExpression` 指定分组键,`groupLevel` 指定嵌套级别: -> -> ~~~ts -> export interface ReportSection { -> // ...原有字段 -> /** 分组键表达式,仅 group-header / group-footer 使用。 */ -> groupExpression?: string -> /** 分组级别,从 1 开始;数值小的为外层组。 */ -> groupLevel?: number -> } -> ~~~ -> -> 分组语义为「**相邻行键值相同即同组**」,不改变行顺序—— -> 因此宿主应先按分组键排序再传入数据。组脚可通过 `group` 作用域访问 -> 聚合能力,如 `sum(group.amount)`、`group.count`、`group.key`。 - -### 6.2 元素树 - -~~~ts -export interface ReportElement { - id: string - type: string - - frame: Rect - styleId?: string - - binding?: ValueBinding - props?: Record - children?: ReportElement[] -} - -export interface Rect { - x: number - y: number - width: number - height: number -} - -export interface ValueBinding { - field?: string - expression?: string - format?: string -} -~~~ - -内置元素初期包括: - -~~~text -text -image -line -rect -container -table -~~~ - -插件元素使用自定义 type,并通过插件 Schema 验证 props。 - -### 6.3 明细表 - -明细表是 V1 的特殊元素,负责把数据集展开成多行。单元格内的元素坐标相对于当前单元格。 - -~~~ts -export interface TableElement extends ReportElement { - type: "table" - datasetId: string - columns: TableColumn[] - repeatHeaderOnEachPage?: boolean -} - -export interface TableColumn { - id: string - width: number - header?: string - binding?: ValueBinding - children?: ReportElement[] -} -~~~ - -### 6.4 样式 - -样式通过 ID 复用,并允许有限的继承和元素级覆盖: - -~~~ts -export interface StyleDefinition { - id: string - extends?: string - fontFamily?: string - fontSize?: number - color?: string - background?: string - border?: BorderStyle - align?: "left" | "center" | "right" - verticalAlign?: "top" | "middle" | "bottom" -} -~~~ - -## 7. Page 模型 - -V1 文档内部统一使用 mm,px 只用于 Designer 显示层,pt 只在 PDF 等输出边界转换。 - -~~~ts -export interface PageSettings { - paper: "A4" | "A5" | "custom" - orientation: "portrait" | "landscape" - - customSize?: { - width: number - height: number - } - - margin: PageMargin - background?: string -} - -export interface PageMargin { - top: number - right: number - bottom: number - left: number -} -~~~ - -paper 和 orientation 是页面配置来源;Layout 阶段将其解析为最终的 width、height。自定义纸张必须提供尺寸,尺寸均以 mm 表示。 - -## 8. 数据和运行时上下文 - -报表文档只保存数据源定义,不保存连接、Token 和本次查询结果。 - -~~~ts -export interface DataSourceDefinition { - id: string - type: string - config?: Record - connectionRef?: string -} - -export interface DatasetDefinition { - id: string - sourceId?: string - fields?: DatasetField[] - query?: string -} - -export interface RenderContext { - data: Record - parameters: Record - locale?: string - timezone?: string -} - -export interface DataProvider { - getDataset( - dataset: DatasetDefinition, - context: RenderContext - ): Promise>> -} -~~~ - -DataProvider 由宿主应用注入,Core 不主动访问网络或数据库。 -config 只保存非敏感的设计配置;连接密码、Token 等敏感信息必须通过 connectionRef 或宿主运行时注入。 - -## 9. Layout 中间结果 - -Layout Engine 接受报表文档和运行时上下文,输出所有 Renderer 共用的分页结果。 - -~~~ts -export interface LayoutOptions { - dataProvider?: DataProvider - textMeasurer: TextMeasurer - fontResolver: FontResolver -} - -export interface LayoutEngine { - layout( - document: ReportDocument, - context: RenderContext, - options?: LayoutOptions - ): Promise -} - -export interface LayoutDocument { - pages: LayoutPage[] - diagnostics: LayoutDiagnostic[] -} - -export interface LayoutPage { - width: number - height: number - nodes: LayoutNode[] -} - -export interface LayoutNode { - id: string - type: string - frame: Rect - style: ResolvedStyle - content?: unknown - children?: LayoutNode[] -} -~~~ - -Layout 必须支持以下接口: - -~~~ts -export interface TextMeasurer { - measure(text: string, style: ResolvedStyle): TextMetrics -} - -export interface FontResolver { - resolve(fontFamily: string): ResolvedFont -} -~~~ - -这样可以分别适配浏览器、Node 和服务端字体环境,同时让分页逻辑保持独立。 - -## 10. 表达式约定 - -表达式系统使用受限语法和 AST,不执行任意 JavaScript。 - -V1 至少支持: - -~~~text -字段:row.amount -参数:params.customerName -简单运算:row.price * row.quantity -条件:if(row.amount > 0, "有", "无") -格式化:format(row.date, "YYYY-MM-DD") -~~~ - -表达式失败时返回带有元素 ID 和表达式内容的诊断信息,单个字段错误不应导致整个文档无结果。 - -## 11. 插件模型 - -插件只通过契约接入,不允许 Core 直接导入插件实现。 - -~~~ts -export interface ReportPlugin { - id: string - version: string - elements?: ElementPlugin[] - datasources?: DataSourcePlugin[] - exporters?: ExporterPlugin[] -} - -export interface ElementPlugin { - type: string - schema: unknown - createDefault(): ReportElement -} -~~~ - -需要针对不同运行环境提供可选适配器: - -~~~text -ElementPlugin -├── LayoutAdapter -├── RendererAdapter(html/svg/pdf) -└── DesignerAdapter -~~~ - -插件引用只保存 id、version 和配置。插件缺失时应产生诊断信息,而不是阻止整个文档被读取。 - -## 12. 序列化、校验和迁移 - -- schemaVersion 使用单调递增整数。 -- 反序列化顺序为:解析 JSON → 校验结构 → 执行迁移 → 规范化默认值。 -- 迁移函数按版本逐步执行,不允许跨版本直接修改内部对象。 -- 序列化结果保持稳定排序,便于版本控制和差异比较。 -- 校验错误必须指出字段路径和元素 ID。 - -示例: - -~~~text -deserialize(json) - → validate(json) - → migrate(json, currentVersion) - → normalize(document) -~~~ - -## 13. 诊断和错误处理 - -统一使用诊断对象表达警告和错误: - -~~~ts -export interface Diagnostic { - severity: "info" | "warning" | "error" - code: string - message: string - path?: string - elementId?: string -} -~~~ - -数据缺失、表达式错误、字体缺失、插件缺失和分页失败都应尽量返回可定位的诊断信息。 - -## 14. UI 规范 - -### 14.1 设计目标 - -Designer 的界面采用现代、简洁、干净的工具型产品风格,参考 shadcn/ui 的设计语言,但不要求 Core 或业务应用必须绑定某一个 UI 框架。 - -核心原则: - -- 画布优先,减少非必要装饰。 -- 使用中性背景、细边框和低强度阴影建立层次。 -- 通过间距、字号和颜色层级表达信息,不依赖渐变和大面积高亮。 -- 常用操作保持短路径,复杂配置分组收起。 -- 所有颜色、间距、圆角和阴影使用设计令牌,禁止组件内散落硬编码。 - -### 14.2 UI 层边界 - -- report-core 不包含任何 UI、CSS 或主题代码。 -- report-designer 负责编辑器状态、命令和交互行为。 -- report-designer-vue 负责 Vue 组件、面板和样式实现。 -- 组件采用 Headless 思路,宿主应用可以覆盖主题和品牌色。 -- 可以使用 shadcn-vue 或同类组件实现,但必须通过 report-designer-vue 隔离依赖。 - -### 14.3 整体布局 - -桌面端采用三栏、画布居中的工作区: - -~~~text -┌──────────────────────────────────────────────────────────────┐ -│ 顶部工具栏:文件、撤销、重做、预览、保存、缩放、主题 │ -├──────────────┬───────────────────────────────┬───────────────┤ -│ 左侧工具箱 │ │ 右侧属性面板 │ -│ 元素 / 数据 │ 报表画布 │ 属性 / 样式 │ -│ 模板 / 图层 │ │ 数据绑定 │ -├──────────────┴───────────────────────────────┴───────────────┤ -│ 底部状态栏:页码、缩放、单位、布局诊断、快捷键提示 │ -└──────────────────────────────────────────────────────────────┘ -~~~ - -建议尺寸: - -- 左侧工具箱:240px 左右,可折叠。 -- 右侧属性面板:320px 左右,可折叠。 -- 顶部工具栏:48px。 -- 底部状态栏:28px。 -- 中间画布区域自适应,并支持拖拽调整两侧面板宽度。 - -屏幕宽度小于 900px 时,侧栏改为抽屉或浮层;移动端优先保证预览和基础属性编辑,不强行复刻完整桌面编辑器。 - -### 14.4 设计令牌 - -使用 CSS 自定义属性作为主题契约,至少提供亮色和暗色两套主题: - -~~~css -:root { - --rd-background: 0 0% 100%; - --rd-foreground: 222 47% 11%; - --rd-muted: 210 40% 96%; - --rd-muted-foreground: 215 16% 47%; - --rd-border: 214 32% 91%; - --rd-input: 214 32% 91%; - --rd-primary: 221 83% 53%; - --rd-primary-foreground: 210 40% 98%; - --rd-destructive: 0 72% 51%; - --rd-canvas: 220 14% 96%; - --rd-selection: 221 83% 53%; - --rd-radius: 8px; -} -~~~ - -具体色值可以由宿主应用覆盖,但必须保持以下语义: - -- background:应用和面板背景。 -- canvas:画布工作区背景。 -- foreground:主要文字和图标。 -- muted:次级区域和禁用背景。 -- border:分隔线和输入框边框。 -- primary:主操作、选中态和焦点环。 -- destructive:删除和不可逆操作。 -- selection:画布元素选中框和辅助线。 - -推荐使用 OKLCH 或 HSL 变量,不在组件中直接写十六进制颜色。 - -### 14.5 字体和间距 - -~~~css -font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", - "PingFang SC", "Microsoft YaHei", sans-serif; -~~~ - -推荐字号:12px(辅助信息)、13px(表单和工具栏)、14px(正文)、16px(小标题)、20px(页面标题)。 - -间距使用 4px 基准:4、8、12、16、20、24、32px。默认圆角 6~8px,面板阴影保持低强度,避免卡片堆叠感。 - -### 14.6 基础组件风格 - -基础组件遵循扁平、克制、可聚焦的风格: - -- Button:Primary、Secondary、Ghost、Destructive、Icon 五类。 -- Input、Textarea、Select、Combobox:1px 边框,聚焦时显示明显但克制的 focus ring。 -- Tabs、Segmented Control:用于属性面板和视图切换。 -- Popover、Tooltip、Context Menu、Command Menu:用于低频和快捷操作。 -- Dialog、Toast、Alert:用于确认、反馈和错误提示。 -- Resizable Panel:用于左右侧栏和属性面板。 - -按钮不使用过度圆润的胶囊形,图标按钮必须提供 Tooltip 和可访问名称。删除等危险操作不能只依赖颜色区分。 - -### 14.7 画布规范 - -- 工作区使用浅灰或深灰中性背景,页面使用白色或主题纸张颜色。 -- 页面保持轻微阴影和清晰边界,不使用强烈投影。 -- 元素 Hover 使用低透明度背景,Selected 使用 1px 主色边框和 8 个缩放控制点。 -- 对齐线、吸附线和标尺使用辅助色,不遮挡元素内容。 -- 支持 50%、75%、100%、125%、150%、200% 常用缩放。 -- 画布操作同时支持鼠标、键盘和上下文菜单,不把拖拽作为唯一入口。 -- 选中态、错误态和辅助线不能只通过颜色表达,必要时增加边框、图标或文字提示。 - -### 14.8 属性面板规范 - -- 按“布局、内容、样式、数据绑定、高级”分组。 -- 分组默认折叠低频配置,保留最近使用状态。 -- 数值输入显示单位,支持键盘微调和批量修改。 -- 绑定字段提供字段选择器,同时允许直接输入表达式。 -- 无选中元素时显示页面属性;多选时只显示共同属性。 -- 表单错误就地显示,并关联到对应字段,不使用只在底部出现的泛化错误。 - -### 14.9 交互和状态 - -顶部工具栏至少提供: - -- 新建、打开、保存。 -- 撤销、重做。 -- 预览、打印。 -- 缩放和适应页面。 -- 主题切换和帮助入口。 - -推荐快捷键:Ctrl/Cmd + S 保存、Ctrl/Cmd + Z 撤销、Ctrl/Cmd + Shift + Z 重做、Delete 删除、Ctrl/Cmd + C/V 复制粘贴、Ctrl/Cmd + K 打开命令菜单。 - -所有异步操作都要有 Loading、Empty、Error 和 Disabled 状态;保存成功、布局警告和表达式错误使用统一 Toast 或诊断面板反馈。 - -### 14.10 主题、密度和无障碍 - -- 默认提供 Light 和 Dark 两套主题。 -- 支持 Standard 和 Compact 两种密度,默认 Standard。 -- 颜色对比度目标达到 WCAG AA,正文至少 4.5:1。 -- 所有交互控件支持键盘访问,焦点状态必须可见。 -- 弹窗、抽屉、菜单和属性面板提供正确的 ARIA 语义。 -- 点击目标不小于 32px,主要触控目标建议不小于 36px。 -- 尊重 prefers-reduced-motion,避免非必要动画。 - -### 14.11 UI 验收标准 - -初期 UI 至少应满足: - -1. 用户可以在不阅读文档的情况下找到新增元素、保存、预览和撤销操作。 -2. 画布、工具箱和属性面板在亮色和暗色主题下都能正常使用。 -3. 选中、禁用、错误、加载和空状态具有一致的视觉语言。 -4. 关键操作可以只使用键盘完成。 -5. 主题颜色可以由宿主应用通过 CSS 变量覆盖。 - -## 15. 测试策略 - -初期至少建立以下测试: - -- √ 文档 Schema、默认值和版本迁移测试。 -- √ 固定元素和明细表的布局快照测试。 -- √ 页眉、页脚和多页分页测试。 -- HTML、SVG、PDF Renderer 的公共布局结果一致性测试。 -- √ 表达式安全性、空值和类型转换测试。 -- √ 中文字体、长文本和自定义纸张测试。 -- √ 插件缺失和插件版本不兼容测试。 - -建议准备一个固定的示例报表作为跨包契约测试数据。 - -> 当前测试规模:`report-core` 139 例、`report-expression` 111 例、 -> `report-layout` 124 例、`report-renderer` 12 例、`report-designer` 14 例、 -> `report-designer-vue` 11 例,合计 **411** 例。 -> 字体相关用例依赖系统字体,在缺少字体的环境中自动跳过。 -> HTML/SVG 分页一致性测试已随 Renderer 实现补齐。 - -## 16. 初期实施顺序 - -> 进度标记说明:`√` 表示已实现并有测试覆盖;`◐` 表示部分实现;未标记表示尚未开始。 -> -> 当前进度:阶段 1、2、3 已完成;阶段 4 主体完成(Renderer、Designer 核心、 -> Vue UI 骨架),Vue 层的图层面板、数据绑定面板、快捷键留待后续迭代。 - -### √ 阶段 1:Core 和文档模型 - -- √ 完成 ReportDocument、Section、Element、Page、Style。 -- √ 完成默认值、校验、序列化和迁移。 -- √ 完成基础命令和 ID 生成。 - -产物:`packages/report-core`(139 个测试用例)。 - -### √ 阶段 2:基础 Layout - -- √ 完成单页固定元素布局。 -- √ 完成文本测量、换行和基础分页。 -- √ 输出统一的 LayoutDocument。 - -产物:`packages/report-layout`(含自研 TTF/TTC 字体度量解析)。 - -### √ 阶段 3:数据和明细表 - -- √ 接入 RenderContext 和 DataProvider。 -- √ 支持字段绑定、简单表达式和明细表展开。 -- √ 支持页眉、页脚重复。 - -产物:`packages/report-expression`(83+28 个测试用例)、`packages/report-layout` 的 -数据绑定与分组能力。 - -补充实现(超出本阶段原始列项): - -- √ 受限表达式系统(字段、参数、运算、条件、格式化)。 -- √ 聚合函数(sum / avg / count / min / max)。 -- √ 基础分组(group-header / group-footer、多级分组、组内聚合)。 -- √ 明细表表头每页重复。 - -### ◐ 阶段 4:Renderer 和 Designer - -- √ 实现 SVG、HTML 和浏览器打印(`@report/renderer`,含 HTML/SVG 分页一致性测试)。 -- √ 实现 PDF Renderer 契约(可注入 `PdfBackend`,缺失/报错走诊断)。 -- √ 完成 Designer 的选择、拖拽、属性编辑和撤销重做(`@report/designer`,纯逻辑层)。 -- √ Vue 层 UI 骨架(`@report/designer-vue`,原生 Vue3 + Vite 库模式,无第三方组件库): - 三栏布局壳、画布(渲染/选中/新增)、工具栏(撤销重做/缩放)、属性面板(基础编辑)、 - 状态栏、设计令牌(亮/暗主题 CSS 变量)。 -- 待后续迭代:图层面板、数据绑定面板、拖拽移动、快捷键、预览接入 Renderer。 - -### 阶段 5:插件和 PDF - -- 实现二维码、条码等独立插件。 -- 根据部署环境确定 PDF 的具体后端。 -- 补充字体、资源和输出一致性测试。 - -## 17. V1 验收标准 - -一个示例报表应当能够: - -1. 在 Designer 中创建并保存。 -2. 绑定一组运行时数据。 -3. 生成包含页眉、明细和页脚的多页结果。 -4. 在 HTML 和 SVG 中得到相同的分页结构。 -5. 通过浏览器打印输出。 -6. 在升级 Schema 后仍可被迁移和读取。 - -达到以上标准后,再继续扩展复杂分组、图表、PDF 和更多插件。 diff --git a/code/one-designer/apps/demo/index.html b/code/one-designer/apps/demo/index.html deleted file mode 100644 index d31f7a37..00000000 --- a/code/one-designer/apps/demo/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - 报表设计器 Demo - - -
- - - diff --git a/code/one-designer/apps/demo/package.json b/code/one-designer/apps/demo/package.json deleted file mode 100644 index 2e1d808b..00000000 --- a/code/one-designer/apps/demo/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@report/demo", - "version": "0.0.0", - "private": true, - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "dependencies": { - "@report/core": "workspace:*", - "@report/layout": "workspace:*", - "@report/designer": "workspace:*", - "@report/designer-vue": "workspace:*", - "@report/renderer": "workspace:*", - "vue": "^3.5.13" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "typescript": "^5.7.2", - "vite": "^5.4.11" - } -} diff --git a/code/one-designer/apps/demo/src/App.vue b/code/one-designer/apps/demo/src/App.vue deleted file mode 100644 index dc82d61f..00000000 --- a/code/one-designer/apps/demo/src/App.vue +++ /dev/null @@ -1,144 +0,0 @@ - - - - - diff --git a/code/one-designer/apps/demo/src/main.ts b/code/one-designer/apps/demo/src/main.ts deleted file mode 100644 index b701a8af..00000000 --- a/code/one-designer/apps/demo/src/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createApp } from "vue" -// 组件样式由库构建产出,宿主需显式引入(设计令牌由 injectThemeStyle 注入)。 -import "@report/designer-vue/style.css" -import App from "./App.vue" - -createApp(App).mount("#app") diff --git a/code/one-designer/apps/demo/vite.config.ts b/code/one-designer/apps/demo/vite.config.ts deleted file mode 100644 index 5f28a97f..00000000 --- a/code/one-designer/apps/demo/vite.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { defineConfig } from "vite" -import vue from "@vitejs/plugin-vue" - -export default defineConfig({ - plugins: [vue()], - server: { - port: 5180, - host: "127.0.0.1", - }, -}) diff --git a/code/one-designer/n1.yaml b/code/one-designer/n1.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/code/one-designer/package.json b/code/one-designer/package.json deleted file mode 100644 index 6e9ed5d7..00000000 --- a/code/one-designer/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "report-designer-monorepo", - "version": "0.0.0", - "private": true, - "description": "Web Report Designer —— 面向业务系统的纯 Web、可嵌入、插件式报表设计与渲染平台", - "type": "module", - "packageManager": "pnpm@11.8.0", - "engines": { - "node": ">=20" - }, - "scripts": { - "build": "pnpm -r --workspace-concurrency=1 --filter \"./packages/**\" run build", - "test": "pnpm -r --workspace-concurrency=1 --filter \"./packages/**\" run test", - "typecheck": "pnpm -r --workspace-concurrency=1 --filter \"./packages/**\" run typecheck", - "clean": "pnpm -r exec rm -rf dist .turbo node_modules/.cache" - }, - "devDependencies": { - "typescript": "^5.7.2", - "tsup": "^8.3.5", - "vitest": "^2.1.8", - "@types/node": "^22.10.2" - } -} diff --git a/code/one-designer/packages/report-core/README.md b/code/one-designer/packages/report-core/README.md deleted file mode 100644 index 0385a8fb..00000000 --- a/code/one-designer/packages/report-core/README.md +++ /dev/null @@ -1,203 +0,0 @@ -# @report/core - -报表文档模型、插件契约、校验、序列化与迁移。这是 Web Report Designer 的最底层包。 - -> 对应设计文档 §4.1、§5、§6、§7、§12、§13。 - -## 定位 - -`@report/core` 是**纯 TypeScript** 包:无 Vue / React、无 DOM、无浏览器 API、无 UI 框架。 -因此它可以在 Browser、Node.js、Electron、Server 和 CLI 中复用(架构原则 §3.1)。 - -Core 不依赖任何上层实现包,也不反向依赖任何具体插件。 - -## 安装与使用 - -```bash -pnpm add @report/core -``` - -```ts -import { - createDocument, - serialize, - deserialize, - createEditSession, - createCommand, - resolvePageSize, -} from "@report/core" - -// 新建文档 -const doc = createDocument({ name: "销售单", page: { paper: "A4" } }) - -// 解析纸张尺寸(mm) -const size = resolvePageSize(doc.page) // { width: 210, height: 297 } - -// 序列化(稳定排序,便于版本控制 diff) -const json = serialize(doc, { pretty: true }) - -// 反序列化:parse → validate → migrate → normalize -const result = deserialize(json) -if (result.ok) { - console.log(result.document?.name) -} -console.log(result.diagnostics) -``` - -## 核心概念 - -### 文档模型:文档 → 区域 → 元素树 - -不把所有元素平铺在根节点上。区域(`ReportSection`)有 7 种 `kind`,V1 只实现 -`page-header` / `detail` / `page-footer`,其余保留模型扩展点。 - -### 单位约定 - -文档内部统一使用 **mm**;px 只用于 Designer 显示层,pt 只在 PDF 等输出边界转换(§7)。 -`paper` + `orientation` 是配置来源,由 `resolvePageSize` 在布局阶段解析为最终 width/height。 - -### 纯数据约束 - -`ReportDocument` 只保存可序列化的报表定义,**不保存**编辑器状态(§3.2): -当前选中项、缩放比例、滚动位置、辅助线、撤销栈、已加载数据和网络连接均不得进入文档。 -`serialize` 会在规范化之前先断言纯数据性,混入函数或 DOM 节点会直接抛 `TypeError`。 - -### 诊断而非异常 - -数据缺失、表达式错误、字体缺失、插件缺失、分页失败都通过 `Diagnostic` 表达, -并尽量带上 `path`(JSON Pointer 风格字段路径)与 `elementId`,不中断文档读取(§13)。 - -```ts -import { DIAGNOSTIC_CODES, DiagnosticBag, formatDiagnostic } from "@report/core" - -const bag = new DiagnosticBag() -bag.warn(DIAGNOSTIC_CODES.REF_DANGLING_DATASET, "区域引用了不存在的数据集", { - path: "/sections/1/datasetId", -}) -console.log(bag.all().map(formatDiagnostic)) -``` - -### 序列化与迁移流程(§12) - -``` -deserialize(json) - → parse 解析 JSON - → validate 校验结构 - → migrate 按版本逐步迁移 - → normalize 规范化默认值 -``` - -- `schemaVersion` 使用单调递增整数,当前为 `CURRENT_SCHEMA_VERSION`。 -- 迁移函数**按版本逐步执行**,`planMigrations` 会强制 `to === from + 1`,禁止跨版本跳跃。 -- 序列化结果按键名稳定排序,便于 diff。 -- 版本高于当前支持时**拒绝读取**,避免降级写坏数据。 - -新增 schema 版本时,在 `src/schema/version.ts` 的 `MIGRATIONS` 中追加一项即可。 - -### 命令与撤销重做 - -Designer 通过 Core 的命令接口修改文档,不直接实现报表业务规则(§4.5)。 -**撤销栈属于编辑器状态,不进入文档**(§3.2),因此 `History` 由调用方持有。 - -```ts -import { createCommand, createEditSession } from "@report/core" - -const rename = createCommand<{ name: string }>("rename", (doc, payload) => { - const next = JSON.parse(JSON.stringify(doc)) - next.name = payload.name - return next -}) - -const session = createEditSession(createDocument({ name: "A" })) -session.execute(rename, { name: "B" }) -session.undo() // 回到 "A" -session.redo() // 回到 "B" - -// 事务:多次编辑合并为一步撤销 -session.transaction("批量调整", (s) => { - s.applyWithinTransaction(rename, { name: "C" }) - s.applyWithinTransaction(rename, { name: "D" }) -}) -``` - -撤销采用**快照式**而非反向命令式:文档是纯数据且体量可控,快照成本可接受, -且天然正确处理「一个事务改了多处」的情况。`mergeKey` + `mergeWindow` 用于合并 -拖拽、连续输入这类高频操作。 - -### 插件 - -插件只通过契约接入,Core 不导入任何具体插件实现(§11)。 -插件缺失或版本不兼容只产生诊断,不阻止文档读取。 - -```ts -import { PluginRegistry } from "@report/core" - -const registry = new PluginRegistry() -registry.register({ - id: "plugin-qrcode", - version: "1.2.0", - compatibleSchemaVersion: ">=1.0.0", - elements: [ - { - type: "qrcode", - createDefault: (options) => ({ - id: options?.id ?? "el-1", - type: "qrcode", - frame: options?.frame ?? { x: 0, y: 0, width: 20, height: 20 }, - props: { value: "https://example.com" }, - }), - }, - ], -}) - -// 校验文档时传入插件类型集合,避免误报未知元素类型 -const result = deserialize(json, { pluginElementTypes: registry.elementTypes() }) -``` - -`ElementPlugin.schema` 使用 `unknown` 是有意为之:Core 不绑定任何具体校验库, -宿主可以传 JSON Schema、Zod、Valibot 或自定义描述,由插件适配器负责具体校验。 - -## 目录结构 - -``` -src/ -├── model/ 报表文档模型(report / page / section / element / table / style / …) -├── plugin/ 插件契约与注册表 -├── document/ 创建、克隆、规范化 -├── serialization/ 序列化、反序列化、迁移 -├── schema/ 版本、默认值、校验 -├── command/ 命令、事务、撤销重做 -├── diagnostics/ 统一诊断对象 -├── utils/ ID 生成、深拷贝与对象工具 -└── index.ts 公共出口 -``` - -## 开发 - -```bash -pnpm build # tsup 打包(ESM + CJS + d.ts) -pnpm test # vitest -pnpm typecheck # tsc --noEmit -``` - -## 当前测试覆盖 - -| 测试文件 | 用例数 | 覆盖内容 | -| --- | --- | --- | -| `document.test.ts` | 19 | 创建、规范化、克隆、元素计数 | -| `serialization.test.ts` | 26 | 稳定序列化、往返、迁移链路、容错读取 | -| `validation.test.ts` | 34 | 结构校验、引用完整性、样式环、插件类型 | -| `command.test.ts` | 35 | 命令、合并、事务、撤销重做 | -| `plugin.test.ts` | 25 | 注册、冲突、版本兼容、缺失诊断 | - -合计 **139** 个用例。 - -## V1 范围内尚未实现的部分 - -本包只覆盖设计文档 §16 的**阶段 1**(Core 和文档模型)。以下属于后续阶段: - -- `report-expression`:表达式解析与受限求值器(阶段 3)。 -- `report-layout`:测量、换行、分页,产出 `LayoutDocument`(阶段 2)。 -- `report-renderer`:HTML / SVG / PDF(阶段 4)。 -- `report-designer` / `report-designer-vue`:编辑器与 UI(阶段 4)。 -- 插件实现:二维码、条码、图表(阶段 5)。 diff --git a/code/one-designer/packages/report-core/package.json b/code/one-designer/packages/report-core/package.json deleted file mode 100644 index 8472761d..00000000 --- a/code/one-designer/packages/report-core/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@report/core", - "version": "0.1.0", - "description": "报表文档模型、插件契约、校验、序列化与迁移", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" - } - }, - "files": ["dist"], - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit" - }, - "devDependencies": { - "tsup": "^8.3.5", - "typescript": "^5.7.2", - "vitest": "^2.1.8" - } -} diff --git a/code/one-designer/packages/report-core/src/command/command.ts b/code/one-designer/packages/report-core/src/command/command.ts deleted file mode 100644 index e618fc07..00000000 --- a/code/one-designer/packages/report-core/src/command/command.ts +++ /dev/null @@ -1,159 +0,0 @@ -/** - * 命令模型(对应设计文档 §4.5 与 §3.2)。 - * - * 设计要点: - * - Designer 通过 Core 的命令接口修改文档,不直接实现报表业务规则。 - * - 撤销栈属于编辑器状态,不进文档(§3.2)。因此 History 由调用方持有, - * Core 只提供命令契约与执行语义。 - * - * 命令采用「整体替换文档」而非原地修改,原因是文档是纯数据、体量可控, - * 整体替换能天然保证不可变性和撤销快照的正确性,避免细粒度 patch 漏改。 - */ -import type { ReportDocument } from "../model/report.js" -import type { Diagnostic } from "../model/common.js" -import { cloneDocument } from "../document/clone.js" - -/** 命令执行上下文。 */ -export interface CommandContext { - /** 当前文档(只读,命令不得直接修改)。 */ - readonly document: ReportDocument -} - -/** 命令执行结果。 */ -export interface CommandResult { - /** 成功时必须返回新的文档;失败时返回 null。 */ - document: ReportDocument | null - diagnostics: Diagnostic[] -} - -/** 命令契约。 */ -export interface Command { - /** 命令名,用于日志、快捷键映射和调试。 */ - readonly type: string - /** 是否可撤销。默认 true。 */ - readonly undoable?: boolean - /** 合并键:相邻且相同 mergeKey 的命令在一定时间窗内合并为一步撤销。 */ - readonly mergeKey?: string - /** - * 执行命令。 - * - * 实现应当是纯函数:不得修改 context.document,只返回新文档。 - */ - execute(payload: TPayload, context: CommandContext): CommandResult -} - -/** 便捷构造:成功结果。 */ -export function success(document: ReportDocument): CommandResult { - return { document, diagnostics: [] } -} - -/** 便捷构造:失败结果。 */ -export function failure(diagnostics: Diagnostic | Diagnostic[]): CommandResult { - return { - document: null, - diagnostics: Array.isArray(diagnostics) ? diagnostics : [diagnostics], - } -} - -/** - * 定义命令的辅助函数。 - * - * 主要用于类型推断:让 payload 类型从 execute 的参数推导出来。 - */ -export function defineCommand( - command: Command, -): Command { - return command -} - -/** - * 基于「取当前文档 → 返回新文档」的函数式惯例构造命令。 - * - * 多数命令不需要访问 payload 以外的信息,用这个包装最省事。 - */ -export function createCommand( - type: string, - handler: (document: ReportDocument, payload: TPayload) => CommandResult | ReportDocument, - options: { undoable?: boolean; mergeKey?: string } = {}, -): Command { - const command: Command = { - type, - execute(payload: TPayload, context: CommandContext): CommandResult { - const result = handler(context.document, payload) - if (isCommandResult(result)) return result - return success(result) - }, - ...(options.undoable !== undefined ? { undoable: options.undoable } :{}), - ...(options.mergeKey !== undefined ? { mergeKey: options.mergeKey } :{}), - } - return command -} - -function isCommandResult(value: unknown): value is CommandResult { - return ( - typeof value === "object" && - value !== null && - "document" in value && - "diagnostics" in value - ) -} - -/** 判断命令是否可撤销。 */ -export function isUndoable(command: Command): boolean { - return command.undoable !== false -} - -/** - * 命令执行器。 - * - * 负责执行命令并把结果交给调用方,自身不保存状态。 - * 撤销栈由 History(见 history.ts)管理。 - */ -export class CommandInvoker { - private document: ReportDocument - - constructor(document: ReportDocument) { - this.document = document - } - - /** 当前文档。 */ - getDocument(): ReportDocument { - return this.document - } - - /** 直接替换文档(用于加载、撤销、重做)。 */ - setDocument(document: ReportDocument): void { - this.document = document - } - - /** 执行命令。失败时文档不变,返回 null。 */ - run(command: Command, payload: TPayload): CommandResult { - const result = command.execute(payload, { - document: this.document, - }) - if (result.document) { - this.document = result.document - } - return result - } - - /** 执行命令并保留旧文档快照,便于撤销。 */ - runWithSnapshot( - command: Command, - payload: TPayload, - ): { result: CommandResult; before: ReportDocument | null } { - const before = isUndoable(command as Command) - ? cloneDocument(this.document) - : null - const result = this.run(command, payload) - if (!result.document) { - return { result, before: null } - } - return { result, before } - } -} - -/** 创建命令执行器。 */ -export function createInvoker(document: ReportDocument): CommandInvoker { - return new CommandInvoker(document) -} diff --git a/code/one-designer/packages/report-core/src/command/history.ts b/code/one-designer/packages/report-core/src/command/history.ts deleted file mode 100644 index 1568731b..00000000 --- a/code/one-designer/packages/report-core/src/command/history.ts +++ /dev/null @@ -1,460 +0,0 @@ -/** - * 事务与撤销/重做(对应设计文档 §4.5 与 §3.2)。 - * - * 重要边界:撤销栈和 redo 栈属于「编辑器状态」,明确禁止写入文档(§3.2)。 - * 因此 History 是一个独立对象,由 Designer 持有,Core 只提供通用实现。 - * - * 实现选择快照式(snapshot-based)撤销而非反向命令式,原因: - * - 文档是纯数据且体量可控,快照成本可接受。 - * - 反向命令需要每个命令实现 undo,容易出错且难以覆盖复杂编辑。 - * - 快照天然正确处理「一个事务改了多处」的情况。 - */ -import type { ReportDocument } from "../model/report.js" -import type { Diagnostic } from "../model/common.js" -import { cloneDocument } from "../document/clone.js" -import { deepEqual } from "../utils/deep.js" -import type { Command, CommandContext, CommandResult } from "./command.js" - -/** 一步可撤销的操作。 */ -export interface HistoryEntry { - /** 便于调试的操作名。 */ - label: string - /** 操作前的文档快照。 */ - before: ReportDocument - /** 操作后的文档快照。 */ - after: ReportDocument - /** 合并键。 */ - mergeKey?: string - /** 记录时间,用于时间窗合并。 */ - timestamp: number -} - -/** History 配置。 */ -export interface HistoryOptions { - /** 最大保留步数。超出后丢弃最早的记录。默认 100。 */ - limit?: number - /** - * 合并时间窗(毫秒)。 - * - * 相邻且 mergeKey 相同的操作在该时间窗内合并为一步,用于拖拽、 - * 连续输入这类高频操作。默认 500ms。 - */ - mergeWindow?: number -} - -/** 一次事务内累积的变更。 */ -interface TransactionState { - label: string - mergeKey?: string - base: ReportDocument - current: ReportDocument -} - -/** - * 撤销/重做历史。 - * - * 支持两种用法: - * 1. 直接记录:`history.record(before, after, "移动元素")` - * 2. 事务:`history.transaction("批量对齐", () => { ... })` - */ -export class History { - private readonly undoStack: HistoryEntry[] = [] - private readonly redoStack: HistoryEntry[] = [] - private readonly limit: number - private readonly mergeWindow: number - private transactionState: TransactionState | null = null - private pendingBase: ReportDocument | null = null - private lastKnownDocument: ReportDocument | null = null - - constructor(options: HistoryOptions = {}) { - this.limit = options.limit ?? 100 - this.mergeWindow = options.mergeWindow ?? 500 - } - - get canUndo(): boolean { - return this.undoStack.length > 0 - } - - get canRedo(): boolean { - return this.redoStack.length > 0 - } - - get undoDepth(): number { - return this.undoStack.length - } - - get redoDepth(): number { - return this.redoStack.length - } - - /** 撤销栈顶部的操作名,便于 UI 显示「撤销:移动元素」。 */ - peekUndoLabel(): string | undefined { - return this.undoStack[this.undoStack.length - 1]?.label - } - - peekRedoLabel(): string | undefined { - return this.redoStack[this.redoStack.length - 1]?.label - } - - /** - * 记录一次变更。 - * - * 若 before 与 after 内容相同则不记录(避免产生空撤销步)。 - */ - record( - before: ReportDocument, - after: ReportDocument, - label: string, - options: { mergeKey?: string } = {}, - ): boolean { - if (deepEqual(before, after)) return false - - // 事务进行中:只更新事务的 current,最后统一提交 - if (this.transactionState) { - this.transactionState.current = cloneDocument(after) - return true - } - - const now = Date.now() - const entry: HistoryEntry = { - label, - before: cloneDocument(before), - after: cloneDocument(after), - timestamp: now, - } - if (options.mergeKey !== undefined) entry.mergeKey = options.mergeKey - - // 合并连续同类操作 - const top = this.undoStack[this.undoStack.length - 1] - if ( - top && - options.mergeKey !== undefined && - top.mergeKey === options.mergeKey && - now - top.timestamp <= this.mergeWindow - ) { - top.after = entry.after - top.timestamp = now - this.redoStack.length = 0 - return true - } - - this.undoStack.push(entry) - this.redoStack.length = 0 - this.trim() - return true - } - - /** - * 在事务中执行一组操作,整体作为一步撤销。 - * - * 事务中即使记录了多次变更,最终也只产生一条撤销记录。 - * - * 只适用于同步完成的编辑。若编辑要跨越多个事件回调(如拖拽的 - * mousedown → mousemove → mouseup),用 beginTransaction / - * commitTransaction,因为本方法在 fn 返回时就会提交。 - */ - transaction( - label: string, - fn: () => T, - options: { mergeKey?: string } = {}, - ): { value: T; changed: boolean } { - if (this.transactionState) { - // 嵌套事务并入外层,避免产生难以理解的多层撤销 - const value = fn() - return { value, changed: true } - } - - if (!this.beginTransaction(label, options)) { - // 没有可回滚的基准文档:直接执行,视为未变更 - const value = fn() - return { value, changed: false } - } - - try { - const value = fn() - const changed = this.commitTransaction() - return { value, changed } - } catch (cause) { - this.rollbackTransaction() - throw cause - } - } - - /** 是否有事务进行中。 */ - get inTransaction(): boolean { - return this.transactionState !== null - } - - /** - * 开始一个**可跨事件回调**的事务。 - * - * 与 transaction() 的区别:这里只登记基准点并置位,提交时机由调用方 - * 决定。拖拽这类「不知道什么时候结束」的连续编辑必须用这个,否则 - * 中间态会被拆成多条撤销记录(依赖时间窗合并并不可靠——用户拖到 - * 一半停手超过合并窗口再继续,就会留下两条记录)。 - * - * 已有事务进行中时返回 false(嵌套并入外层)。 - */ - beginTransaction(label: string, options: { mergeKey?: string } = {}): boolean { - if (this.transactionState) return false - - const baseline = this.pendingBase ?? this.lastKnownDocument - if (!baseline) return false - - this.transactionState = { - label, - base: cloneDocument(baseline), - current: cloneDocument(baseline), - ...(options.mergeKey !== undefined ? { mergeKey: options.mergeKey } : {}), - } - return true - } - - /** - * 提交事务,整体作为一步撤销。 - * - * 返回是否真的产生了一条记录(内容没变则不记录)。 - */ - commitTransaction(): boolean { - const state = this.transactionState - this.transactionState = null - if (!state) return false - if (deepEqual(state.base, state.current)) return false - - const entry: HistoryEntry = { - label: state.label, - before: cloneDocument(state.base), - after: cloneDocument(state.current), - timestamp: Date.now(), - } - if (state.mergeKey !== undefined) entry.mergeKey = state.mergeKey - this.undoStack.push(entry) - this.redoStack.length = 0 - this.trim() - return true - } - - /** - * 回滚事务,丢弃期间的全部变更。 - * - * 返回应恢复的文档;无事务进行中时返回 null。 - */ - rollbackTransaction(): ReportDocument | null { - const state = this.transactionState - this.transactionState = null - if (!state) return null - return cloneDocument(state.base) - } - - /** - * 设置事务或记录的基准文档。 - * - * 由于 History 不持有当前文档(那是 Invoker 的职责),调用方在每次 - * 操作前通过这个方法告知「变更前的状态」。 - */ - setBase(document: ReportDocument): void { - this.lastKnownDocument = cloneDocument(document) - if (this.transactionState) { - this.transactionState.base = cloneDocument(document) - this.transactionState.current = cloneDocument(document) - } else { - this.pendingBase = cloneDocument(document) - } - } - - /** 事务或记录过程中同步当前状态。 */ - updateCurrent(document: ReportDocument): void { - this.lastKnownDocument = cloneDocument(document) - if (this.transactionState) { - this.transactionState.current = cloneDocument(document) - } - } - - /** 撤销。返回应恢复的文档;无可撤销时返回 null。 */ - undo(): ReportDocument | null { - const entry = this.undoStack.pop() - if (!entry) return null - this.redoStack.push(entry) - this.lastKnownDocument = cloneDocument(entry.before) - this.pendingBase = cloneDocument(entry.before) - return cloneDocument(entry.before) - } - - /** 重做。返回应恢复的文档;无可重做时返回 null。 */ - redo(): ReportDocument | null { - const entry = this.redoStack.pop() - if (!entry) return null - this.undoStack.push(entry) - this.lastKnownDocument = cloneDocument(entry.after) - this.pendingBase = cloneDocument(entry.after) - return cloneDocument(entry.after) - } - - /** 清空历史(加载新文档时调用)。 */ - clear(): void { - this.undoStack.length = 0 - this.redoStack.length = 0 - this.transactionState = null - this.pendingBase = null - this.lastKnownDocument = null - } - - /** 丢弃超出上限的最早记录。 */ - private trim(): void { - while (this.undoStack.length > this.limit) { - this.undoStack.shift() - } - } - - /** 导出历史摘要,便于调试与测试。 */ - describe(): { undo: string[]; redo: string[] } { - return { - undo: this.undoStack.map((entry) => entry.label), - redo: this.redoStack.map((entry) => entry.label), - } - } -} - -/** - * 可撤销的编辑会话。 - * - * 把 Invoker 与 History 组合起来,提供 Designer 直接可用的 API: - * 执行命令 → 自动记录历史 → 可撤销。 - */ -export class EditSession { - private document: ReportDocument - readonly history: History - - constructor(document: ReportDocument, options: HistoryOptions = {}) { - this.document = cloneDocument(document) - this.history = new History(options) - this.history.setBase(this.document) - } - - getDocument(): ReportDocument { - return this.document - } - - /** - * 执行命令。 - * - * 失败时文档不变、不记录历史,直接返回诊断。 - */ - execute( - command: Command, - payload: TPayload, - options: { label?: string; mergeKey?: string } = {}, - ): CommandResult { - const context: CommandContext = { document: this.document } - const result = command.execute(payload, context) - if (!result.document) return result - - const before = this.document - const after = result.document - - if (command.undoable !== false) { - const label = options.label ?? command.type - const mergeKey = options.mergeKey ?? command.mergeKey - this.history.record(before, after, label, { - ...(mergeKey !== undefined ? { mergeKey } :{}), - }) - } - - this.document = after - this.history.updateCurrent(after) - return result - } - - /** - * 以事务方式执行一组编辑,整体作为一步撤销。 - */ - transaction( - label: string, - fn: (session: EditSession) => T, - options: { mergeKey?: string } = {}, - ): { value: T; changed: boolean } { - this.history.setBase(this.document) - return this.history.transaction( - label, - () => fn(this), - options, - ) - } - - /** - * 开始一个**可跨事件回调**的事务。 - * - * 事务期间的编辑用 applyWithinTransaction 执行(只改文档、不单独记历史), - * 结束时用 commitTransaction 整体提交为一步撤销。 - * - * 拖拽必须走这条路径:拖多久、中途停顿多久都不该影响撤销粒度。 - */ - beginTransaction(label: string, options: { mergeKey?: string } = {}): boolean { - this.history.setBase(this.document) - return this.history.beginTransaction(label, options) - } - - /** 提交事务,返回是否产生了一条撤销记录。 */ - commitTransaction(): boolean { - return this.history.commitTransaction() - } - - /** 是否有事务进行中。 */ - get inTransaction(): boolean { - return this.history.inTransaction - } - - /** 撤销。 */ - undo(): boolean { - const restored = this.history.undo() - if (!restored) return false - this.document = restored - return true - } - - /** 重做。 */ - redo(): boolean { - const restored = this.history.redo() - if (!restored) return false - this.document = restored - return true - } - - /** 用新文档替换当前文档并清空历史。 */ - load(document: ReportDocument): void { - this.document = cloneDocument(document) - this.history.clear() - this.history.setBase(this.document) - } - - /** - * 内部使用:让事务内的命令执行走同一条路径。 - * - * 这里直接修改内部文档而不记录历史,由外层 transaction 统一提交。 - */ - applyWithinTransaction( - command: Command, - payload: TPayload, - ): CommandResult { - const context: CommandContext = { document: this.document } - const result = command.execute(payload, context) - if (result.document) { - this.document = result.document - this.history.updateCurrent(this.document) - } - return result - } -} - -/** 创建编辑会话。 */ -export function createEditSession( - document: ReportDocument, - options: HistoryOptions = {}, -): EditSession { - return new EditSession(document, options) -} - -/** 诊断是否为空(便于测试断言)。 */ -export function hasErrorDiagnostics(diagnostics: readonly Diagnostic[]): boolean { - return diagnostics.some((item) => item.severity === "error") -} diff --git a/code/one-designer/packages/report-core/src/diagnostics/diagnostic.ts b/code/one-designer/packages/report-core/src/diagnostics/diagnostic.ts deleted file mode 100644 index 97fe285d..00000000 --- a/code/one-designer/packages/report-core/src/diagnostics/diagnostic.ts +++ /dev/null @@ -1,149 +0,0 @@ -/** - * 诊断构建与收集(对应设计文档 §13)。 - * - * 全流程统一使用 Diagnostic 表达警告和错误,不抛异常做业务控制: - * 数据缺失、表达式错误、字体缺失、插件缺失和分页失败都应尽量返回 - * 可定位的诊断信息,而不是中断整个文档的读取。 - */ -import type { Diagnostic, DiagnosticSeverity } from "../model/common.js" - -/** 诊断错误码。集中定义,便于测试和宿主做本地化映射。 */ -export const DIAGNOSTIC_CODES = { - // 结构校验 - SCHEMA_INVALID: "schema.invalid", - SCHEMA_VERSION_UNKNOWN: "schema.version-unknown", - SCHEMA_VERSION_MISSING: "schema.version-missing", - SCHEMA_MIGRATION_FAILED: "schema.migration-failed", - SCHEMA_REQUIRED_MISSING: "schema.required-missing", - SCHEMA_TYPE_MISMATCH: "schema.type-mismatch", - SCHEMA_ENUM_INVALID: "schema.enum-invalid", - SCHEMA_RANGE_INVALID: "schema.range-invalid", - - // 引用完整性 - REF_DANGLING_DATASET: "ref.dangling-dataset", - REF_DANGLING_DATASOURCE: "ref.dangling-datasource", - REF_DANGLING_STYLE: "ref.dangling-style", - REF_DUPLICATE_ID: "ref.duplicate-id", - REF_CYCLE_DETECTED: "ref.cycle-detected", - - // 元素 - ELEMENT_UNKNOWN_TYPE: "element.unknown-type", - ELEMENT_CHILD_NOT_ALLOWED: "element.child-not-allowed", - ELEMENT_FRAME_INVALID: "element.frame-invalid", - - // 插件 - PLUGIN_MISSING: "plugin.missing", - PLUGIN_VERSION_INCOMPATIBLE: "plugin.version-incompatible", - PLUGIN_ALREADY_REGISTERED: "plugin.already-registered", - - // 数据与表达式 - DATA_DATASET_MISSING: "data.dataset-missing", - EXPRESSION_PARSE_ERROR: "expression.parse-error", - EXPRESSION_EVAL_ERROR: "expression.eval-error", - - // 布局 - LAYOUT_PAGE_OVERFLOW: "layout.page-overflow", - LAYOUT_TEXT_OVERFLOW: "layout.text-overflow", -} as const - -export type DiagnosticCode = - (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES] - -/** 创建一条诊断。 */ -export function createDiagnostic( - severity: DiagnosticSeverity, - code: string, - message: string, - extra?: { path?: string; elementId?: string }, -): Diagnostic { - const diagnostic: Diagnostic = { severity, code, message } - if (extra?.path !== undefined) diagnostic.path = extra.path - if (extra?.elementId !== undefined) diagnostic.elementId = extra.elementId - return diagnostic -} - -export function info( - code: string, - message: string, - extra?: { path?: string; elementId?: string }, -): Diagnostic { - return createDiagnostic("info", code, message, extra) -} - -export function warning( - code: string, - message: string, - extra?: { path?: string; elementId?: string }, -): Diagnostic { - return createDiagnostic("warning", code, message, extra) -} - -export function error( - code: string, - message: string, - extra?: { path?: string; elementId?: string }, -): Diagnostic { - return createDiagnostic("error", code, message, extra) -} - -/** 诊断收集器。在流程中累积诊断,最后统一交给调用方。 */ -export class DiagnosticBag { - private readonly items: Diagnostic[] = [] - - add(diagnostic: Diagnostic): void { - this.items.push(diagnostic) - } - - info(code: string, message: string, extra?: { path?: string; elementId?: string }): void { - this.items.push(info(code, message, extra)) - } - - warn(code: string, message: string, extra?: { path?: string; elementId?: string }): void { - this.items.push(warning(code, message, extra)) - } - - error(code: string, message: string, extra?: { path?: string; elementId?: string }): void { - this.items.push(error(code, message, extra)) - } - - get size(): number { - return this.items.length - } - - /** 是否包含至少一条错误级诊断。 */ - get hasError(): boolean { - return this.items.some((item) => item.severity === "error") - } - - all(): Diagnostic[] { - return [...this.items] - } - - bySeverity(severity: DiagnosticSeverity): Diagnostic[] { - return this.items.filter((item) => item.severity === severity) - } - - /** 按给定严重级别过滤,返回新的收集器。 */ - filter(severity: DiagnosticSeverity): DiagnosticBag { - const bag = new DiagnosticBag() - for (const item of this.items) { - if (item.severity === severity) bag.add(item) - } - return bag - } -} - -/** 用一组诊断构造收集器。 */ -export function toBag(diagnostics: readonly Diagnostic[]): DiagnosticBag { - const bag = new DiagnosticBag() - for (const diagnostic of diagnostics) bag.add(diagnostic) - return bag -} - -/** 把诊断渲染成便于日志查看的单行文本。 */ -export function formatDiagnostic(diagnostic: Diagnostic): string { - const parts = [`[${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`] - if (diagnostic.path) parts.push(`path=${diagnostic.path}`) - if (diagnostic.elementId) parts.push(`elementId=${diagnostic.elementId}`) - return parts.join(" ") -} diff --git a/code/one-designer/packages/report-core/src/document/clone.ts b/code/one-designer/packages/report-core/src/document/clone.ts deleted file mode 100644 index cec7bcaf..00000000 --- a/code/one-designer/packages/report-core/src/document/clone.ts +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 文档克隆(对应设计文档 §4.1)。 - * - * 克隆服务于三类场景: - * - 撤销重做需要保存文档快照(§3.2 明确撤销栈不属于文档,由 Designer 持有)。 - * - 复制粘贴需要深拷贝元素子树。 - * - 预览需要在不污染编辑态的前提下拿到只读副本。 - * - * 所有克隆都保证「纯数据」约束(§3.5):不含函数、DOM 节点和运行时对象。 - */ -import type { ReportDocument } from "../model/report.js" -import type { ReportElement } from "../model/element.js" -import type { ReportSection } from "../model/section.js" -import { deepClone } from "../utils/deep.js" -import { createElementId } from "../utils/id.js" - -/** - * 深拷贝文档。 - * - * 保留原 ID,用于快照。若需要一份「独立的新文档」,请用 create.duplicateDocument。 - */ -export function cloneDocument(document: ReportDocument): ReportDocument { - return deepClone(document) -} - -/** 深拷贝单个元素(保留原 ID)。 */ -export function cloneElement(element: ReportElement): ReportElement { - return deepClone(element) -} - -/** - * 为复制粘贴克隆元素子树。 - * - * 会为整棵子树重新分配 ID,避免粘贴后出现重复 ID。 - * 表格列 ID 同样重新分配。 - */ -export function cloneElementWithNewIds( - element: ReportElement, - generateId: () => string = createElementId, -): ReportElement { - const copy = deepClone(element) - const remap = (node: ReportElement): void => { - node.id = generateId() - if (node.children?.length) node.children.forEach(remap) - const columns = (node as { columns?: { id: string; children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - column.id = generateId() - if (column.children?.length) column.children.forEach(remap) - } - } - } - remap(copy) - return copy -} - -/** 深拷贝区域。 */ -export function cloneSection(section: ReportSection): ReportSection { - return deepClone(section) -} - -/** - * 克隆区域并重新分配其下所有元素 ID。 - */ -export function cloneSectionWithNewIds( - section: ReportSection, - generateId: () => string = createElementId, -): ReportSection { - const copy = cloneSection(section) - const remap = (elements: ReportElement[]): void => { - for (const element of elements) { - element.id = generateId() - if (element.children?.length) remap(element.children) - const columns = (element as { columns?: { id: string; children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - column.id = generateId() - if (column.children?.length) remap(column.children) - } - } - } - } - remap(copy.children) - return copy -} - -/** - * 创建文档快照。 - * - * 与 cloneDocument 的差异在于语义:快照是「只读、用于回滚」的副本, - * 调用方不应再修改它。 - */ -export function snapshot(document: ReportDocument): Readonly { - return Object.freeze(cloneDocument(document)) as Readonly -} - -/** 把只读快照还原为可变文档。 */ -export function restore(snapshotValue: Readonly): ReportDocument { - return cloneDocument(snapshotValue as ReportDocument) -} diff --git a/code/one-designer/packages/report-core/src/document/create.ts b/code/one-designer/packages/report-core/src/document/create.ts deleted file mode 100644 index b1176e36..00000000 --- a/code/one-designer/packages/report-core/src/document/create.ts +++ /dev/null @@ -1,128 +0,0 @@ -/** - * 文档创建(对应设计文档 §4.1 与 §16 阶段 1)。 - * - * 新建文档必须一步到位地满足规范化要求,因此这里直接产出完整的 - * ReportDocument,而不是半成品结构。 - */ -import type { ReportDocument, ReportMetadata } from "../model/report.js" -import type { PageSettings } from "../model/page.js" -import type { ReportSection, ReportSectionKind } from "../model/section.js" -import type { ReportElement } from "../model/element.js" -import type { StyleDefinition } from "../model/style.js" -import { createDefaultPageSettings } from "../model/page.js" -import { createDefaultSectionOptions } from "../schema/defaults.js" -import { CURRENT_SCHEMA_VERSION } from "../schema/version.js" -import { createDocumentId, createSectionId } from "../utils/id.js" -import { normalize } from "./normalize.js" - -/** 创建文档的选项。 */ -export interface CreateDocumentOptions { - name?: string - id?: string - page?: Partial - metadata?: ReportMetadata - /** 自定义初始区域;缺省为 page-header / detail / page-footer 三个空区域。 */ - sections?: ReportSection[] - styles?: Record -} - -/** 新建一份空白报表文档。 */ -export function createDocument(options: CreateDocumentOptions = {}): ReportDocument { - const name = options.name ?? "未命名报表" - const page = mergePage(options.page) - - const document: ReportDocument = { - schemaVersion: CURRENT_SCHEMA_VERSION, - id: options.id ?? createDocumentId(), - name, - page, - styles: options.styles ?? {}, - dataSources: {}, - datasets: {}, - parameters: {}, - sections: options.sections ?? createDefaultSections(), - } - - if (options.metadata) { - document.metadata = { ...options.metadata } - } - - return normalize(document) -} - -function mergePage(partial: Partial | undefined): PageSettings { - const base = createDefaultPageSettings() - if (!partial) return base - const out: PageSettings = { - paper: partial.paper ?? base.paper, - orientation: partial.orientation ?? base.orientation, - margin: { ...base.margin, ...(partial.margin ?? {}) }, - } - if (partial.customSize) out.customSize = { ...partial.customSize } - if (partial.background !== undefined) out.background = partial.background - return out -} - -/** 创建 V1 的三个默认区域。 */ -export function createDefaultSections(): ReportSection[] { - const kinds: ReportSectionKind[] = ["page-header", "detail", "page-footer"] - return kinds.map((kind) => { - const section: ReportSection = { id: createSectionId(), kind, children: [] } - const options = createDefaultSectionOptions(kind) - if (options !== undefined) section.options = options - return section - }) -} - -/** - * 从已有文档派生一份新文档。 - * - * 会重新生成文档 ID,避免同一宿主里出现两份同 ID 文档。 - * 跨文档引用(样式、数据集)保持原样,因为它们随文档一起被复制。 - */ -export function duplicateDocument( - document: ReportDocument, - options: { name?: string } = {}, -): ReportDocument { - const copy = normalize(deepCopyDocument(document)) - copy.id = createDocumentId() - copy.name = options.name ?? `${document.name} 副本` - if (copy.metadata) { - copy.metadata.createdAt = new Date().toISOString() - delete copy.metadata.updatedAt - } - return copy -} - -/** 文档的深拷贝(纯数据,直接走 JSON 通路最稳妥)。 */ -function deepCopyDocument(document: ReportDocument): ReportDocument { - return JSON.parse(JSON.stringify(document)) as ReportDocument -} - -/** 判断文档是否为空(没有任何元素、数据源、数据集和参数)。 */ -export function isDocumentEmpty(document: ReportDocument): boolean { - if (document.sections.some((section) => section.children.length > 0)) return false - if (Object.keys(document.dataSources).length > 0) return false - if (Object.keys(document.datasets).length > 0) return false - if (Object.keys(document.parameters).length > 0) return false - return true -} - -/** 统计文档中的元素总数(含嵌套)。 */ -export function countElements(document: ReportDocument): number { - let count = 0 - const walk = (elements: readonly ReportElement[]): void => { - for (const element of elements) { - count += 1 - if (element.children?.length) walk(element.children) - const columns = (element as { columns?: { children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - if (column.children?.length) walk(column.children) - } - } - } - } - for (const section of document.sections) walk(section.children) - return count -} diff --git a/code/one-designer/packages/report-core/src/document/normalize.ts b/code/one-designer/packages/report-core/src/document/normalize.ts deleted file mode 100644 index e5261de8..00000000 --- a/code/one-designer/packages/report-core/src/document/normalize.ts +++ /dev/null @@ -1,180 +0,0 @@ -/** - * 文档规范化(对应设计文档 §12 的 normalize 阶段)。 - * - * 规范化保证「新建文档」和「读取旧文档」得到结构一致的结果: - * 补齐缺省字段、统一 ID 引用、丢弃非法值。规范化不做业务校验, - * 校验由 schema/validation 负责,两者职责分离。 - */ -import type { ReportDocument, ReportPluginReference } from "../model/report.js" -import type { ReportSection } from "../model/section.js" -import type { ReportElement } from "../model/element.js" -import type { StyleDefinition } from "../model/style.js" -import type { DataSourceDefinition, DatasetDefinition } from "../model/datasource.js" -import type { ReportParameter } from "../model/parameter.js" -import { - normalizeElement, - normalizeSection, - createDefaultPageSettings, -} from "../schema/defaults.js" -import { CURRENT_SCHEMA_VERSION } from "../schema/version.js" -import { createSectionId } from "../utils/id.js" - -/** - * 规范化文档。 - * - * 输入可以是任意 unknown(通常来自反序列化后的 JSON),输出一定是 - * 结构完整的 ReportDocument。缺字段补默认,多余字段丢弃。 - */ -export function normalize(document: ReportDocument): ReportDocument { - const sections = normalizeSections(document.sections) - - const out: ReportDocument = { - schemaVersion: CURRENT_SCHEMA_VERSION, - id: document.id, - name: typeof document.name === "string" && document.name.length > 0 - ? document.name - : "未命名报表", - page: normalizePage(document.page), - styles: normalizeStyles(document.styles), - dataSources: normalizeDataSources(document.dataSources), - datasets: normalizeDatasets(document.datasets), - parameters: normalizeParameters(document.parameters), - sections, - } - - const plugins = normalizePlugins(document.plugins) - if (plugins) out.plugins = plugins - if (document.metadata) out.metadata = { ...document.metadata } - - return out -} - -function normalizePage(page: ReportDocument["page"]): ReportDocument["page"] { - const fallback = createDefaultPageSettings() - if (!page) return fallback - const out: ReportDocument["page"] = { - paper: page.paper ?? fallback.paper, - orientation: page.orientation ?? fallback.orientation, - margin: { - top: page.margin?.top ?? fallback.margin.top, - right: page.margin?.right ?? fallback.margin.right, - bottom: page.margin?.bottom ?? fallback.margin.bottom, - left: page.margin?.left ?? fallback.margin.left, - }, - } - if (page.customSize) { - out.customSize = { - width: page.customSize.width, - height: page.customSize.height, - } - } - if (page.background !== undefined) out.background = page.background - return out -} - -function normalizeStyles( - styles: Record | undefined, -): Record { - const out: Record = {} - for (const [id, style] of Object.entries(styles ?? {})) { - if (!style || typeof style !== "object") continue - // 以字典键为准,保证 style.id 与键一致,避免出现两处不一致 - out[id] = { ...style, id } - } - return out -} - -function normalizeDataSources( - sources: Record | undefined, -): Record { - const out: Record = {} - for (const [id, source] of Object.entries(sources ?? {})) { - if (!source || typeof source !== "object") continue - const item: DataSourceDefinition = { id, type: source.type ?? "unknown" } - if (source.config !== undefined) item.config = source.config - if (source.connectionRef !== undefined) item.connectionRef = source.connectionRef - out[id] = item - } - return out -} - -function normalizeDatasets( - datasets: Record | undefined, -): Record { - const out: Record = {} - for (const [id, dataset] of Object.entries(datasets ?? {})) { - if (!dataset || typeof dataset !== "object") continue - const item: DatasetDefinition = { id } - if (dataset.sourceId !== undefined) item.sourceId = dataset.sourceId - if (dataset.fields !== undefined) item.fields = dataset.fields.map((f) => ({ ...f })) - if (dataset.query !== undefined) item.query = dataset.query - if (dataset.config !== undefined) item.config = dataset.config - out[id] = item - } - return out -} - -function normalizeParameters( - parameters: Record | undefined, -): Record { - const out: Record = {} - for (const [id, parameter] of Object.entries(parameters ?? {})) { - if (!parameter || typeof parameter !== "object") continue - // 参数名缺省时回落到 id,保证表达式始终可引用 - const name = typeof parameter.name === "string" && parameter.name.length > 0 - ? parameter.name - : id - out[id] = { ...parameter, id, name } - } - return out -} - -function normalizePlugins( - plugins: ReportPluginReference[] | undefined, -): ReportPluginReference[] | undefined { - if (!Array.isArray(plugins) || plugins.length === 0) return undefined - const seen = new Set() - const out: ReportPluginReference[] = [] - for (const plugin of plugins) { - if (!plugin?.id || seen.has(plugin.id)) continue - seen.add(plugin.id) - const item: ReportPluginReference = { id: plugin.id, version: plugin.version ?? "*" } - if (plugin.config !== undefined) item.config = plugin.config - out.push(item) - } - return out.length > 0 ? out : undefined -} - -/** - * 规范化区域列表。 - * - * 保证 page-header / detail / page-footer 三个 V1 区域一定存在, - * 且每种至多一个,避免 Designer 侧到处判空。 - */ -export function normalizeSections( - sections: ReportSection[] | undefined, -): ReportSection[] { - const list = Array.isArray(sections) ? sections.map(normalizeSection) : [] - - const singleKinds: ReportSection["kind"][] = ["page-header", "detail", "page-footer"] - const out: ReportSection[] = [] - - for (const kind of singleKinds) { - const existing = list.find((section) => section.kind === kind) - if (existing) { - out.push(existing) - } else { - out.push({ id: createSectionId(), kind, children: [] }) - } - } - // 其余区域(report-header / group-* / summary)按原顺序附在后面 - for (const section of list) { - if (!singleKinds.includes(section.kind)) out.push(section) - } - return out -} - -/** 规范化元素树。 */ -export function normalizeElements(elements: ReportElement[] | undefined): ReportElement[] { - return (elements ?? []).map(normalizeElement) -} diff --git a/code/one-designer/packages/report-core/src/index.ts b/code/one-designer/packages/report-core/src/index.ts deleted file mode 100644 index 1eb5b25c..00000000 --- a/code/one-designer/packages/report-core/src/index.ts +++ /dev/null @@ -1,298 +0,0 @@ -/** - * @report/core 公共入口(对应设计文档 §4.1、§5)。 - * - * 本包是纯 TypeScript,无 Vue / React / DOM / 浏览器 API 依赖(§3.1), - * 可在 Browser、Node.js、Electron、Server 和 CLI 中复用。 - * - * 导出组织原则: - * - 模型与类型从 model/ 导出。 - * - 行为函数按领域分组导出,命名保持动词开头。 - * - 内部工具(deep / id)只导出稳定接口,供 Designer 复用。 - */ - -// --------------------------------------------------------------------------- -// 模型 -// --------------------------------------------------------------------------- - -export type { - Rect, - BoxSpacing, - PageMargin, - BorderStyle, - BorderSide, - BorderLineStyle, - HorizontalAlign, - VerticalAlign, - ColorValue, - ColorConfig, - Diagnostic, - DiagnosticSeverity, -} from "./model/common.js" - -export type { - PaperKind, - PageOrientation, - CustomPageSize, - PageSettings, - ResolvedPageSize, -} from "./model/page.js" -export { - PAPER_SIZES_MM, - DEFAULT_PAGE_MARGIN, - createDefaultPageSettings, - resolvePageSize, - resolveContentBox, -} from "./model/page.js" - -export type { - StyleDefinition, - ResolvedStyle, - StyleResolution, -} from "./model/style.js" -export { - DEFAULT_RESOLVED_STYLE, - mergeStyleOverride, - resolveStyleChain, -} from "./model/style.js" - -export type { ReportElement, ValueBinding, BuiltinElementType } from "./model/element.js" -export { - BUILTIN_ELEMENT_TYPES, - CONTAINER_ELEMENT_TYPES, - isBuiltinElementType, - canHaveChildren, - createTextElement, - createRectElement, - createLineElement, - createImageElement, - createContainerElement, -} from "./model/element.js" - -export type { - TableElement, - TableColumn, - RowHeightMode, -} from "./model/table.js" -export { - isTableElement, - measureTableWidth, - createTableElement, -} from "./model/table.js" - -export type { - ReportSection, - ReportSectionKind, - ReportSectionOptions, -} from "./model/section.js" -export { - V1_SECTION_KINDS, - GROUP_SECTION_KINDS, - RESERVED_SECTION_KINDS, - isV1SectionKind, - isGroupSectionKind, - createSection, -} from "./model/section.js" - -export type { - DataSourceDefinition, - DatasetDefinition, - DatasetField, - DatasetFieldType, -} from "./model/datasource.js" -export { findSensitiveKeys } from "./model/datasource.js" - -export type { - ReportParameter, - ParameterOption, - ParameterValueType, -} from "./model/parameter.js" -export { isValidParameterName } from "./model/parameter.js" - -export type { RenderContext, DataProvider } from "./model/runtime.js" -export { createEmptyRenderContext } from "./model/runtime.js" - -export type { - ReportDocument, - ReportMetadata, - ReportPluginReference, -} from "./model/report.js" -export { - findSectionsByKind, - findFirstSection, - collectElementIds, -} from "./model/report.js" - -// --------------------------------------------------------------------------- -// Schema:版本、默认值与校验 -// --------------------------------------------------------------------------- - -export type { Migration } from "./schema/version.js" -export { - CURRENT_SCHEMA_VERSION, - MIN_SCHEMA_VERSION, - MIGRATIONS, - planMigrations, - isValidSchemaVersion, -} from "./schema/version.js" - -export { - DEFAULT_ELEMENT_SIZE, - FALLBACK_ELEMENT_SIZE, - getDefaultElementSize, - createDefaultFrame, - createDefaultSectionOptions, - createDefaultTableColumn, - createDefaultTable, - createDefaultMetadata, - normalizeElement, - normalizeRect, - normalizeColumn, - normalizeSection, - createEmptyDocumentSkeleton, -} from "./schema/defaults.js" -export type { EmptyDocumentSkeleton } from "./schema/defaults.js" - -export { - validateStructure, - validateDocument, - detectStyleCycles, -} from "./schema/validation.js" - -// --------------------------------------------------------------------------- -// 文档:创建、克隆、规范化 -// --------------------------------------------------------------------------- - -export type { CreateDocumentOptions } from "./document/create.js" -export { - createDocument, - createDefaultSections, - duplicateDocument, - isDocumentEmpty, - countElements, -} from "./document/create.js" - -export { - cloneDocument, - cloneElement, - cloneElementWithNewIds, - cloneSection, - cloneSectionWithNewIds, - snapshot, - restore, -} from "./document/clone.js" - -export { normalize, normalizeSections, normalizeElements } from "./document/normalize.js" - -// --------------------------------------------------------------------------- -// 序列化 -// --------------------------------------------------------------------------- - -export type { SerializeOptions } from "./serialization/serialize.js" -export { serialize, serializeValue, toPlainObject } from "./serialization/serialize.js" - -export type { MigrateResult } from "./serialization/migrate.js" -export { migrate, needsMigration } from "./serialization/migrate.js" - -export type { DeserializeOptions, DeserializeResult } from "./serialization/deserialize.js" -export { - deserialize, - deserializeValue, - deserializeLeniently, - deserializeStrictly, - tryDeserialize, - summarizeDiagnostics, -} from "./serialization/deserialize.js" - -// --------------------------------------------------------------------------- -// 命令与撤销重做 -// --------------------------------------------------------------------------- - -export type { - Command, - CommandContext, - CommandResult, -} from "./command/command.js" -export { - createCommand, - defineCommand, - success, - failure, - isUndoable, - CommandInvoker, - createInvoker, -} from "./command/command.js" - -export type { HistoryEntry, HistoryOptions } from "./command/history.js" -export { - History, - EditSession, - createEditSession, - hasErrorDiagnostics, -} from "./command/history.js" - -// --------------------------------------------------------------------------- -// 插件 -// --------------------------------------------------------------------------- - -export type { - ReportPlugin, - ElementPlugin, - DataSourcePlugin, - ExporterPlugin, - PluginContext, - PluginKind, - MissingPluginInfo, -} from "./plugin/plugin.js" -export { isVersionCompatible, describeDataSourcePlugin } from "./plugin/plugin.js" - -export type { RegisterResult } from "./plugin/registry.js" -export { - PluginRegistry, - createPluginRegistry, - reportRegisterResult, -} from "./plugin/registry.js" - -// --------------------------------------------------------------------------- -// 诊断 -// --------------------------------------------------------------------------- - -export { - DIAGNOSTIC_CODES, - createDiagnostic, - info, - warning, - error, - DiagnosticBag, - toBag, - formatDiagnostic, -} from "./diagnostics/diagnostic.js" -export type { DiagnosticCode } from "./diagnostics/diagnostic.js" - -// --------------------------------------------------------------------------- -// 工具 -// --------------------------------------------------------------------------- - -export { - createId, - createElementId, - createSectionId, - createDocumentId, - createDatasetId, - createDataSourceId, - createParameterId, - createColumnId, - createStyleId, - isValidId, - createUniqueId, -} from "./utils/id.js" -export type { IdOptions } from "./utils/id.js" - -export { - isPlainObject, - isPlainData, - deepClone, - deepEqual, - sortKeysDeep, - omitUndefined, - deepMerge, -} from "./utils/deep.js" diff --git a/code/one-designer/packages/report-core/src/model/common.ts b/code/one-designer/packages/report-core/src/model/common.ts deleted file mode 100644 index d5ed69a5..00000000 --- a/code/one-designer/packages/report-core/src/model/common.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 基础公共类型(对应设计文档 §6.2 / §7 / §13)。 - * - * 本文件是整个 core 的最底层,不依赖任何其他模块。 - */ - -/** 矩形区域。文档内部长度单位统一为 mm(§7)。 */ -export interface Rect { - x: number - y: number - width: number - height: number -} - -/** 四边尺寸,用于页边距、内边距等。单位 mm。 */ -export interface BoxSpacing { - top: number - right: number - bottom: number - left: number -} - -/** 页面边距(§7)。 */ -export type PageMargin = BoxSpacing - -/** 边框线型。 */ -export type BorderLineStyle = "solid" | "dashed" | "dotted" | "none" - -/** 单条边框。 */ -export interface BorderSide { - width: number - color: string - style?: BorderLineStyle -} - -/** - * 边框定义。既支持四边统一写法,也支持逐边覆盖。 - */ -export interface BorderStyle { - /** 四边统一宽度;被 sides 中的同边配置覆盖 */ - width?: number - /** 四边统一颜色;被 sides 中的同边配置覆盖 */ - color?: string - /** 四边统一线型 */ - style?: BorderLineStyle - /** 逐边覆盖,优先级高于统一配置 */ - sides?: { - top?: BorderSide - right?: BorderSide - bottom?: BorderSide - left?: BorderSide - } -} - -/** 水平对齐。 */ -export type HorizontalAlign = "left" | "center" | "right" - -/** 垂直对齐。 */ -export type VerticalAlign = "top" | "middle" | "bottom" - -/** - * 颜色字符串。 - * - * 文档层允许 #rgb / #rrggbb / #rrggbbaa / rgb() / rgba() / hsl() / oklch() - * 以及 "transparent"。UI 层的设计令牌(§14.4)不进入文档,文档保存的是 - * 解析后的具体色值,保证跨 Renderer 输出一致。 - */ -export type ColorValue = string - -/** 通用诊断严重级别(§13)。 */ -export type DiagnosticSeverity = "info" | "warning" | "error" - -/** 统一的诊断对象(§13)。 */ -export interface Diagnostic { - severity: DiagnosticSeverity - code: string - message: string - /** 字段路径,使用 JSON Pointer 风格,如 /sections/0/children/1/frame/width */ - path?: string - /** 相关元素 ID */ - elementId?: string -} - -/** 颜色配置,保留未来扩展渐变等能力的空间。 */ -export interface ColorConfig { - type: "solid" | "none" - value?: ColorValue -} diff --git a/code/one-designer/packages/report-core/src/model/dataset.ts b/code/one-designer/packages/report-core/src/model/dataset.ts deleted file mode 100644 index 9feed2a5..00000000 --- a/code/one-designer/packages/report-core/src/model/dataset.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * 数据集定义(对应设计文档 §8)。 - * - * 从 datasource.ts 拆出,保持「数据源定义」与「数据集定义」职责清晰: - * 数据源描述“连到哪里”,数据集描述“取哪些字段、以何种查询取”。 - */ -export type { - DatasetDefinition, - DatasetField, - DatasetFieldType, -} from "./datasource.js" diff --git a/code/one-designer/packages/report-core/src/model/datasource.ts b/code/one-designer/packages/report-core/src/model/datasource.ts deleted file mode 100644 index a18cac74..00000000 --- a/code/one-designer/packages/report-core/src/model/datasource.ts +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 数据源定义(对应设计文档 §8)。 - * - * 关键约束:报表文档只保存数据源定义,不保存连接、Token 和本次查询结果。 - * config 只保存非敏感的设计配置;连接密码、Token 等敏感信息必须通过 - * connectionRef 或宿主运行时注入。 - */ - -/** 数据源定义。 */ -export interface DataSourceDefinition { - id: string - /** 数据源类型标识,由 DataSourcePlugin 提供,如 "rest"、"sql"、"static"。 */ - type: string - /** 非敏感的设计期配置。禁止写入密码和 Token。 */ - config?: Record - /** - * 指向宿主应用中已配置的连接。 - * - * Core 不解析该值,只做透传,由宿主的 DataProvider 负责解析。 - */ - connectionRef?: string -} - -/** 数据集字段。 */ -export interface DatasetField { - name: string - /** 字段类型,用于表达式求值和格式化。 */ - type?: DatasetFieldType - /** 展示名。 */ - label?: string -} - -/** 字段类型。 */ -export type DatasetFieldType = - | "string" - | "number" - | "boolean" - | "date" - | "datetime" - | "object" - | "array" - | "any" - -/** 数据集定义。 */ -export interface DatasetDefinition { - id: string - /** 所属数据源 ID。缺省表示使用宿主注入的默认数据源。 */ - sourceId?: string - fields?: DatasetField[] - /** - * 查询语句 / 请求描述。 - * - * Core 不解析其语法,只做透传,由宿主的 DataProvider 解释, - * 从而避免 Core 绑定任何具体的数据访问技术。 - */ - query?: string - /** 数据集级的设计期配置。 */ - config?: Record -} - -/** - * 判断数据源定义中是否含有疑似敏感字段。 - * - * 用于序列化前的体检和 Designer 的提示:文档不允许出现明文凭据(§3.4)。 - */ -export function findSensitiveKeys(source: DataSourceDefinition): string[] { - const SENSITIVE = /(password|passwd|secret|token|apikey|api_key|credential|privatekey)/i - const hits: string[] = [] - const walk = (value: unknown, path: string): void => { - if (value === null || typeof value !== "object") return - if (Array.isArray(value)) { - value.forEach((item, index) => walk(item, `${path}/${index}`)) - return - } - for (const [key, item] of Object.entries(value as Record)) { - const next = `${path}/${key}` - if (SENSITIVE.test(key)) hits.push(next) - walk(item, next) - } - } - walk(source.config, "/config") - if (source.connectionRef !== undefined && SENSITIVE.test(source.connectionRef)) { - // connectionRef 本身是引用而非凭据,仅当其形如明文键值对时提示 - hits.push("/connectionRef") - } - return hits -} diff --git a/code/one-designer/packages/report-core/src/model/element.ts b/code/one-designer/packages/report-core/src/model/element.ts deleted file mode 100644 index 9cf52b1a..00000000 --- a/code/one-designer/packages/report-core/src/model/element.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 元素模型(对应设计文档 §6.2)。 - * - * 报表采用「文档 + 区域 + 元素树」模型,元素可嵌套(container / table)。 - * 元素坐标 frame 相对于其父容器;顶层元素相对于所在区域的内容区。 - */ -import type { Rect } from "./common.js" - -/** 值绑定(§6.2)。 */ -export interface ValueBinding { - /** 字段路径,如 "amount" 或 "customer.name"。 */ - field?: string - /** 受限表达式,如 "row.price * row.quantity"。 */ - expression?: string - /** 格式化模式,如 "YYYY-MM-DD"、"#,##0.00"。 */ - format?: string -} - -/** 元素基类。 */ -export interface ReportElement { - id: string - /** 元素类型。内置类型见 BUILTIN_ELEMENT_TYPES,插件可用自定义 type。 */ - type: string - - frame: Rect - styleId?: string - - binding?: ValueBinding - /** 元素专属属性,由内置实现或插件 Schema 解释。 */ - props?: Record - children?: ReportElement[] - /** 元素级样式覆盖,优先级高于 styleId。 */ - style?: Record - /** 人类可读的名称,用于图层面板。 */ - name?: string - /** 是否锁定,禁止在 Designer 中直接操作。 */ - locked?: boolean - /** 是否隐藏。隐藏元素不参与布局输出。 */ - hidden?: boolean -} - -/** 内置元素类型(§6.2)。 */ -export const BUILTIN_ELEMENT_TYPES = [ - "text", - "image", - "line", - "rect", - "container", - "table", -] as const - -export type BuiltinElementType = (typeof BUILTIN_ELEMENT_TYPES)[number] - -/** 判断是否为内置元素类型。 */ -export function isBuiltinElementType(type: string): type is BuiltinElementType { - return (BUILTIN_ELEMENT_TYPES as readonly string[]).includes(type) -} - -/** - * 允许包含子元素的类型。 - * - * line / image / text 是叶子节点;container / table 可嵌套。 - * 插件的容器能力由其 ElementPlugin 自行声明。 - */ -export const CONTAINER_ELEMENT_TYPES: ReadonlySet = new Set([ - "container", - "table", -]) - -/** 判断某类型是否允许拥有 children。 */ -export function canHaveChildren(type: string, pluginContainers?: ReadonlySet): boolean { - if (CONTAINER_ELEMENT_TYPES.has(type)) return true - return pluginContainers?.has(type) ?? false -} - -/** 创建文本元素。 */ -export function createTextElement( - id: string, - frame: Rect, - text = "文本", -): ReportElement { - return { id, type: "text", frame, props: { text } } -} - -/** 创建矩形元素。 */ -export function createRectElement(id: string, frame: Rect): ReportElement { - return { id, type: "rect", frame } -} - -/** 创建线条元素。 */ -export function createLineElement(id: string, frame: Rect): ReportElement { - return { id, type: "line", frame, props: { direction: "horizontal" } } -} - -/** 创建图片元素。 */ -export function createImageElement(id: string, frame: Rect, src = ""): ReportElement { - return { id, type: "image", frame, props: { src, fit: "contain" } } -} - -/** 创建容器元素。 */ -export function createContainerElement( - id: string, - frame: Rect, - children: ReportElement[] = [], -): ReportElement { - return { id, type: "container", frame, children } -} diff --git a/code/one-designer/packages/report-core/src/model/page.ts b/code/one-designer/packages/report-core/src/model/page.ts deleted file mode 100644 index f72cbaa3..00000000 --- a/code/one-designer/packages/report-core/src/model/page.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 页面模型(对应设计文档 §7)。 - * - * 单位约定:文档内部统一使用 mm;px 只用于 Designer 显示层, - * pt 只在 PDF 等输出边界转换。因此本文件出现的所有长度均为 mm。 - */ -import type { PageMargin } from "./common.js" - -/** 纸张类型。 */ -export type PaperKind = "A4" | "A5" | "custom" - -/** 纸张方向。 */ -export type PageOrientation = "portrait" | "landscape" - -/** 自定义纸张尺寸。 */ -export interface CustomPageSize { - width: number - height: number -} - -/** 页面设置。 */ -export interface PageSettings { - paper: PaperKind - orientation: PageOrientation - customSize?: CustomPageSize - margin: PageMargin - background?: string -} - -/** - * 标准纸张的纵向尺寸(mm)。 - * - * 这里只保存纵向基准值,横向由 resolvePageSize 交换宽高得到, - * 避免同一纸张出现两份可能不一致的数据。 - */ -export const PAPER_SIZES_MM: Readonly, CustomPageSize>> = - Object.freeze({ - A4: Object.freeze({ width: 210, height: 297 }), - A5: Object.freeze({ width: 148, height: 210 }), - }) - -/** 默认页边距(mm)。 */ -export const DEFAULT_PAGE_MARGIN: PageMargin = Object.freeze({ - top: 15, - right: 15, - bottom: 15, - left: 15, -}) - -/** 默认页面设置。 */ -export function createDefaultPageSettings(): PageSettings { - return { - paper: "A4", - orientation: "portrait", - margin: { ...DEFAULT_PAGE_MARGIN }, - } -} - -/** 解析后的页面尺寸(mm)。 */ -export interface ResolvedPageSize { - width: number - height: number -} - -/** - * 把 paper + orientation 解析为最终的 width / height(§7)。 - * - * 这是 Layout 阶段的职责,放在 core 是为了让 Designer 预览和 - * Renderer 都能拿到同一套换算结果。 - */ -export function resolvePageSize(page: PageSettings): ResolvedPageSize { - const base = resolveBaseSize(page) - return page.orientation === "landscape" - ? { width: base.height, height: base.width } - : { width: base.width, height: base.height } -} - -function resolveBaseSize(page: PageSettings): ResolvedPageSize { - if (page.paper === "custom") { - return { - width: page.customSize?.width ?? PAPER_SIZES_MM.A4.width, - height: page.customSize?.height ?? PAPER_SIZES_MM.A4.height, - } - } - const size = PAPER_SIZES_MM[page.paper] - return { width: size.width, height: size.height } -} - -/** - * 纸张内容区尺寸(扣除页边距后,mm)。 - * - * 分页计算的可排版高度即来自这里。 - */ -export function resolveContentBox(page: PageSettings): { - width: number - height: number - x: number - y: number -} { - const size = resolvePageSize(page) - return { - x: page.margin.left, - y: page.margin.top, - width: Math.max(0, size.width - page.margin.left - page.margin.right), - height: Math.max(0, size.height - page.margin.top - page.margin.bottom), - } -} diff --git a/code/one-designer/packages/report-core/src/model/parameter.ts b/code/one-designer/packages/report-core/src/model/parameter.ts deleted file mode 100644 index 590c771b..00000000 --- a/code/one-designer/packages/report-core/src/model/parameter.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 报表参数契约(对应设计文档 §8)。 - * - * 参数是设计期声明、运行期注入的输入。文档只保存声明, - * 实际取值由 RenderContext.parameters 提供。 - */ -import type { DatasetFieldType } from "./datasource.js" - -/** 参数值类型。 */ -export type ParameterValueType = Exclude - -/** 报表参数声明。 */ -export interface ReportParameter { - id: string - /** 参数名,表达式通过 params. 访问。 */ - name: string - type?: ParameterValueType - /** 展示名。 */ - label?: string - /** 默认值。必须是纯数据。 */ - defaultValue?: unknown - /** 是否必填。 */ - required?: boolean - /** 可选项,用于枚举型参数。 */ - options?: ParameterOption[] - /** 帮助文本。 */ - description?: string -} - -/** 枚举型参数的候选项。 */ -export interface ParameterOption { - label: string - value: string | number | boolean -} - -/** 判断参数名是否可用于表达式(合法的标识符)。 */ -export function isValidParameterName(name: string): boolean { - return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) -} diff --git a/code/one-designer/packages/report-core/src/model/report.ts b/code/one-designer/packages/report-core/src/model/report.ts deleted file mode 100644 index 5123cfcc..00000000 --- a/code/one-designer/packages/report-core/src/model/report.ts +++ /dev/null @@ -1,90 +0,0 @@ -/** - * 报表文档根模型(对应设计文档 §6)。 - * - * 原则(§3.2):ReportDocument 只保存可序列化的报表定义,不保存 - * 当前选中项、缩放比例、滚动位置、辅助线、撤销栈,以及已加载的数据 - * 和网络连接。任何编辑器状态都必须留在 Designer 侧。 - */ -import type { PageSettings } from "./page.js" -import type { ReportSection } from "./section.js" -import type { StyleDefinition } from "./style.js" -import type { DataSourceDefinition } from "./datasource.js" -import type { DatasetDefinition } from "./datasource.js" -import type { ReportParameter } from "./parameter.js" - -/** 插件引用。只保存 id、version 和配置(§11)。 */ -export interface ReportPluginReference { - id: string - version: string - config?: Record -} - -/** 文档元信息。 */ -export interface ReportMetadata { - title?: string - description?: string - author?: string - /** ISO 8601 时间字符串。 */ - createdAt?: string - updatedAt?: string - /** 宿主自定义标签。 */ - tags?: string[] - [key: string]: unknown -} - -/** 报表文档。 */ -export interface ReportDocument { - schemaVersion: number - - id: string - name: string - - page: PageSettings - - styles: Record - - dataSources: Record - datasets: Record - parameters: Record - - sections: ReportSection[] - - plugins?: ReportPluginReference[] - metadata?: ReportMetadata -} - -/** 按区域种类查找区域。 */ -export function findSectionsByKind( - document: ReportDocument, - kind: ReportSection["kind"], -): ReportSection[] { - return document.sections.filter((section) => section.kind === kind) -} - -/** 取第一个匹配的区域。 */ -export function findFirstSection( - document: ReportDocument, - kind: ReportSection["kind"], -): ReportSection | undefined { - return document.sections.find((section) => section.kind === kind) -} - -/** 收集文档中所有元素的 ID(含嵌套)。 */ -export function collectElementIds(document: ReportDocument): Set { - const ids = new Set() - const walk = (elements: readonly import("./element.js").ReportElement[]): void => { - for (const element of elements) { - ids.add(element.id) - if (element.children?.length) walk(element.children) - const columns = (element as { columns?: readonly import("./table.js").TableColumn[] }) - .columns - if (columns?.length) { - for (const column of columns) { - if (column.children?.length) walk(column.children) - } - } - } - } - for (const section of document.sections) walk(section.children) - return ids -} diff --git a/code/one-designer/packages/report-core/src/model/runtime.ts b/code/one-designer/packages/report-core/src/model/runtime.ts deleted file mode 100644 index d775282b..00000000 --- a/code/one-designer/packages/report-core/src/model/runtime.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * 运行时数据契约(对应设计文档 §8)。 - * - * 报表文档只保存数据源定义,不保存连接、Token 和本次查询结果。 - * 运行时数据通过 RenderContext 注入,取数能力通过 DataProvider 注入。 - * - * 放在 core 而非 layout:这两个契约是**跨包**的—— - * Designer 需要构造 RenderContext 做预览,Layout 需要消费它, - * 若定义在 layout 则 Designer 必须依赖 layout 才能构造上下文。 - */ -import type { DatasetDefinition } from "./datasource.js" - -/** 渲染上下文(§8)。 */ -export interface RenderContext { - /** - * 数据集数据:datasetId → 行数组。 - * - * 宿主预先取数后注入;Core 与 Layout 都不主动访问网络或数据库。 - */ - data: Record>> - /** 报表参数。 */ - parameters: Record - locale?: string - timezone?: string -} - -/** - * 数据提供器(§8)。 - * - * 由宿主实现。当 RenderContext 中缺少某数据集时按需调用, - * 使 Core/Layout 保持与具体数据访问技术无关。 - */ -export interface DataProvider { - getDataset( - dataset: DatasetDefinition, - context: RenderContext, - ): Promise>> -} - -/** 创建空的渲染上下文。 */ -export function createEmptyRenderContext(): RenderContext { - return { data: {}, parameters: {} } -} diff --git a/code/one-designer/packages/report-core/src/model/section.ts b/code/one-designer/packages/report-core/src/model/section.ts deleted file mode 100644 index c72245de..00000000 --- a/code/one-designer/packages/report-core/src/model/section.ts +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 报表区域模型(对应设计文档 §6.1)。 - * - * V1 先实现 page-header、detail 和 page-footer,其他区域只保留模型扩展点。 - */ -import type { ReportElement } from "./element.js" - -/** 区域种类。 */ -export type ReportSectionKind = - | "report-header" - | "page-header" - | "detail" - | "group-header" - | "group-footer" - | "summary" - | "page-footer" - -/** V1 实际实现渲染的区域。 */ -export const V1_SECTION_KINDS: readonly ReportSectionKind[] = [ - "page-header", - "detail", - "page-footer", -] - -/** 分组相关区域。 */ -export const GROUP_SECTION_KINDS: readonly ReportSectionKind[] = [ - "group-header", - "group-footer", -] - -/** 仅保留模型扩展点、尚未实现渲染的区域。 */ -export const RESERVED_SECTION_KINDS: readonly ReportSectionKind[] = [ - "report-header", - "summary", -] - -/** 判断是否为分组区域。 */ -export function isGroupSectionKind(kind: ReportSectionKind): boolean { - return GROUP_SECTION_KINDS.includes(kind) -} - -/** 区域级选项。 */ -export interface ReportSectionOptions { - /** 每页重复(页眉页脚用)。 */ - repeatOnEachPage?: boolean - /** 尽量不与后续内容分离。 */ - keepTogether?: boolean - /** 是否允许跨页拆分。 */ - allowSplit?: boolean -} - -/** 报表区域。 */ -export interface ReportSection { - id: string - kind: ReportSectionKind - /** 绑定的数据集,仅 detail / group-* 有意义。 */ - datasetId?: string - children: ReportElement[] - options?: ReportSectionOptions - /** 区域高度(mm)。detail 区域可省略,由内容决定。 */ - height?: number - name?: string - /** - * 分组键表达式,仅 group-header / group-footer 使用。 - * - * 例如 "row.category"。相邻行该值相同即属于同一组。 - * 表达式在数据集行作用域下求值(可访问 row / index / rownumber)。 - */ - groupExpression?: string - /** 分组级别,从 1 开始。数值小的为外层组。用于多级分组排序。 */ - groupLevel?: number - /** - * 组变更时是否强制换页(即每个分组独占一页起始)。 - */ - pageBreakBefore?: boolean -} - -/** 判断区域种类是否为 V1 实现范围。 */ -export function isV1SectionKind(kind: ReportSectionKind): boolean { - return V1_SECTION_KINDS.includes(kind) -} - -/** 创建区域。 */ -export function createSection( - id: string, - kind: ReportSectionKind, - children: ReportElement[] = [], -): ReportSection { - const section: ReportSection = { id, kind, children } - if (kind === "page-header" || kind === "page-footer") { - section.options = { repeatOnEachPage: true, keepTogether: true } - } - return section -} diff --git a/code/one-designer/packages/report-core/src/model/style.ts b/code/one-designer/packages/report-core/src/model/style.ts deleted file mode 100644 index 32cbdf46..00000000 --- a/code/one-designer/packages/report-core/src/model/style.ts +++ /dev/null @@ -1,149 +0,0 @@ -/** - * 样式模型(对应设计文档 §6.4)。 - * - * 样式通过 ID 复用,并允许有限的继承(extends)和元素级覆盖。 - * 继承链在解析阶段展开,运行时不保留链式查找,避免深层继承带来的 - * 性能与可预测性问题。 - */ -import type { - BorderStyle, - HorizontalAlign, - VerticalAlign, -} from "./common.js" - -/** 样式定义。 */ -export interface StyleDefinition { - id: string - /** 继承的父样式 ID。 */ - extends?: string - - fontFamily?: string - /** 字号,单位 pt(排版惯例),Layout 阶段换算为目标单位。 */ - fontSize?: number - fontWeight?: "normal" | "bold" | number - fontStyle?: "normal" | "italic" - /** 行高倍数,1 表示与字号等高的紧凑行距。 */ - lineHeight?: number - color?: string - background?: string - - border?: BorderStyle - padding?: Partial> - - align?: HorizontalAlign - verticalAlign?: VerticalAlign - - /** 文本装饰。 */ - textDecoration?: "none" | "underline" | "line-through" - - /** 元素级覆盖允许出现任意额外键,由 Layout/Renderer 按需解释。 */ - [key: string]: unknown -} - -/** 已解析的样式:所有继承链已展开,可直接消费。 */ -export interface ResolvedStyle { - fontFamily: string - fontSize: number - fontWeight: "normal" | "bold" | number - fontStyle: "normal" | "italic" - lineHeight: number - color: string - background: string - border?: BorderStyle - padding: { top: number; right: number; bottom: number; left: number } - align: HorizontalAlign - verticalAlign: VerticalAlign - textDecoration: "none" | "underline" | "line-through" -} - -/** 默认已解析样式。 */ -export const DEFAULT_RESOLVED_STYLE: ResolvedStyle = Object.freeze({ - fontFamily: "sans-serif", - fontSize: 10, - fontWeight: "normal" as const, - fontStyle: "normal" as const, - lineHeight: 1.2, - color: "#000000", - background: "transparent", - padding: Object.freeze({ top: 0, right: 0, bottom: 0, left: 0 }), - align: "left" as const, - verticalAlign: "top" as const, - textDecoration: "none" as const, -}) - -/** - * 解析单条样式定义,可选地叠加元素级覆盖。 - * - * 只处理当前层,不跟随 extends;继承链的展开由 resolveStyleChain 完成。 - */ -export function mergeStyleOverride( - base: ResolvedStyle, - definition: StyleDefinition | undefined, -): ResolvedStyle { - if (!definition) return base - const out: ResolvedStyle = { ...base } - if (definition.fontFamily !== undefined) out.fontFamily = definition.fontFamily - if (definition.fontSize !== undefined) out.fontSize = definition.fontSize - if (definition.fontWeight !== undefined) out.fontWeight = definition.fontWeight - if (definition.fontStyle !== undefined) out.fontStyle = definition.fontStyle - if (definition.lineHeight !== undefined) out.lineHeight = definition.lineHeight - if (definition.color !== undefined) out.color = definition.color - if (definition.background !== undefined) out.background = definition.background - if (definition.border !== undefined) out.border = definition.border - if (definition.align !== undefined) out.align = definition.align - if (definition.verticalAlign !== undefined) out.verticalAlign = definition.verticalAlign - if (definition.textDecoration !== undefined) out.textDecoration = definition.textDecoration - if (definition.padding !== undefined) { - out.padding = { - top: definition.padding.top ?? base.padding.top, - right: definition.padding.right ?? base.padding.right, - bottom: definition.padding.bottom ?? base.padding.bottom, - left: definition.padding.left ?? base.padding.left, - } - } - return out -} - -/** 继承链解析结果。 */ -export interface StyleResolution { - style: ResolvedStyle - /** 检测到的循环继承链,非空表示解析失败并已回退到默认样式。 */ - cycle?: string[] -} - -/** - * 展开样式继承链。 - * - * 遇到循环继承时不抛异常,而是返回 cycle 信息并回退到默认样式, - * 交由调用方转成诊断信息(§13)。 - */ -export function resolveStyleChain( - styleId: string | undefined, - styles: Readonly>, -): StyleResolution { - if (!styleId) return { style: DEFAULT_RESOLVED_STYLE } - - const chain: StyleDefinition[] = [] - const seen = new Set() - const order: string[] = [] - - let currentId: string | undefined = styleId - while (currentId) { - if (seen.has(currentId)) { - return { style: DEFAULT_RESOLVED_STYLE, cycle: [...order, currentId] } - } - const definition: StyleDefinition | undefined = styles[currentId] - if (!definition) break - seen.add(currentId) - order.push(currentId) - chain.push(definition) - currentId = definition.extends - } - - // 从最基类开始应用,保证子类覆盖父类 - let resolved: ResolvedStyle = DEFAULT_RESOLVED_STYLE - for (let i = chain.length - 1; i >= 0; i -= 1) { - resolved = mergeStyleOverride(resolved, chain[i]) - } - return { style: resolved } -} diff --git a/code/one-designer/packages/report-core/src/model/table.ts b/code/one-designer/packages/report-core/src/model/table.ts deleted file mode 100644 index 16672e7b..00000000 --- a/code/one-designer/packages/report-core/src/model/table.ts +++ /dev/null @@ -1,81 +0,0 @@ -/** - * 明细表模型(对应设计文档 §6.3)。 - * - * 明细表是 V1 的特殊元素,负责把数据集展开成多行。 - * 单元格内的元素坐标相对于当前单元格。 - */ -import type { Rect } from "./common.js" -import type { ReportElement, ValueBinding } from "./element.js" - -/** 表格列。 */ -export interface TableColumn { - id: string - /** 列宽(mm)。 */ - width: number - /** 表头文本。 */ - header?: string - /** 表头绑定,存在时优先于 header 字面量。 */ - headerBinding?: ValueBinding - /** 单元格整列绑定。 */ - binding?: ValueBinding - /** 单元格内自由布局的元素,坐标相对于单元格左上角。 */ - children?: ReportElement[] - /** 列级样式。 */ - styleId?: string - align?: "left" | "center" | "right" -} - -/** 行高策略。 */ -export type RowHeightMode = "auto" | "fixed" - -/** 明细表元素。 */ -export interface TableElement extends ReportElement { - type: "table" - /** 展开所用的数据集。 */ - datasetId: string - columns: TableColumn[] - /** 每页重复表头。 */ - repeatHeaderOnEachPage?: boolean - /** 表头行高度(mm)。 */ - headerHeight?: number - /** 数据行高度(mm)。 */ - rowHeight?: number - /** 行高模式。auto 表示按内容动态撑高。 */ - rowHeightMode?: RowHeightMode - /** 表格级边框与网格线。 */ - showGrid?: boolean - /** 无数据时的占位文本。 */ - emptyText?: string -} - -/** 判断元素是否为明细表。 */ -export function isTableElement(element: ReportElement): element is TableElement { - return element.type === "table" && Array.isArray((element as TableElement).columns) -} - -/** 表格总宽度(mm)。 */ -export function measureTableWidth(table: TableElement): number { - return table.columns.reduce((sum, column) => sum + (column.width ?? 0), 0) -} - -/** 创建明细表元素。 */ -export function createTableElement( - id: string, - frame: Rect, - datasetId: string, - columns: TableColumn[] = [], -): TableElement { - return { - id, - type: "table", - frame, - datasetId, - columns, - repeatHeaderOnEachPage: true, - headerHeight: 8, - rowHeight: 7, - rowHeightMode: "fixed", - showGrid: true, - emptyText: "无数据", - } -} diff --git a/code/one-designer/packages/report-core/src/plugin/context.ts b/code/one-designer/packages/report-core/src/plugin/context.ts deleted file mode 100644 index b1bed0bc..00000000 --- a/code/one-designer/packages/report-core/src/plugin/context.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 插件上下文(对应设计文档 §11)。 - * - * 只暴露注册所需的最小信息,不暴露文档内部结构。 - */ -export type { PluginContext, PluginKind, ReportPlugin } from "./plugin.js" diff --git a/code/one-designer/packages/report-core/src/plugin/datasource-plugin.ts b/code/one-designer/packages/report-core/src/plugin/datasource-plugin.ts deleted file mode 100644 index fa2f866f..00000000 --- a/code/one-designer/packages/report-core/src/plugin/datasource-plugin.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 数据源插件契约(对应设计文档 §11)。 - */ -export type { DataSourcePlugin } from "./plugin.js" diff --git a/code/one-designer/packages/report-core/src/plugin/element-plugin.ts b/code/one-designer/packages/report-core/src/plugin/element-plugin.ts deleted file mode 100644 index caa97edc..00000000 --- a/code/one-designer/packages/report-core/src/plugin/element-plugin.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 元素插件契约(对应设计文档 §11)。 - * - * 单独成文件,方便插件作者只依赖这一个入口而不引入整个 core。 - */ -export type { ElementPlugin } from "./plugin.js" diff --git a/code/one-designer/packages/report-core/src/plugin/exporter-plugin.ts b/code/one-designer/packages/report-core/src/plugin/exporter-plugin.ts deleted file mode 100644 index cf3d2fc6..00000000 --- a/code/one-designer/packages/report-core/src/plugin/exporter-plugin.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 导出器插件契约(对应设计文档 §11)。 - * - * 用于 HTML / SVG / PDF 之外的自定义输出目标。 - */ -export type { ExporterPlugin } from "./plugin.js" diff --git a/code/one-designer/packages/report-core/src/plugin/plugin.ts b/code/one-designer/packages/report-core/src/plugin/plugin.ts deleted file mode 100644 index 290188d1..00000000 --- a/code/one-designer/packages/report-core/src/plugin/plugin.ts +++ /dev/null @@ -1,147 +0,0 @@ -/** - * 插件契约(对应设计文档 §11)。 - * - * 核心约束:插件只通过契约接入,不允许 Core 直接导入插件实现。 - * 插件引用只保存 id、version 和配置;插件缺失时应产生诊断信息, - * 而不是阻止整个文档被读取。 - */ -import type { ReportElement } from "../model/element.js" -import type { DataSourceDefinition } from "../model/datasource.js" - -/** 插件类型标识。 */ -export type PluginKind = "element" | "datasource" | "exporter" - -/** - * 元素插件。 - * - * schema 使用「未知形状」是有意为之:Core 不绑定任何具体校验库, - * 宿主可以传 JSON Schema、Zod、Valibot 或自定义描述,Core 只做透传 - * 和存在性检查,具体校验由插件适配器负责。 - */ -export interface ElementPlugin { - /** 元素类型标识,对应 ReportElement.type。 */ - type: string - /** 插件展示名。 */ - label?: string - /** 是否允许包含子元素,用于校验和 Designer 交互。 */ - isContainer?: boolean - /** props 的结构描述,由插件自行解释。 */ - schema?: unknown - /** 创建一个带默认 props 的实例。 */ - createDefault(options?: { id?: string; frame?: ReportElement["frame"] }): ReportElement - /** 可选:校验 props,返回错误消息数组(空数组表示通过)。 */ - validate?(element: ReportElement): string[] - /** 可选:为外部资源声明允许的来源,供 Renderer 做安全校验。 */ - externalResources?: "none" | "image" | "any" -} - -/** 数据源插件。 */ -export interface DataSourcePlugin { - /** 数据源类型标识,对应 DataSourceDefinition.type。 */ - type: string - label?: string - /** 默认配置,用于 Designer 新建数据源。 */ - createDefaultConfig?(): Record -} - -/** 导出器插件。用于 HTML / SVG / PDF 之外的额外输出目标。 */ -export interface ExporterPlugin { - /** 导出目标标识,如 "pdf"、"png"。 */ - format: string - label?: string -} - -/** 插件包。 */ -export interface ReportPlugin { - id: string - version: string - /** 插件声明兼容的 core schema 版本范围描述,仅作提示与诊断。 */ - compatibleSchemaVersion?: string - elements?: ElementPlugin[] - datasources?: DataSourcePlugin[] - exporters?: ExporterPlugin[] - /** 插件初始化钩子,用于注册适配器等。 */ - setup?(context: PluginContext): void -} - -/** - * 插件上下文。 - * - * 只暴露注册能力,不暴露文档内部结构,避免插件反向操纵 Core 状态。 - */ -export interface PluginContext { - pluginId: string - pluginVersion: string - /** 当前 core 支持的 schema 版本。 */ - schemaVersion: number -} - -/** - * 版本兼容性判断(语义化版本的宽松实现)。 - * - * requirement 支持 ">=1.0.0"、"^1.2.0"、"1.x"、"*"。 - * 无法解析时返回 true 并交由诊断提示,避免因解析失败阻断插件加载。 - */ -export function isVersionCompatible(version: string, requirement?: string): boolean { - if (!requirement || requirement === "*") return true - const actual = parseVersion(version) - if (!actual) return true - - const match = requirement.trim().match(/^(>=|\^|~)?\s*v?(\d+)(?:\.(\d+|x|\*))?(?:\.(\d+|x|\*))?$/) - if (!match) return true - - const operator = match[1] ?? "" - const major = Number(match[2]) - const minorRaw = match[3] - const minor = minorRaw === undefined || minorRaw === "x" || minorRaw === "*" - ? undefined - : Number(minorRaw) - - switch (operator) { - case ">=": - if (actual.major !== major) return actual.major > major - if (minor === undefined) return true - return actual.minor >= minor - case "^": - return actual.major === major - case "~": - return actual.major === major && (minor === undefined || actual.minor === minor) - default: - // 无操作符:按 major 匹配,minor 缺省视为任意 - if (actual.major !== major) return false - return minor === undefined || actual.minor === minor - } -} - -interface ParsedVersion { - major: number - minor: number - patch: number -} - -function parseVersion(version: string): ParsedVersion | null { - const match = version.trim().match(/^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?/) - if (!match) return null - return { - major: Number(match[1]), - minor: Number(match[2] ?? 0), - patch: Number(match[3] ?? 0), - } -} - -/** 从数据源定义创建插件所需的最小信息(用于诊断)。 */ -export interface MissingPluginInfo { - pluginId: string - version: string - kind: PluginKind - /** 用到该插件的元素 ID 或数据源 ID。 */ - usedBy?: string -} - -/** 依据数据源定义判断所需的插件。 */ -export function describeDataSourcePlugin( - source: DataSourceDefinition, -): MissingPluginInfo | null { - if (!source.type) return null - return { pluginId: source.type, version: "*", kind: "datasource", usedBy: source.id } -} diff --git a/code/one-designer/packages/report-core/src/plugin/registry.ts b/code/one-designer/packages/report-core/src/plugin/registry.ts deleted file mode 100644 index 9f2c1c2f..00000000 --- a/code/one-designer/packages/report-core/src/plugin/registry.ts +++ /dev/null @@ -1,257 +0,0 @@ -/** - * 插件注册表(对应设计文档 §11 与 §4.1)。 - * - * 职责: - * - 保存已注册插件,提供按类型查找元素插件的能力。 - * - 对缺插件与版本不兼容产出诊断(§13),而不是抛异常。 - * - 不导入任何具体插件实现,只接受契约对象。 - */ -import type { Diagnostic } from "../model/common.js" -import { DIAGNOSTIC_CODES, type DiagnosticBag } from "../diagnostics/diagnostic.js" -import { CURRENT_SCHEMA_VERSION } from "../schema/version.js" -import { - isVersionCompatible, - type DataSourcePlugin, - type ElementPlugin, - type ExporterPlugin, - type MissingPluginInfo, - type PluginContext, - type ReportPlugin, -} from "./plugin.js" - -/** 注册结果。 */ -export interface RegisterResult { - ok: boolean - diagnostics: Diagnostic[] -} - -/** - * 插件注册表。 - * - * 一个注册表实例对应一个运行时(Editor 或 Renderer)。Core 本身不持有 - * 全局单例,避免在 SSR / 多文档场景下互相污染。 - */ -export class PluginRegistry { - private readonly plugins = new Map() - private readonly elementPlugins = new Map() - private readonly dataSourcePlugins = new Map() - private readonly exporterPlugins = new Map() - - /** 注册一个插件。重复注册同 id 时返回失败诊断(不覆盖)。 */ - register(plugin: ReportPlugin): RegisterResult { - const diagnostics: Diagnostic[] = [] - - if (!plugin.id) { - diagnostics.push({ - severity: "error", - code: DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, - message: "插件缺少 id", - }) - return { ok: false, diagnostics } - } - - if (this.plugins.has(plugin.id)) { - diagnostics.push({ - severity: "error", - code: DIAGNOSTIC_CODES.PLUGIN_ALREADY_REGISTERED, - message: `插件 "${plugin.id}" 已注册,忽略重复注册`, - }) - return { ok: false, diagnostics } - } - - // 版本兼容性:不匹配时产生警告但仍然注册,避免阻断打开文档 - if ( - plugin.compatibleSchemaVersion && - !isVersionCompatible(String(CURRENT_SCHEMA_VERSION), plugin.compatibleSchemaVersion) - ) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.PLUGIN_VERSION_INCOMPATIBLE, - message: - `插件 "${plugin.id}@${plugin.version}" 声明兼容 ${plugin.compatibleSchemaVersion},` + - `当前 schema 为 ${CURRENT_SCHEMA_VERSION}`, - }) - } - - // 元素类型冲突检查 - for (const element of plugin.elements ?? []) { - const existing = this.elementPlugins.get(element.type) - if (existing) { - diagnostics.push({ - severity: "error", - code: DIAGNOSTIC_CODES.PLUGIN_ALREADY_REGISTERED, - message: `元素类型 "${element.type}" 已被其他插件注册`, - }) - return { ok: false, diagnostics } - } - } - - this.plugins.set(plugin.id, plugin) - for (const element of plugin.elements ?? []) { - this.elementPlugins.set(element.type, element) - } - for (const datasource of plugin.datasources ?? []) { - this.dataSourcePlugins.set(datasource.type, datasource) - } - for (const exporter of plugin.exporters ?? []) { - this.exporterPlugins.set(exporter.format, exporter) - } - - if (plugin.setup) { - const context: PluginContext = { - pluginId: plugin.id, - pluginVersion: plugin.version, - schemaVersion: CURRENT_SCHEMA_VERSION, - } - plugin.setup(context) - } - - return { ok: true, diagnostics } - } - - /** 批量注册。 */ - registerAll(plugins: readonly ReportPlugin[]): RegisterResult { - const diagnostics: Diagnostic[] = [] - let ok = true - for (const plugin of plugins) { - const result = this.register(plugin) - diagnostics.push(...result.diagnostics) - if (!result.ok) ok = false - } - return { ok, diagnostics } - } - - /** 注销插件。 */ - unregister(pluginId: string): boolean { - const plugin = this.plugins.get(pluginId) - if (!plugin) return false - for (const element of plugin.elements ?? []) this.elementPlugins.delete(element.type) - for (const datasource of plugin.datasources ?? []) this.dataSourcePlugins.delete(datasource.type) - for (const exporter of plugin.exporters ?? []) this.exporterPlugins.delete(exporter.format) - this.plugins.delete(pluginId) - return true - } - - has(pluginId: string): boolean { - return this.plugins.has(pluginId) - } - - get(pluginId: string): ReportPlugin | undefined { - return this.plugins.get(pluginId) - } - - /** 按元素类型取插件。 */ - getElementPlugin(type: string): ElementPlugin | undefined { - return this.elementPlugins.get(type) - } - - getDataSourcePlugin(type: string): DataSourcePlugin | undefined { - return this.dataSourcePlugins.get(type) - } - - getExporterPlugin(format: string): ExporterPlugin | undefined { - return this.exporterPlugins.get(format) - } - - /** 已注册的全部元素类型,供校验判断元素是否合法。 */ - elementTypes(): Set { - return new Set(this.elementPlugins.keys()) - } - - /** 允许包含子元素的插件类型。 */ - containerTypes(): Set { - const out = new Set() - for (const [type, plugin] of this.elementPlugins) { - if (plugin.isContainer) out.add(type) - } - return out - } - - list(): ReportPlugin[] { - return [...this.plugins.values()] - } - - clear(): void { - this.plugins.clear() - this.elementPlugins.clear() - this.dataSourcePlugins.clear() - this.exporterPlugins.clear() - } - - /** - * 检查文档声明的插件引用是否都已注册(§11)。 - * - * 缺失或版本不匹配只产生诊断,不阻止文档读取。 - */ - checkReferences( - references: readonly { id: string; version: string }[] | undefined, - ): Diagnostic[] { - const diagnostics: Diagnostic[] = [] - for (const reference of references ?? []) { - const plugin = this.plugins.get(reference.id) - if (!plugin) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.PLUGIN_MISSING, - message: `文档引用的插件 "${reference.id}" 未注册,相关元素将无法正确布局或渲染`, - }) - continue - } - if (reference.version && !isVersionCompatible(plugin.version, reference.version)) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.PLUGIN_VERSION_INCOMPATIBLE, - message: - `文档要求插件 "${reference.id}" 版本 ${reference.version},` + - `当前注册的是 ${plugin.version}`, - }) - } - } - return diagnostics - } - - /** 收集文档中实际用到但未注册的插件,便于给出可定位诊断。 */ - collectMissing(infos: readonly MissingPluginInfo[]): Diagnostic[] { - const diagnostics: Diagnostic[] = [] - for (const info of infos) { - const registered = - info.kind === "element" - ? this.elementPlugins.has(info.pluginId) - : info.kind === "datasource" - ? this.dataSourcePlugins.has(info.pluginId) - : this.exporterPlugins.has(info.pluginId) - if (!registered) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.PLUGIN_MISSING, - message: `缺少提供 "${info.pluginId}" 的${describeKind(info.kind)}插件`, - ...(info.usedBy ? { elementId: info.usedBy } :{}), - }) - } - } - return diagnostics - } -} - -function describeKind(kind: MissingPluginInfo["kind"]): string { - switch (kind) { - case "element": - return "元素" - case "datasource": - return "数据源" - case "exporter": - return "导出器" - } -} - -/** 把注册结果里的诊断写入收集器。 */ -export function reportRegisterResult(bag: DiagnosticBag, result: RegisterResult): void { - for (const diagnostic of result.diagnostics) bag.add(diagnostic) -} - -/** 创建一个空的注册表。 */ -export function createPluginRegistry(plugins: readonly ReportPlugin[] = []): PluginRegistry { - const registry = new PluginRegistry() - registry.registerAll(plugins) - return registry -} diff --git a/code/one-designer/packages/report-core/src/schema/defaults.ts b/code/one-designer/packages/report-core/src/schema/defaults.ts deleted file mode 100644 index d186a4ee..00000000 --- a/code/one-designer/packages/report-core/src/schema/defaults.ts +++ /dev/null @@ -1,195 +0,0 @@ -/** - * 默认值(对应设计文档 §12 的 normalize 阶段和 §16 阶段 1)。 - * - * 默认值的唯一来源。create / deserialize 都通过这里补齐缺省字段, - * 保证「新建文档」和「读取旧文档」得到一致的结构。 - */ -import { createDefaultPageSettings, type PageSettings } from "../model/page.js" -import type { ReportDocument, ReportMetadata } from "../model/report.js" -import type { ReportSection, ReportSectionKind } from "../model/section.js" -import type { ReportElement } from "../model/element.js" -import type { TableColumn, TableElement } from "../model/table.js" -import type { Rect } from "../model/common.js" -import { createElementId, createSectionId } from "../utils/id.js" - -/** 新元素的默认尺寸(mm)。 */ -export const DEFAULT_ELEMENT_SIZE: Readonly> = - Object.freeze({ - text: { width: 40, height: 8 }, - image: { width: 40, height: 30 }, - line: { width: 40, height: 0.2 }, - rect: { width: 40, height: 20 }, - container: { width: 60, height: 40 }, - table: { width: 180, height: 40 }, - }) - -/** 未知类型元素的兜底尺寸。 */ -export const FALLBACK_ELEMENT_SIZE = Object.freeze({ width: 30, height: 10 }) - -/** 取某类型元素的默认尺寸。 */ -export function getDefaultElementSize(type: string): { width: number; height: number } { - return DEFAULT_ELEMENT_SIZE[type] ?? FALLBACK_ELEMENT_SIZE -} - -/** 默认矩形。 */ -export function createDefaultFrame(type: string, x = 0, y = 0): Rect { - const size = getDefaultElementSize(type) - return { x, y, width: size.width, height: size.height } -} - -/** 默认页面设置。 */ -export { createDefaultPageSettings } - -/** 默认区域选项。 */ -export function createDefaultSectionOptions( - kind: ReportSectionKind, -): ReportSection["options"] { - if (kind === "page-header" || kind === "page-footer") { - return { repeatOnEachPage: true, keepTogether: true } - } - if (kind === "detail") { - return { allowSplit: true } - } - return undefined -} - -/** 默认表格列。 */ -export function createDefaultTableColumn(width = 30): TableColumn { - return { id: `col_${Math.random().toString(36).slice(2, 10)}`, width } -} - -/** 默认明细表。 */ -export function createDefaultTable( - id: string, - datasetId: string, - frame?: Rect, -): TableElement { - return { - id, - type: "table", - frame: frame ?? createDefaultFrame("table"), - datasetId, - columns: [], - repeatHeaderOnEachPage: true, - headerHeight: 8, - rowHeight: 7, - rowHeightMode: "fixed", - showGrid: true, - emptyText: "无数据", - } -} - -/** 默认元信息。 */ -export function createDefaultMetadata(name: string): ReportMetadata { - return { - title: name, - createdAt: new Date().toISOString(), - } -} - -/** - * 元素的缺省字段表。 - * - * 用于 normalize 阶段给缺字段补默认值。注意这里只给「结构性」字段 - * 补默认,不给 props 里的业务字段补,避免把插件的语义写死在 core。 - */ -export function normalizeElement(element: ReportElement): ReportElement { - const out: ReportElement = { - id: element.id ?? createElementId(), - type: element.type ?? "text", - frame: normalizeRect(element.frame, element.type ?? "text"), - } - if (element.styleId !== undefined) out.styleId = element.styleId - if (element.binding !== undefined) out.binding = element.binding - if (element.props !== undefined) out.props = element.props - if (element.style !== undefined) out.style = element.style - if (element.name !== undefined) out.name = element.name - if (element.locked !== undefined) out.locked = element.locked - if (element.hidden !== undefined) out.hidden = element.hidden - if (element.children !== undefined) { - out.children = element.children.map(normalizeElement) - } - if (element.type === "table") { - const table = element as TableElement - const columns = Array.isArray(table.columns) ? table.columns : [] - ;(out as TableElement).datasetId = table.datasetId - ;(out as TableElement).columns = columns.map(normalizeColumn) - if (table.repeatHeaderOnEachPage !== undefined) { - ;(out as TableElement).repeatHeaderOnEachPage = table.repeatHeaderOnEachPage - } - if (table.headerHeight !== undefined) (out as TableElement).headerHeight = table.headerHeight - if (table.rowHeight !== undefined) (out as TableElement).rowHeight = table.rowHeight - if (table.rowHeightMode !== undefined) (out as TableElement).rowHeightMode = table.rowHeightMode - if (table.showGrid !== undefined) (out as TableElement).showGrid = table.showGrid - if (table.emptyText !== undefined) (out as TableElement).emptyText = table.emptyText - } - return out -} - -/** 规格化矩形:缺失字段补 0,负宽高取绝对值。 */ -export function normalizeRect(rect: Rect | undefined, type: string): Rect { - const fallback = createDefaultFrame(type) - if (!rect) return fallback - return { - x: Number.isFinite(rect.x) ? rect.x : 0, - y: Number.isFinite(rect.y) ? rect.y : 0, - width: Number.isFinite(rect.width) ? Math.abs(rect.width) : fallback.width, - height: Number.isFinite(rect.height) ? Math.abs(rect.height) : fallback.height, - } -} - -/** 规格化表格列。 */ -export function normalizeColumn(column: TableColumn): TableColumn { - const out: TableColumn = { - id: column.id ?? createDefaultTableColumn().id, - width: Number.isFinite(column.width) ? Math.abs(column.width) : 30, - } - if (column.header !== undefined) out.header = column.header - if (column.headerBinding !== undefined) out.headerBinding = column.headerBinding - if (column.binding !== undefined) out.binding = column.binding - if (column.styleId !== undefined) out.styleId = column.styleId - if (column.align !== undefined) out.align = column.align - if (column.children !== undefined) out.children = column.children.map(normalizeElement) - return out -} - -/** 规格化区域。 */ -export function normalizeSection(section: ReportSection): ReportSection { - const out: ReportSection = { - id: section.id ?? createSectionId(), - kind: section.kind ?? "detail", - children: (section.children ?? []).map(normalizeElement), - } - if (section.datasetId !== undefined) out.datasetId = section.datasetId - if (section.height !== undefined) out.height = section.height - if (section.name !== undefined) out.name = section.name - const options = section.options ?? createDefaultSectionOptions(out.kind) - if (options !== undefined) out.options = options - return out -} - -/** 新建空白文档所需的骨架(不含 id / name,由 create 决定)。 */ -export interface EmptyDocumentSkeleton { - page: PageSettings - styles: ReportDocument["styles"] - dataSources: ReportDocument["dataSources"] - datasets: ReportDocument["datasets"] - parameters: ReportDocument["parameters"] - sections: ReportSection[] -} - -/** 创建空白文档骨架:默认 A4 纵向 + 页眉 / 明细 / 页脚三个区域。 */ -export function createEmptyDocumentSkeleton(): EmptyDocumentSkeleton { - return { - page: createDefaultPageSettings(), - styles: {}, - dataSources: {}, - datasets: {}, - parameters: {}, - sections: [ - { id: createSectionId(), kind: "page-header", children: [], options: createDefaultSectionOptions("page-header") }, - { id: createSectionId(), kind: "detail", children: [], options: createDefaultSectionOptions("detail") }, - { id: createSectionId(), kind: "page-footer", children: [], options: createDefaultSectionOptions("page-footer") }, - ] as ReportSection[], - } -} diff --git a/code/one-designer/packages/report-core/src/schema/validation.ts b/code/one-designer/packages/report-core/src/schema/validation.ts deleted file mode 100644 index 10b4eef6..00000000 --- a/code/one-designer/packages/report-core/src/schema/validation.ts +++ /dev/null @@ -1,571 +0,0 @@ -/** - * 结构校验(对应设计文档 §12)。 - * - * 要求: - * - 校验错误必须指出字段路径和元素 ID。 - * - 校验不抛异常做业务控制,统一返回 Diagnostic[](§13)。 - * - * 校验分两级: - * - validateStructure:只检查 JSON 形状是否满足当前 schema,用于反序列化入口。 - * - validateDocument:在结构成立的基础上检查引用完整性、类型合法性和业务约束。 - */ -import type { Diagnostic } from "../model/common.js" -import { DIAGNOSTIC_CODES, error, toBag, warning, type DiagnosticBag } from "../diagnostics/diagnostic.js" -import { - isPlainData, - isPlainObject, -} from "../utils/deep.js" -import { isValidId } from "../utils/id.js" -import { - BUILTIN_ELEMENT_TYPES, - canHaveChildren, -} from "../model/element.js" -import { isV1SectionKind, RESERVED_SECTION_KINDS, type ReportSectionKind } from "../model/section.js" -import { isValidParameterName } from "../model/parameter.js" -import { isValidSchemaVersion, MIN_SCHEMA_VERSION } from "./version.js" - -/** 允许的区域种类全集。 */ -const ALL_SECTION_KINDS: readonly ReportSectionKind[] = [ - "report-header", - "page-header", - "detail", - "group-header", - "group-footer", - "summary", - "page-footer", -] - -const PAPER_KINDS = ["A4", "A5", "custom"] as const -const ORIENTATIONS = ["portrait", "landscape"] as const -const ALIGNMENTS = ["left", "center", "right"] as const - -/** 校验 JSON Pointer 路径拼接。 */ -function join(base: string, key: string | number): string { - return `${base}/${key}` -} - -/** - * 第一级:结构校验。 - * - * 只回答「这份 JSON 是否可能是 ReportDocument」,不检查引用完整性, - * 因为迁移阶段需要先通过这一关,之后才可能补齐缺失引用。 - */ -export function validateStructure(input: unknown): Diagnostic[] { - const diagnostics: Diagnostic[] = [] - const bag = { - error(code: string, message: string, extra?: { path?: string; elementId?: string }) { - diagnostics.push(error(code, message, extra)) - }, - warn(code: string, message: string, extra?: { path?: string; elementId?: string }) { - diagnostics.push(warning(code, message, extra)) - }, - } - - if (!isPlainObject(input)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_INVALID, "文档根节点必须是普通对象", { path: "/" }) - return diagnostics - } - - // schemaVersion - const rawVersion = (input as Record).schemaVersion - if (rawVersion === undefined) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_VERSION_MISSING, "缺少 schemaVersion 字段", { - path: "/schemaVersion", - }) - } else if (!isValidSchemaVersion(rawVersion)) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_VERSION_UNKNOWN, - `schemaVersion 必须是 >= ${MIN_SCHEMA_VERSION} 的整数,收到 ${JSON.stringify(rawVersion)}`, - { path: "/schemaVersion" }, - ) - } - - // 必填字符串 - for (const key of ["id", "name"] as const) { - const value = (input as Record)[key] - if (typeof value !== "string" || value.length === 0) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, `缺少必填字段 ${key}`, { - path: join("", key), - }) - } - } - - // page - const page = (input as Record).page - if (page === undefined) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, "缺少必填字段 page", { path: "/page" }) - } else if (!isPlainObject(page)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "page 必须是对象", { path: "/page" }) - } else { - const paper = (page as Record).paper - if (paper !== undefined && !PAPER_KINDS.includes(paper as (typeof PAPER_KINDS)[number])) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_ENUM_INVALID, - `page.paper 必须是 ${PAPER_KINDS.join(" / ")} 之一,收到 ${JSON.stringify(paper)}`, - { path: "/page/paper" }, - ) - } - const orientation = (page as Record).orientation - if ( - orientation !== undefined && - !ORIENTATIONS.includes(orientation as (typeof ORIENTATIONS)[number]) - ) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_ENUM_INVALID, - `page.orientation 必须是 portrait / landscape 之一`, - { path: "/page/orientation" }, - ) - } - const customSize = (page as Record).customSize - if (customSize !== undefined) { - if (!isPlainObject(customSize)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "page.customSize 必须是对象", { - path: "/page/customSize", - }) - } else { - for (const key of ["width", "height"] as const) { - const value = (customSize as Record)[key] - if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_RANGE_INVALID, - `page.customSize.${key} 必须是正数`, - { path: `/page/customSize/${key}` }, - ) - } - } - } - } - } - - // sections - const sections = (input as Record).sections - if (sections === undefined) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, "缺少必填字段 sections", { - path: "/sections", - }) - } else if (!Array.isArray(sections)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "sections 必须是数组", { path: "/sections" }) - } else { - sections.forEach((section, index) => { - const path = `/sections/${index}` - if (!isPlainObject(section)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "区域必须是对象", { path }) - return - } - const kind = (section as Record).kind - if (!ALL_SECTION_KINDS.includes(kind as ReportSectionKind)) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_ENUM_INVALID, - `未知的区域种类 ${JSON.stringify(kind)}`, - { path: `${path}/kind` }, - ) - } - const children = (section as Record).children - if (children !== undefined && !Array.isArray(children)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "区域 children 必须是数组", { - path: `${path}/children`, - }) - } - if (Array.isArray(children)) { - validateElementStructure(children, `${path}/children`, bag) - } - }) - } - - // 集合型字段 - for (const key of ["styles", "dataSources", "datasets", "parameters"] as const) { - const value = (input as Record)[key] - if (value !== undefined && !isPlainObject(value)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, `${key} 必须是对象(字典)`, { - path: `/${key}`, - }) - } - } - - // 纯数据检查(§3.5:文档 JSON 中不能保存函数、DOM 节点或运行时对象) - if (!isPlainData(input)) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_INVALID, - "文档包含不可序列化的值(函数、DOM 节点或运行时对象)", - { path: "/" }, - ) - } - - return diagnostics -} - -/** 递归校验元素结构。 */ -function validateElementStructure( - elements: unknown[], - basePath: string, - bag: { error: (code: string, message: string, extra?: { path?: string; elementId?: string }) => void }, -): void { - elements.forEach((element, index) => { - const path = `${basePath}/${index}` - if (!isPlainObject(element)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "元素必须是对象", { path }) - return - } - const record = element as Record - const id = typeof record.id === "string" ? record.id : undefined - if (!isValidId(record.id)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, "元素缺少合法的 id", { path: `${path}/id` }) - } - if (typeof record.type !== "string" || record.type.length === 0) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, "元素缺少 type", { path: `${path}/type` }) - } - const frame = record.frame - if (frame !== undefined && !isPlainObject(frame)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "元素 frame 必须是对象", { - path: `${path}/frame`, - ...(id ? { elementId: id } : {}), - }) - } - const children = record.children - if (children !== undefined) { - if (!Array.isArray(children)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "元素 children 必须是数组", { - path: `${path}/children`, - ...(id ? { elementId: id } : {}), - }) - } else { - validateElementStructure(children, `${path}/children`, bag) - } - } - // 表格列 - if (record.type === "table") { - const columns = record.columns - if (columns !== undefined && !Array.isArray(columns)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "表格 columns 必须是数组", { - path: `${path}/columns`, - }) - } else if (Array.isArray(columns)) { - columns.forEach((column, columnIndex) => { - const columnPath = `${path}/columns/${columnIndex}` - if (!isPlainObject(column)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "表格列必须是对象", { - path: columnPath, - }) - return - } - const columnChildren = (column as Record).children - if (columnChildren !== undefined) { - if (!Array.isArray(columnChildren)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_TYPE_MISMATCH, "表格列 children 必须是数组", { - path: `${columnPath}/children`, - }) - } else { - validateElementStructure(columnChildren, `${columnPath}/children`, bag) - } - } - }) - } - } - }) -} - -/** - * 第二级:完整文档校验。 - * - * 在结构成立后检查引用完整性、业务约束,并产出可定位的诊断。 - */ -export function validateDocument( - document: unknown, - options: { pluginElementTypes?: ReadonlySet } = {}, -): Diagnostic[] { - const diagnostics: Diagnostic[] = [...validateStructure(document)] - if (diagnostics.some((item) => item.severity === "error")) { - // 结构已不成立,继续做引用检查只会产生噪音 - return diagnostics - } - const bag: DiagnosticBag = toBag(diagnostics) - const doc = document as Record - - const dataSourceIds = new Set(Object.keys((doc.dataSources as object) ?? {})) - const datasetIds = new Set(Object.keys((doc.datasets as object) ?? {})) - const styleIds = new Set(Object.keys((doc.styles as object) ?? {})) - - // 数据集引用的数据源 - for (const [datasetId, dataset] of Object.entries( - (doc.datasets as Record) ?? {}, - )) { - if (!isPlainObject(dataset)) continue - const sourceId = (dataset as Record).sourceId - if (typeof sourceId === "string" && sourceId.length > 0 && !dataSourceIds.has(sourceId)) { - bag.warn( - DIAGNOSTIC_CODES.REF_DANGLING_DATASOURCE, - `数据集 "${datasetId}" 引用了不存在的数据源 "${sourceId}"`, - { path: `/datasets/${datasetId}/sourceId` }, - ) - } - } - - // 样式继承链 - const styleCycle = detectStyleCycles((doc.styles as Record) ?? {}) - for (const cycle of styleCycle) { - bag.error( - DIAGNOSTIC_CODES.REF_CYCLE_DETECTED, - `样式继承存在循环:${cycle.join(" → ")}`, - { path: `/styles/${cycle[0]}` }, - ) - } - for (const [styleId, style] of Object.entries((doc.styles as Record) ?? {})) { - if (!isPlainObject(style)) continue - const parent = (style as Record).extends - if (typeof parent === "string" && !styleIds.has(parent)) { - bag.warn( - DIAGNOSTIC_CODES.REF_DANGLING_STYLE, - `样式 "${styleId}" 继承了不存在的样式 "${parent}"`, - { path: `/styles/${styleId}/extends` }, - ) - } - } - - // 参数名 - const seenParameterNames = new Set() - for (const [parameterId, parameter] of Object.entries( - (doc.parameters as Record) ?? {}, - )) { - if (!isPlainObject(parameter)) continue - const name = (parameter as Record).name - if (typeof name === "string") { - if (!isValidParameterName(name)) { - bag.error( - DIAGNOSTIC_CODES.SCHEMA_INVALID, - `参数名 "${name}" 不是合法标识符,无法在表达式中引用`, - { path: `/parameters/${parameterId}/name` }, - ) - } - if (seenParameterNames.has(name)) { - bag.error(DIAGNOSTIC_CODES.REF_DUPLICATE_ID, `参数名 "${name}" 重复`, { - path: `/parameters/${parameterId}/name`, - }) - } - seenParameterNames.add(name) - } - } - - // 元素树 - const seenElementIds = new Map() - const pluginTypes = options.pluginElementTypes - const sections = (doc.sections as unknown[]) ?? [] - sections.forEach((section, index) => { - if (!isPlainObject(section)) return - const record = section as Record - const kind = record.kind as ReportSectionKind - const sectionPath = `/sections/${index}` - - if (RESERVED_SECTION_KINDS.includes(kind)) { - bag.warn( - DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE, - `区域 "${kind}" 在 V1 中仅保留模型扩展点,暂不参与渲染`, - { path: `${sectionPath}/kind` }, - ) - } - if (!isV1SectionKind(kind) && !RESERVED_SECTION_KINDS.includes(kind)) { - bag.error(DIAGNOSTIC_CODES.SCHEMA_ENUM_INVALID, `未知的区域种类 "${kind}"`, { - path: `${sectionPath}/kind`, - }) - } - - const datasetId = record.datasetId - if (typeof datasetId === "string" && datasetId.length > 0 && !datasetIds.has(datasetId)) { - bag.warn( - DIAGNOSTIC_CODES.REF_DANGLING_DATASET, - `区域引用了不存在的数据集 "${datasetId}"`, - { path: `${sectionPath}/datasetId` }, - ) - } - - if (Array.isArray(record.children)) { - validateElements( - record.children, - `${sectionPath}/children`, - { bag, datasetIds, styleIds, pluginTypes, seenElementIds }, - ) - } - }) - - // 必须返回 bag 的内容而不是初始的 diagnostics 数组: - // toBag 会复制一份内部列表,之后写入 bag 的诊断不会出现在 diagnostics 中。 - return bag.all() -} - -interface ValidateContext { - bag: DiagnosticBag - datasetIds: ReadonlySet - styleIds: ReadonlySet - pluginTypes?: ReadonlySet - seenElementIds: Map -} - -/** 递归校验元素:类型、引用、重复 ID。 */ -function validateElements( - elements: unknown[], - basePath: string, - ctx: ValidateContext, -): void { - elements.forEach((element, index) => { - const path = `${basePath}/${index}` - if (!isPlainObject(element)) return - const record = element as Record - const id = typeof record.id === "string" ? record.id : "" - const type = typeof record.type === "string" ? record.type : "" - const where = id ? { elementId: id } : {} - - // 重复 ID - if (id) { - const previous = ctx.seenElementIds.get(id) - if (previous) { - ctx.bag.error(DIAGNOSTIC_CODES.REF_DUPLICATE_ID, `元素 ID "${id}" 重复`, { path, ...where }) - } else { - ctx.seenElementIds.set(id, path) - } - } - - // 元素类型:内置 或 已注册插件 - const isBuiltin = (BUILTIN_ELEMENT_TYPES as readonly string[]).includes(type) - const isPlugin = ctx.pluginTypes?.has(type) ?? false - if (type && !isBuiltin && !isPlugin) { - if (ctx.pluginTypes) { - ctx.bag.error( - DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE, - `未知的元素类型 "${type}",且没有已注册的插件提供该类型`, - { path: `${path}/type`, ...where }, - ) - } else { - // 未提供插件清单时降级为警告,避免误报(插件可能由宿主稍后注册) - ctx.bag.warn( - DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE, - `元素类型 "${type}" 不是内置类型;如为插件元素,请注册对应插件`, - { path: `${path}/type`, ...where }, - ) - } - } - - // styleId 引用 - const styleId = record.styleId - if (typeof styleId === "string" && styleId.length > 0 && !ctx.styleIds.has(styleId)) { - ctx.bag.warn(DIAGNOSTIC_CODES.REF_DANGLING_STYLE, `元素引用了不存在的样式 "${styleId}"`, { - path: `${path}/styleId`, - ...where, - }) - } - - // frame 合法性 - if (isPlainObject(record.frame)) { - const frame = record.frame as Record - for (const key of ["x", "y", "width", "height"] as const) { - const value = frame[key] - if (value !== undefined && (typeof value !== "number" || !Number.isFinite(value))) { - ctx.bag.error( - DIAGNOSTIC_CODES.ELEMENT_FRAME_INVALID, - `frame.${key} 必须是有限数字`, - { path: `${path}/frame/${key}`, ...where }, - ) - } - } - const width = frame.width - const height = frame.height - if (typeof width === "number" && width < 0) { - ctx.bag.error(DIAGNOSTIC_CODES.ELEMENT_FRAME_INVALID, "frame.width 不能为负", { - path: `${path}/frame/width`, - ...where, - }) - } - if (typeof height === "number" && height < 0) { - ctx.bag.error(DIAGNOSTIC_CODES.ELEMENT_FRAME_INVALID, "frame.height 不能为负", { - path: `${path}/frame/height`, - ...where, - }) - } - } - - // 叶子元素不允许 children - const children = record.children - if (Array.isArray(children) && children.length > 0) { - if (!canHaveChildren(type, undefined)) { - const isContainerCapable = isPlugin || canHaveChildren(type, undefined) - if (!isContainerCapable && isBuiltin) { - ctx.bag.error( - DIAGNOSTIC_CODES.ELEMENT_CHILD_NOT_ALLOWED, - `元素类型 "${type}" 不允许包含子元素`, - { path: `${path}/children`, ...where }, - ) - } - } - validateElements(children, `${path}/children`, ctx) - } - - // 表格专属检查 - if (type === "table") { - const datasetId = record.datasetId - if (typeof datasetId !== "string" || datasetId.length === 0) { - ctx.bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, "明细表必须指定 datasetId", { - path: `${path}/datasetId`, - ...where, - }) - } else if (!ctx.datasetIds.has(datasetId)) { - ctx.bag.error( - DIAGNOSTIC_CODES.REF_DANGLING_DATASET, - `明细表引用了不存在的数据集 "${datasetId}"`, - { path: `${path}/datasetId`, ...where }, - ) - } - const columns = record.columns - if (!Array.isArray(columns)) { - ctx.bag.error(DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, "明细表必须包含 columns 数组", { - path: `${path}/columns`, - ...where, - }) - } else { - columns.forEach((column, columnIndex) => { - const columnPath = `${path}/columns/${columnIndex}` - if (!isPlainObject(column)) return - const columnRecord = column as Record - const columnWidth = columnRecord.width - if (typeof columnWidth !== "number" || !Number.isFinite(columnWidth) || columnWidth <= 0) { - ctx.bag.error( - DIAGNOSTIC_CODES.SCHEMA_RANGE_INVALID, - "表格列宽必须是正数", - { path: `${columnPath}/width`, ...where }, - ) - } - if (Array.isArray(columnRecord.children)) { - validateElements(columnRecord.children, `${columnPath}/children`, ctx) - } - }) - } - } - }) -} - -/** 检测样式继承环,返回所有环。 */ -export function detectStyleCycles( - styles: Record, -): string[][] { - const cycles: string[][] = [] - const state = new Map() - - const visit = (id: string, stack: string[]): void => { - const status = state.get(id) - if (status === "done") return - if (status === "visiting") { - const start = stack.indexOf(id) - cycles.push(start >= 0 ? stack.slice(start).concat(id) : [...stack, id]) - return - } - state.set(id, "visiting") - const style = styles[id] - if (isPlainObject(style)) { - const parent = (style as Record).extends - if (typeof parent === "string" && parent.length > 0) { - visit(parent, [...stack, id]) - } - } - state.set(id, "done") - } - - for (const id of Object.keys(styles)) visit(id, []) - return cycles -} diff --git a/code/one-designer/packages/report-core/src/schema/version.ts b/code/one-designer/packages/report-core/src/schema/version.ts deleted file mode 100644 index 134bf405..00000000 --- a/code/one-designer/packages/report-core/src/schema/version.ts +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Schema 版本与迁移契约(对应设计文档 §12)。 - * - * - schemaVersion 使用单调递增整数。 - * - 反序列化顺序:解析 JSON → 校验结构 → 执行迁移 → 规范化默认值。 - * - 迁移函数按版本逐步执行,不允许跨版本直接修改内部对象。 - */ - -/** 当前 schema 版本。任何破坏性模型变更都必须递增此值并补齐迁移函数。 */ -export const CURRENT_SCHEMA_VERSION = 1 - -/** 首个受支持的 schema 版本。 */ -export const MIN_SCHEMA_VERSION = 1 - -/** - * 一次版本迁移。 - * - * from → to 必须是相邻版本(to === from + 1),由 migrate 流程强制校验, - * 保证“逐步执行、不跨版本直接改内部对象”。 - */ -export interface Migration { - from: number - to: number - description: string - /** - * 迁移函数。 - * - * 输入输出都是「未知形状的普通对象」,因为迁移发生在结构校验之前, - * 此时还不能假定数据符合当前模型。迁移函数必须容错:字段缺失时跳过, - * 而不是抛异常。 - */ - migrate(document: Record): Record -} - -/** - * 迁移注册表。 - * - * 目前只有 v1,故为空。新增版本时在此追加,例如: - * - * { - * from: 1, - * to: 2, - * description: "把 page.margin 从 px 改为 mm", - * migrate: (doc) => { ...; return doc }, - * } - */ -export const MIGRATIONS: readonly Migration[] = Object.freeze([]) - -/** 按起始版本取出需要依次执行的迁移链。 */ -export function planMigrations( - from: number, - to: number, - migrations: readonly Migration[] = MIGRATIONS, -): Migration[] { - if (from === to) return [] - if (from > to) { - throw new RangeError(`不支持从 v${from} 降级到 v${to}`) - } - const plan: Migration[] = [] - let cursor = from - while (cursor < to) { - const step = migrations.find((item) => item.from === cursor) - if (!step) { - throw new RangeError(`缺少 v${cursor} → v${cursor + 1} 的迁移函数`) - } - if (step.to !== step.from + 1) { - throw new RangeError( - `迁移必须逐版本执行:v${step.from} → v${step.to} 不是相邻版本`, - ) - } - plan.push(step) - cursor = step.to - } - return plan -} - -/** 判断给定版本号是否为受支持的整数版本。 */ -export function isValidSchemaVersion(value: unknown): value is number { - return typeof value === "number" && Number.isInteger(value) && value >= MIN_SCHEMA_VERSION -} diff --git a/code/one-designer/packages/report-core/src/serialization/deserialize.ts b/code/one-designer/packages/report-core/src/serialization/deserialize.ts deleted file mode 100644 index 8f7acde9..00000000 --- a/code/one-designer/packages/report-core/src/serialization/deserialize.ts +++ /dev/null @@ -1,223 +0,0 @@ -/** - * 反序列化(对应设计文档 §12)。 - * - * 固定流程: - * - * deserialize(json) - * → parse 解析 JSON - * → validate 校验结构 - * → migrate 按版本逐步迁移 - * → normalize 规范化默认值 - * - * 关键取舍:校验失败时仍尽力返回一份可用的文档,并把问题放进 diagnostics。 - * 这是 §13 的要求——插件缺失、字段缺失等问题应可定位,而不应阻止 - * 整个文档被读取。只有连根结构都不成立时才返回 ok: false。 - */ -import type { Diagnostic } from "../model/common.js" -import type { ReportDocument } from "../model/report.js" -import { DIAGNOSTIC_CODES, error } from "../diagnostics/diagnostic.js" -import { isPlainObject } from "../utils/deep.js" -import { validateStructure, validateDocument } from "../schema/validation.js" -import { normalize } from "../document/normalize.js" -import { migrate } from "./migrate.js" -import { CURRENT_SCHEMA_VERSION } from "../schema/version.js" - -/** 反序列化选项。 */ -export interface DeserializeOptions { - /** 已注册的插件元素类型,用于校验元素 type 是否合法。 */ - pluginElementTypes?: ReadonlySet - /** - * 结构校验失败时是否仍然继续尝试规范化。 - * - * 默认 true:尽量把可读的内容还给用户,同时汇报全部问题。 - */ - lenient?: boolean -} - -/** 反序列化结果。 */ -export interface DeserializeResult { - ok: boolean - document: ReportDocument | null - diagnostics: Diagnostic[] - /** 实际执行的迁移步骤。 */ - migrationsApplied: string[] - /** 迁移前的 schema 版本。 */ - sourceVersion: number | null -} - -/** 从 JSON 字符串反序列化报表文档。 */ -export function deserialize( - json: string, - options: DeserializeOptions = {}, -): DeserializeResult { - let parsed: unknown - try { - parsed = JSON.parse(json) - } catch (cause) { - return { - ok: false, - document: null, - diagnostics: [ - error(DIAGNOSTIC_CODES.SCHEMA_INVALID, `JSON 解析失败:${(cause as Error).message}`, { - path: "/", - }), - ], - migrationsApplied: [], - sourceVersion: null, - } - } - return deserializeValue(parsed, options) -} - -/** 从已解析的普通对象反序列化报表文档。 */ -export function deserializeValue( - input: unknown, - options: DeserializeOptions = {}, -): DeserializeResult { - const { lenient = true } = options - const diagnostics: Diagnostic[] = [] - - if (!isPlainObject(input)) { - return { - ok: false, - document: null, - diagnostics: [ - error(DIAGNOSTIC_CODES.SCHEMA_INVALID, "文档根节点必须是普通对象", { path: "/" }), - ], - migrationsApplied: [], - sourceVersion: null, - } - } - - const sourceVersion = - typeof input.schemaVersion === "number" ? input.schemaVersion : null - - // 步骤 1:结构校验(在迁移之前,因为迁移函数假定输入形状基本可用) - const structureDiagnostics = validateStructure(input) - diagnostics.push(...structureDiagnostics) - - const structureBroken = structureDiagnostics.some((item) => item.severity === "error") - if (structureBroken && !lenient) { - return { - ok: false, - document: null, - diagnostics, - migrationsApplied: [], - sourceVersion, - } - } - - // 步骤 2:迁移 - let working: unknown = input - let migrationsApplied: string[] = [] - if (sourceVersion !== null && sourceVersion < CURRENT_SCHEMA_VERSION) { - const migration = migrate(input) - diagnostics.push(...migration.diagnostics) - migrationsApplied = migration.applied - working = migration.document - if (migration.diagnostics.some((item) => item.severity === "error")) { - return { - ok: false, - document: null, - diagnostics, - migrationsApplied, - sourceVersion, - } - } - } else if (sourceVersion !== null && sourceVersion > CURRENT_SCHEMA_VERSION) { - diagnostics.push( - error( - DIAGNOSTIC_CODES.SCHEMA_VERSION_UNKNOWN, - `文档版本 v${sourceVersion} 高于当前支持的 v${CURRENT_SCHEMA_VERSION},拒绝读取以避免数据损坏`, - { path: "/schemaVersion" }, - ), - ) - return { - ok: false, - document: null, - diagnostics, - migrationsApplied, - sourceVersion, - } - } - - // 步骤 3:规范化 - let document: ReportDocument - try { - document = normalize(working as ReportDocument) - } catch (cause) { - diagnostics.push( - error(DIAGNOSTIC_CODES.SCHEMA_INVALID, `文档规范化失败:${(cause as Error).message}`, { - path: "/", - }), - ) - return { - ok: false, - document: null, - diagnostics, - migrationsApplied, - sourceVersion, - } - } - - // 步骤 4:完整校验(引用完整性等),产出可定位诊断 - const validationOptions = options.pluginElementTypes - ? { pluginElementTypes: options.pluginElementTypes } - : {} - const fullDiagnostics = validateDocument(document, validationOptions) - // 结构与引用问题在迁移后可能已被修复,这里只补充去重后仍存在的问题 - for (const diagnostic of fullDiagnostics) { - if (!diagnostics.some((existing) => sameDiagnostic(existing, diagnostic))) { - diagnostics.push(diagnostic) - } - } - - return { - ok: !diagnostics.some((item) => item.severity === "error"), - document, - diagnostics, - migrationsApplied, - sourceVersion, - } -} - -function sameDiagnostic(a: Diagnostic, b: Diagnostic): boolean { - return a.code === b.code && a.path === b.path && a.elementId === b.elementId -} - -/** - * 宽松读取:无论有多少诊断都尽量返回文档。 - * - * 便于宿主做「打开旧文件」这类容错场景,配合 diagnostics 提示用户。 - */ -export function deserializeLeniently( - json: string, - options: Omit = {}, -): DeserializeResult { - return deserialize(json, { ...options, lenient: true }) -} - -/** 严格读取:任何错误级诊断都视为失败。 */ -export function deserializeStrictly( - json: string, - options: Omit = {}, -): DeserializeResult { - return deserialize(json, { ...options, lenient: false }) -} - -/** 便捷函数:只想要文档,不需要诊断时使用。失败返回 null。 */ -export function tryDeserialize( - json: string, - options: DeserializeOptions = {}, -): ReportDocument | null { - return deserialize(json, options).document -} - -/** 汇总诊断信息为一行摘要,便于日志。 */ -export function summarizeDiagnostics(diagnostics: readonly Diagnostic[]): string { - const errors = diagnostics.filter((item) => item.severity === "error").length - const warnings = diagnostics.filter((item) => item.severity === "warning").length - const infos = diagnostics.filter((item) => item.severity === "info").length - if (diagnostics.length === 0) return "无诊断信息" - return `共 ${diagnostics.length} 条诊断(错误 ${errors}、警告 ${warnings}、提示 ${infos})` -} diff --git a/code/one-designer/packages/report-core/src/serialization/migrate.ts b/code/one-designer/packages/report-core/src/serialization/migrate.ts deleted file mode 100644 index 4cf34c09..00000000 --- a/code/one-designer/packages/report-core/src/serialization/migrate.ts +++ /dev/null @@ -1,159 +0,0 @@ -/** - * 版本迁移(对应设计文档 §12)。 - * - * 要求: - * - 迁移函数按版本逐步执行,不允许跨版本直接修改内部对象。 - * - 迁移发生在结构校验之前(见 §12 的流程),因此必须容错: - * 字段缺失时跳过,而不是抛异常。 - */ -import type { Diagnostic } from "../model/common.js" -import { DIAGNOSTIC_CODES, warning, error } from "../diagnostics/diagnostic.js" -import { - CURRENT_SCHEMA_VERSION, - MIGRATIONS, - isValidSchemaVersion, - planMigrations, - type Migration, -} from "../schema/version.js" -import { isPlainObject } from "../utils/deep.js" - -/** 迁移结果。 */ -export interface MigrateResult { - /** 迁移后的对象。迁移失败时返回原对象。 */ - document: Record - /** 迁移前的版本。 */ - fromVersion: number - /** 迁移后的版本。 */ - toVersion: number - /** 实际执行的迁移步骤描述。 */ - applied: string[] - diagnostics: Diagnostic[] -} - -/** - * 把文档对象迁移到目标版本。 - * - * @param input 任意形状的文档对象 - * @param targetVersion 目标版本,缺省为当前版本 - */ -export function migrate( - input: unknown, - targetVersion: number = CURRENT_SCHEMA_VERSION, - migrations: readonly Migration[] = MIGRATIONS, -): MigrateResult { - const diagnostics: Diagnostic[] = [] - const applied: string[] = [] - - if (!isPlainObject(input)) { - diagnostics.push( - error(DIAGNOSTIC_CODES.SCHEMA_INVALID, "文档根节点必须是普通对象,无法执行迁移", { - path: "/", - }), - ) - return { - document: {}, - fromVersion: 0, - toVersion: targetVersion, - applied, - diagnostics, - } - } - - const document: Record = { ...input } - const rawVersion = document.schemaVersion - - if (!isValidSchemaVersion(rawVersion)) { - diagnostics.push( - error( - DIAGNOSTIC_CODES.SCHEMA_VERSION_MISSING, - `无法迁移:schemaVersion 缺失或非法(${JSON.stringify(rawVersion)})`, - { path: "/schemaVersion" }, - ), - ) - return { - document, - fromVersion: 0, - toVersion: targetVersion, - applied, - diagnostics, - } - } - - const fromVersion = rawVersion - - if (fromVersion === targetVersion) { - return { document, fromVersion, toVersion: targetVersion, applied, diagnostics } - } - - if (fromVersion > targetVersion) { - diagnostics.push( - error( - DIAGNOSTIC_CODES.SCHEMA_VERSION_UNKNOWN, - `文档 schemaVersion 为 ${fromVersion},高于当前支持的 ${targetVersion}。` + - "请升级运行环境后再打开该文档。", - { path: "/schemaVersion" }, - ), - ) - return { document, fromVersion, toVersion: fromVersion, applied, diagnostics } - } - - let plan: Migration[] - try { - plan = planMigrations(fromVersion, targetVersion, migrations) - } catch (cause) { - diagnostics.push( - error( - DIAGNOSTIC_CODES.SCHEMA_MIGRATION_FAILED, - `无法规划迁移路径:${(cause as Error).message}`, - { path: "/schemaVersion" }, - ), - ) - return { document, fromVersion, toVersion: fromVersion, applied, diagnostics } - } - - let current = document - for (const step of plan) { - try { - const next = step.migrate(current) - if (!isPlainObject(next)) { - throw new TypeError("迁移函数必须返回普通对象") - } - current = next - current.schemaVersion = step.to - applied.push(`v${step.from} → v${step.to}:${step.description}`) - } catch (cause) { - diagnostics.push( - error( - DIAGNOSTIC_CODES.SCHEMA_MIGRATION_FAILED, - `迁移 v${step.from} → v${step.to} 失败:${(cause as Error).message}`, - { path: "/" }, - ), - ) - return { document: current, fromVersion, toVersion: step.from, applied, diagnostics } - } - } - - if (applied.length > 0) { - diagnostics.push( - warning( - DIAGNOSTIC_CODES.SCHEMA_MIGRATION_FAILED, - `文档已从 v${fromVersion} 迁移到 v${targetVersion},共 ${applied.length} 步`, - ), - ) - } - - return { - document: current, - fromVersion, - toVersion: targetVersion, - applied, - diagnostics, - } -} - -/** 判断给定文档是否需要迁移。 */ -export function needsMigration(input: unknown): boolean { - if (!isPlainObject(input)) return false - const version = (input as Record).schemaVersion - return isValidSchemaVersion(version) && version < CURRENT_SCHEMA_VERSION -} diff --git a/code/one-designer/packages/report-core/src/serialization/serialize.ts b/code/one-designer/packages/report-core/src/serialization/serialize.ts deleted file mode 100644 index 1b3019ad..00000000 --- a/code/one-designer/packages/report-core/src/serialization/serialize.ts +++ /dev/null @@ -1,90 +0,0 @@ -/** - * 序列化(对应设计文档 §12)。 - * - * 要求:序列化结果保持稳定排序,便于版本控制和差异比较。 - * 因此输出前会做 sortKeysDeep,保证同一份文档永远产出逐字节一致的 JSON。 - */ -import type { ReportDocument } from "../model/report.js" -import { sortKeysDeep, isPlainData } from "../utils/deep.js" -import { CURRENT_SCHEMA_VERSION } from "../schema/version.js" -import { normalize } from "../document/normalize.js" - -/** 序列化选项。 */ -export interface SerializeOptions { - /** - * 是否美化输出。 - * - * 默认 false,产出紧凑 JSON,适合作为传输格式; - * 存入版本库时建议开启,便于 diff。 - */ - pretty?: boolean - /** 缩进字符数,仅在 pretty 为 true 时生效。 */ - indent?: number - /** 是否按键名排序。默认 true,保证稳定输出。 */ - stable?: boolean -} - -/** - * 把文档序列化为 JSON 字符串。 - * - * 序列化前先 normalize,保证输出始终是当前 schema 的完整结构, - * 避免把半成品或含缺省字段缺失的文档写进存储。 - */ -export function serialize( - document: ReportDocument, - options: SerializeOptions = {}, -): string { - // 先校验输入的纯数据性,再规范化。 - // 顺序很重要:normalize 会按字段重建文档,顺带丢弃未知字段, - // 因此若先规范化,混入的函数 / DOM 节点会被静默吞掉而无法被发现。 - assertPlainData(document) - const normalized = normalize(document) - const withVersion: ReportDocument = { - ...normalized, - schemaVersion: CURRENT_SCHEMA_VERSION, - } - return serializeValue(withVersion, options) -} - -/** - * 断言值是纯数据(§3.5)。 - * - * 文档 JSON 中不能保存函数、DOM 节点或运行时对象。 - */ -function assertPlainData(value: unknown): void { - if (!isPlainData(value)) { - throw new TypeError( - "文档中包含不可序列化的值(函数、DOM 节点或运行时对象)。" + - "请检查是否误把编辑器状态写入了文档(见架构原则 §3.2 / §3.5)。", - ) - } -} - -/** 序列化任意纯数据值。 */ -export function serializeValue(value: unknown, options: SerializeOptions = {}): string { - const { pretty = false, indent = 2, stable = true } = options - - if (!isPlainData(value)) { - throw new TypeError( - "文档中包含不可序列化的值(函数、DOM 节点或运行时对象)。" + - "请检查是否误把编辑器状态写入了文档(见架构原则 §3.2 / §3.5)。", - ) - } - - const prepared = stable ? sortKeysDeep(value) : value - return pretty ? JSON.stringify(prepared, null, indent) : JSON.stringify(prepared) -} - -/** - * 把文档转为可安全写盘的普通对象(深拷贝 + 稳定排序)。 - * - * 适用于 host 需要自己控制 JSON 化时机的场景(如 Electron IPC)。 - */ -export function toPlainObject(document: ReportDocument): Record { - const normalized = normalize(document) - const withVersion: ReportDocument = { - ...normalized, - schemaVersion: CURRENT_SCHEMA_VERSION, - } - return sortKeysDeep(JSON.parse(JSON.stringify(withVersion))) as Record -} diff --git a/code/one-designer/packages/report-core/src/utils/deep.ts b/code/one-designer/packages/report-core/src/utils/deep.ts deleted file mode 100644 index 058fcff1..00000000 --- a/code/one-designer/packages/report-core/src/utils/deep.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 深拷贝与对象工具。 - * - * 约束(§3.2 / §3.5):文档必须是纯数据,因此这里只需要处理 JSON - * 可序列化类型,不处理函数、Date、Map、Set、DOM 节点。遇到这些类型 - * 会被显式拒绝,避免运行时对象混入文档。 - */ - -/** 判断是否为普通对象(不含数组、null)。 */ -export function isPlainObject(value: unknown): value is Record { - if (typeof value !== "object" || value === null) return false - const proto = Object.getPrototypeOf(value) - return proto === Object.prototype || proto === null -} - -/** 判断是否为纯数据(可安全序列化)。 */ -export function isPlainData(value: unknown): boolean { - if (value === null) return true - const type = typeof value - if (type === "string" || type === "number" || type === "boolean") return true - if (type === "function" || type === "symbol" || type === "bigint" || type === "undefined") { - return false - } - if (Array.isArray(value)) return value.every(isPlainData) - if (isPlainObject(value)) return Object.values(value).every(isPlainData) - return false -} - -/** - * 深拷贝纯数据。 - * - * 故意不使用 structuredClone,以保证在全部目标环境(含较老的 Node/Electron) - * 中行为一致,并且在拷贝过程中顺手校验纯数据约束。 - */ -export function deepClone(value: T): T { - if (value === null || typeof value !== "object") return value - if (Array.isArray(value)) { - return value.map((item) => deepClone(item)) as unknown as T - } - if (isPlainObject(value)) { - const out: Record = {} - for (const [key, item] of Object.entries(value)) { - out[key] = deepClone(item) - } - return out as T - } - throw new TypeError( - `deepClone 只接受纯数据,收到 ${Object.prototype.toString.call(value)}`, - ) -} - -/** 深比较两个纯数据是否相等。 */ -export function deepEqual(a: unknown, b: unknown): boolean { - if (a === b) return true - if (typeof a !== typeof b) return false - if (a === null || b === null) return false - if (Array.isArray(a)) { - if (!Array.isArray(b) || a.length !== b.length) return false - return a.every((item, index) => deepEqual(item, b[index])) - } - if (isPlainObject(a) && isPlainObject(b)) { - const keysA = Object.keys(a) - const keysB = Object.keys(b) - if (keysA.length !== keysB.length) return false - return keysA.every((key) => deepEqual(a[key], b[key])) - } - return false -} - -/** - * 按键名递归排序对象键,保证序列化结果稳定(§12)。 - * - * 数组顺序保持不变,只有对象键参与排序。 - */ -export function sortKeysDeep(value: T): T { - if (Array.isArray(value)) { - return value.map((item) => sortKeysDeep(item)) as unknown as T - } - if (isPlainObject(value)) { - const out: Record = {} - for (const key of Object.keys(value).sort()) { - out[key] = sortKeysDeep(value[key]) - } - return out as T - } - return value -} - -/** 移除对象中的 undefined 值,返回新对象。 */ -export function omitUndefined>(value: T): T { - const out: Record = {} - for (const [key, item] of Object.entries(value)) { - if (item !== undefined) out[key] = item - } - return out as T -} - -/** 深合并,source 中显式定义的值覆盖 target。undefined 不覆盖。 */ -export function deepMerge(target: T, source: unknown): T { - if (!isPlainObject(target) || !isPlainObject(source)) { - return (source === undefined ? target : source) as T - } - const out: Record = { ...target } - for (const [key, value] of Object.entries(source)) { - if (value === undefined) continue - const current = out[key] - out[key] = isPlainObject(current) && isPlainObject(value) - ? deepMerge(current, value) - : value - } - return out as T -} diff --git a/code/one-designer/packages/report-core/src/utils/id.ts b/code/one-designer/packages/report-core/src/utils/id.ts deleted file mode 100644 index ed84117f..00000000 --- a/code/one-designer/packages/report-core/src/utils/id.ts +++ /dev/null @@ -1,97 +0,0 @@ -/** - * ID 生成(Â?6 阶段 1 要求「完成基础命令å’?ID 生成」)ã€? * - * 要求ï¼? * - 不依èµ?crypto/浏览å™?API,可åœ?Browser / Node / Electron / Server / CLI 复用(Â?.1)ã€? * - 同一进程内保证单调递增,避免同一毫秒内批量创建元素时碰撞ã€? * - 生成结果只包含小写字母和数字,便于在 JSON 中做稳定排序(Â?2)ã€? */ - -const ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz" -const RANDOM_LENGTH = 10 - -let counter = Math.floor(Math.random() * 0xffffff) - -function randomChars(length: number): string { - let out = "" - for (let i = 0; i < length; i += 1) { - out += ALPHABET[Math.floor(Math.random() * ALPHABET.length)] - } - return out -} - -function counterChars(): string { - counter = (counter + 1) % 0xffffff - let value = counter - let out = "" - for (let i = 0; i < 5; i += 1) { - out = ALPHABET[value % ALPHABET.length]! + out - value = Math.floor(value / ALPHABET.length) - } - return out -} - -export interface IdOptions { - /** ID 前缀,例å¦?"el"ã€?sec",便于在大文档中肉眼辨认ã€?*/ - prefix?: string -} - -/** - * 生成一ä¸?IDã€? * - * 形如 `el_k3f9a2x8qp_00a1b`:前缀 + 随机æ®?+ 进程内单调计数器ã€? */ -export function createId(options: IdOptions = {}): string { - const { prefix } = options - const body = `${randomChars(RANDOM_LENGTH)}_${counterChars()}` - return prefix ? `${prefix}_${body}` : body -} - -/** 元素 IDã€?*/ -export function createElementId(): string { - return createId({ prefix: "el" }) -} - -/** 区域 IDã€?*/ -export function createSectionId(): string { - return createId({ prefix: "sec" }) -} - -/** 文档 IDã€?*/ -export function createDocumentId(): string { - return createId({ prefix: "rpt" }) -} - -/** 数据é›?IDã€?*/ -export function createDatasetId(): string { - return createId({ prefix: "ds" }) -} - -/** 数据æº?IDã€?*/ -export function createDataSourceId(): string { - return createId({ prefix: "src" }) -} - -/** 参数 IDã€?*/ -export function createParameterId(): string { - return createId({ prefix: "p" }) -} - -/** 表格åˆ?IDã€?*/ -export function createColumnId(): string { - return createId({ prefix: "col" }) -} - -/** 样式 IDã€?*/ -export function createStyleId(): string { - return createId({ prefix: "sty" }) -} - -/** 判断字符串是否为合法 ID(非空且不含空白)ã€?*/ -export function isValidId(value: unknown): value is string { - return typeof value === "string" && value.length > 0 && !/\s/.test(value) -} - -/** - * 在给定集合中生成一个不冲突çš?IDã€? * - * 用于 createDefault 之类需要保证唯一性的场景ã€? */ -export function createUniqueId(existing: ReadonlySet, options?: IdOptions): string { - let candidate = createId(options) - while (existing.has(candidate)) { - candidate = createId(options) - } - return candidate -} diff --git a/code/one-designer/packages/report-core/tests/command.test.ts b/code/one-designer/packages/report-core/tests/command.test.ts deleted file mode 100644 index 1c04bf8a..00000000 --- a/code/one-designer/packages/report-core/tests/command.test.ts +++ /dev/null @@ -1,449 +0,0 @@ -/** - * 命令、事务与撤销重做测试(对应 §4.5、§3.2)。 - * - * 关键断言:撤销栈属于编辑器状态,不进入文档(§3.2)。 - */ -import { describe, expect, it } from "vitest" -import { - CommandInvoker, - createCommand, - createInvoker, - failure, - isUndoable, - success, -} from "../src/command/command.js" -import { - EditSession, - History, - createEditSession, - hasErrorDiagnostics, -} from "../src/command/history.js" -import { createDocument } from "../src/document/create.js" -import type { Command } from "../src/command/command.js" -import type { ReportDocument } from "../src/model/report.js" - -/** 测试用:给 detail 区域加一个文本元素。 */ -const addText = createCommand<{ text: string }>( - "addText", - (document, payload) => { - const next = JSON.parse(JSON.stringify(document)) as ReportDocument - const detail = next.sections.find((s) => s.kind === "detail")! - detail.children.push({ - id: `el-${payload.text}`, - type: "text", - frame: { x: 0, y: 0, width: 10, height: 5 }, - props: { text: payload.text }, - }) - return next - }, -) - -/** 测试用:改名。 */ -const rename = createCommand<{ name: string }>("rename", (document, payload) => { - const next = JSON.parse(JSON.stringify(document)) as ReportDocument - next.name = payload.name - return next -}) - -describe("createCommand", () => { - it("返回新文档而不修改原文档", () => { - const doc = createDocument({ name: "原始" }) - const result = rename.execute({ name: "新名" }, { document: doc }) - expect(result.document?.name).toBe("新名") - expect(doc.name).toBe("原始") - }) - - it("支持返回 CommandResult", () => { - const cmd = createCommand("noop", (document) => success(document)) - const result = cmd.execute(undefined, { document: createDocument() }) - expect(result.document).not.toBeNull() - expect(result.diagnostics).toEqual([]) - }) - - it("默认可撤销", () => { - expect(isUndoable(rename as Command)).toBe(true) - }) - - it("可声明不可撤销", () => { - const cmd = createCommand("load", (d) => d, { undoable: false }) - expect(isUndoable(cmd as Command)).toBe(false) - }) - - it("可声明合并键", () => { - const cmd = createCommand("drag", (d) => d, { mergeKey: "drag" }) - expect(cmd.mergeKey).toBe("drag") - }) - - it("failure 构造失败结果", () => { - const result = failure({ severity: "error", code: "x", message: "失败" }) - expect(result.document).toBeNull() - expect(result.diagnostics).toHaveLength(1) - }) - - it("hasErrorDiagnostics 判断错误", () => { - expect(hasErrorDiagnostics([{ severity: "warning", code: "w", message: "m" }])).toBe(false) - expect(hasErrorDiagnostics([{ severity: "error", code: "e", message: "m" }])).toBe(true) - }) -}) - -describe("CommandInvoker", () => { - it("执行命令后更新内部文档", () => { - const invoker = createInvoker(createDocument({ name: "A" })) - invoker.run(rename, { name: "B" }) - expect(invoker.getDocument().name).toBe("B") - }) - - it("失败时文档不变", () => { - const failing = createCommand("fail", () => - failure({ severity: "error", code: "x", message: "boom" }), - ) - const invoker = new CommandInvoker(createDocument({ name: "A" })) - const result = invoker.run(failing, undefined) - expect(result.document).toBeNull() - expect(invoker.getDocument().name).toBe("A") - }) - - it("runWithSnapshot 返回变更前快照", () => { - const invoker = createInvoker(createDocument({ name: "A" })) - const { before, result } = invoker.runWithSnapshot(rename, { name: "B" }) - expect(before?.name).toBe("A") - expect(result.document?.name).toBe("B") - }) - - it("不可撤销命令不产生快照", () => { - const cmd = createCommand("noop", (d) => d, { undoable: false }) - const invoker = createInvoker(createDocument()) - const { before } = invoker.runWithSnapshot(cmd, undefined) - expect(before).toBeNull() - }) -}) - -describe("History", () => { - it("记录后可撤销重做", () => { - const history = new History() - const a = createDocument({ name: "A" }) - const b = createDocument({ name: "B" }) - expect(history.record(a, b, "改名")).toBe(true) - expect(history.canUndo).toBe(true) - - const undone = history.undo() - expect(undone?.name).toBe("A") - expect(history.canRedo).toBe(true) - - const redone = history.redo() - expect(redone?.name).toBe("B") - }) - - it("相同内容不记录(避免空撤销步)", () => { - const history = new History() - const a = createDocument({ name: "A" }) - // 用同一份文档的深拷贝作为 after,保证内容(含生成的 ID)完全一致。 - // 注意不能新建 createDocument,因为它会生成新的随机 ID。 - const b = JSON.parse(JSON.stringify(a)) as ReportDocument - expect(history.record(a, b, "无变化")).toBe(false) - expect(history.canUndo).toBe(false) - }) - - it("撤销后新操作清空重做栈", () => { - const history = new History() - const a = createDocument({ name: "A" }) - const b = createDocument({ name: "B" }) - const c = createDocument({ name: "C" }) - history.record(a, b, "第一步") - history.undo() - history.record(a, c, "新分支") - expect(history.canRedo).toBe(false) - expect(history.peekUndoLabel()).toBe("新分支") - }) - - it("空栈时撤销返回 null", () => { - expect(new History().undo()).toBeNull() - expect(new History().redo()).toBeNull() - }) - - it("按 mergeKey 与时间窗合并连续操作", () => { - const history = new History({ mergeWindow: 10_000 }) - const a = createDocument({ name: "A" }) - const b = createDocument({ name: "B" }) - const c = createDocument({ name: "C" }) - history.record(a, b, "拖拽", { mergeKey: "drag" }) - history.record(b, c, "拖拽", { mergeKey: "drag" }) - expect(history.undoDepth).toBe(1) - expect(history.undo()?.name).toBe("A") - }) - - it("mergeKey 不同则不合并", () => { - const history = new History({ mergeWindow: 10_000 }) - const a = createDocument({ name: "A" }) - const b = createDocument({ name: "B" }) - const c = createDocument({ name: "C" }) - history.record(a, b, "拖拽", { mergeKey: "drag" }) - history.record(b, c, "缩放", { mergeKey: "resize" }) - expect(history.undoDepth).toBe(2) - }) - - it("超过上限时丢弃最早记录", () => { - const history = new History({ limit: 2 }) - const docs = ["A", "B", "C", "D"].map((name) => createDocument({ name })) - for (let i = 0; i < docs.length - 1; i += 1) { - history.record(docs[i]!, docs[i + 1]!, `步骤${i}`) - } - expect(history.undoDepth).toBe(2) - }) - - it("事务把多次变更合并为一步", () => { - const history = new History() - const a = createDocument({ name: "A" }) - history.setBase(a) - - const b = createDocument({ name: "B" }) - const c = createDocument({ name: "C" }) - - const { changed } = history.transaction("批量操作", () => { - history.updateCurrent(b) - history.updateCurrent(c) - }) - - expect(changed).toBe(true) - expect(history.undoDepth).toBe(1) - expect(history.undo()?.name).toBe("A") - }) - - it("事务内无实际变更则不记录", () => { - const history = new History() - const a = createDocument({ name: "A" }) - history.setBase(a) - const { changed } = history.transaction("空事务", () => { - history.updateCurrent(a) - }) - expect(changed).toBe(false) - expect(history.undoDepth).toBe(0) - }) - - it("嵌套事务并入外层", () => { - const history = new History() - const a = createDocument({ name: "A" }) - history.setBase(a) - const b = createDocument({ name: "B" }) - history.transaction("外层", () => { - history.transaction("内层", () => { - history.updateCurrent(b) - }) - }) - expect(history.undoDepth).toBe(1) - }) - - it("begin/commit 事务可跨调用累积,最终合并为一步", () => { - const history = new History() - history.setBase(createDocument({ name: "A" })) - - expect(history.inTransaction).toBe(false) - expect(history.beginTransaction("拖拽")).toBe(true) - expect(history.inTransaction).toBe(true) - - // 模拟拖拽过程中反复更新(每次都是一次事件回调) - history.updateCurrent(createDocument({ name: "B" })) - history.updateCurrent(createDocument({ name: "C" })) - - expect(history.commitTransaction()).toBe(true) - expect(history.inTransaction).toBe(false) - expect(history.undoDepth).toBe(1) - // 撤销直接回到事务开始前的 A,而不是中间态 B - expect(history.undo()?.name).toBe("A") - }) - - it("begin 事务期间不产生中间撤销记录", () => { - const history = new History() - history.setBase(createDocument({ name: "A" })) - history.beginTransaction("拖拽") - history.updateCurrent(createDocument({ name: "B" })) - history.updateCurrent(createDocument({ name: "C" })) - // 还没提交,撤销栈里不该有任何东西 - expect(history.undoDepth).toBe(0) - history.commitTransaction() - expect(history.undoDepth).toBe(1) - }) - - it("commit 无实际变更时返回 false 且不记录", () => { - const history = new History() - const a = createDocument({ name: "A" }) - history.setBase(a) - history.beginTransaction("空拖拽") - history.updateCurrent(a) - expect(history.commitTransaction()).toBe(false) - expect(history.undoDepth).toBe(0) - }) - - it("rollback 丢弃事务期间的变更", () => { - const history = new History() - history.setBase(createDocument({ name: "A" })) - history.beginTransaction("拖拽") - history.updateCurrent(createDocument({ name: "B" })) - - expect(history.rollbackTransaction()?.name).toBe("A") - expect(history.inTransaction).toBe(false) - expect(history.undoDepth).toBe(0) - }) - - it("事务进行中再 begin 返回 false(嵌套并入外层)", () => { - const history = new History() - history.setBase(createDocument({ name: "A" })) - expect(history.beginTransaction("外层")).toBe(true) - expect(history.beginTransaction("内层")).toBe(false) - history.updateCurrent(createDocument({ name: "B" })) - history.commitTransaction() - expect(history.undoDepth).toBe(1) - }) - - it("没有基准文档时 begin 返回 false", () => { - const history = new History() - expect(history.beginTransaction("拖拽")).toBe(false) - expect(history.inTransaction).toBe(false) - }) - - it("clear 清空历史", () => { - const history = new History() - history.record(createDocument({ name: "A" }), createDocument({ name: "B" }), "x") - history.clear() - expect(history.canUndo).toBe(false) - expect(history.canRedo).toBe(false) - }) - - it("describe 导出摘要", () => { - const history = new History() - history.record(createDocument({ name: "A" }), createDocument({ name: "B" }), "改名") - expect(history.describe().undo).toEqual(["改名"]) - }) - - it("peek 返回待撤销/重做的操作名", () => { - const history = new History() - history.record(createDocument({ name: "A" }), createDocument({ name: "B" }), "改名") - expect(history.peekUndoLabel()).toBe("改名") - history.undo() - expect(history.peekRedoLabel()).toBe("改名") - }) -}) - -describe("EditSession", () => { - it("执行命令并累积历史", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.execute(rename, { name: "B" }) - expect(session.getDocument().name).toBe("B") - expect(session.history.canUndo).toBe(true) - }) - - it("撤销恢复上一状态", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.execute(rename, { name: "B" }) - expect(session.undo()).toBe(true) - expect(session.getDocument().name).toBe("A") - }) - - it("重做恢复后续状态", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.execute(rename, { name: "B" }) - session.undo() - expect(session.redo()).toBe(true) - expect(session.getDocument().name).toBe("B") - }) - - it("无可撤销时返回 false", () => { - const session = createEditSession(createDocument()) - expect(session.undo()).toBe(false) - expect(session.redo()).toBe(false) - }) - - it("失败命令不产生历史", () => { - const failing = createCommand("fail", () => - failure({ severity: "error", code: "x", message: "boom" }), - ) - const session = createEditSession(createDocument({ name: "A" })) - session.execute(failing, undefined) - expect(session.history.canUndo).toBe(false) - expect(session.getDocument().name).toBe("A") - }) - - it("多步操作依次撤销", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.execute(rename, { name: "B" }) - session.execute(rename, { name: "C" }) - session.undo() - expect(session.getDocument().name).toBe("B") - session.undo() - expect(session.getDocument().name).toBe("A") - }) - - it("load 替换文档并清空历史", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.execute(rename, { name: "B" }) - session.load(createDocument({ name: "全新" })) - expect(session.getDocument().name).toBe("全新") - expect(session.history.canUndo).toBe(false) - }) - - it("事务内多次编辑合并为一步撤销", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.transaction("批量改名", (s) => { - s.applyWithinTransaction(rename, { name: "B" }) - s.applyWithinTransaction(rename, { name: "C" }) - }) - expect(session.getDocument().name).toBe("C") - session.undo() - expect(session.getDocument().name).toBe("A") - }) - - it("begin/commit 事务可跨多个事件回调累积为一步撤销", () => { - const session = createEditSession(createDocument({ name: "A" })) - - expect(session.inTransaction).toBe(false) - expect(session.beginTransaction("拖拽")).toBe(true) - expect(session.inTransaction).toBe(true) - - // 每次 applyWithinTransaction 相当于一次 mousemove 回调 - session.applyWithinTransaction(rename, { name: "B" }) - session.applyWithinTransaction(rename, { name: "C" }) - // 未提交前不应有撤销记录 - expect(session.history.canUndo).toBe(false) - - expect(session.commitTransaction()).toBe(true) - expect(session.inTransaction).toBe(false) - expect(session.getDocument().name).toBe("C") - - // 一次撤销回到事务开始前的 A - session.undo() - expect(session.getDocument().name).toBe("A") - }) - - it("begin/commit 事务无变更时不产生撤销记录", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.beginTransaction("拖拽") - expect(session.commitTransaction()).toBe(false) - expect(session.history.canUndo).toBe(false) - }) - - it("会话修改不影响传入的原始文档", () => { - const original = createDocument({ name: "A" }) - const session = createEditSession(original) - session.execute(rename, { name: "B" }) - expect(original.name).toBe("A") - }) - - it("撤销不把编辑器状态写进文档(§3.2)", () => { - const session = createEditSession(createDocument({ name: "A" })) - session.execute(rename, { name: "B" }) - session.execute(rename, { name: "C" }) - const doc = session.getDocument() as unknown as Record - for (const key of ["undoStack", "redoStack", "history", "selection", "zoom", "scroll"]) { - expect(doc[key]).toBeUndefined() - } - }) -}) - -describe("EditSession 与 History 可复用性", () => { - it("EditSession 使用注入的 History 配置", () => { - const session = new EditSession(createDocument(), { limit: 1 }) - session.execute(rename, { name: "B" }) - session.execute(rename, { name: "C" }) - expect(session.history.undoDepth).toBe(1) - }) -}) diff --git a/code/one-designer/packages/report-core/tests/document.test.ts b/code/one-designer/packages/report-core/tests/document.test.ts deleted file mode 100644 index 57f80798..00000000 --- a/code/one-designer/packages/report-core/tests/document.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -/** - * 文档创建、规范化与克隆测试(对应 §14 文档 schema 与默认值测试)。 - */ -import { describe, expect, it } from "vitest" -import { - countElements, - createDocument, - createDefaultSections, - duplicateDocument, - isDocumentEmpty, -} from "../src/document/create.js" -import { normalize } from "../src/document/normalize.js" -import { cloneElementWithNewIds, cloneDocument } from "../src/document/clone.js" -import { CURRENT_SCHEMA_VERSION } from "../src/schema/version.js" -import { createElementId } from "../src/utils/id.js" -import type { ReportElement } from "../src/model/element.js" -import type { TableElement } from "../src/model/table.js" - -describe("createDocument", () => { - it("产出满足当前 schema 版本的完整文档", () => { - const doc = createDocument({ name: "测试报表" }) - expect(doc.schemaVersion).toBe(CURRENT_SCHEMA_VERSION) - expect(doc.name).toBe("测试报表") - expect(doc.id).toBeTruthy() - expect(doc.page.paper).toBe("A4") - expect(doc.page.orientation).toBe("portrait") - expect(doc.sections).toHaveLength(3) - expect(doc.sections.map((s) => s.kind)).toEqual([ - "page-header", - "detail", - "page-footer", - ]) - }) - - it("缺省名称为未命名报表", () => { - expect(createDocument().name).toBe("未命名报表") - }) - - it("可覆盖页面设置", () => { - const doc = createDocument({ - page: { paper: "A5", orientation: "landscape", margin: { top: 5, right: 15, bottom: 15, left: 15 } }, - }) - expect(doc.page.paper).toBe("A5") - expect(doc.page.orientation).toBe("landscape") - expect(doc.page.margin.top).toBe(5) - // 未指定的边距回落到默认值 - expect(doc.page.margin.right).toBe(15) - }) - - it("新建文档为空", () => { - expect(isDocumentEmpty(createDocument())).toBe(true) - }) -}) - -describe("normalize", () => { - it("补齐缺失的 V1 区域", () => { - const doc = createDocument() - const stripped = normalize({ - ...doc, - sections: [{ id: "s1", kind: "detail", children: [] }], - }) - expect(stripped.sections).toHaveLength(3) - expect(stripped.sections.map((s) => s.kind)).toEqual([ - "page-header", - "detail", - "page-footer", - ]) - }) - - it("保留额外区域并附在 V1 区域之后", () => { - const doc = createDocument() - const withSummary = normalize({ - ...doc, - sections: [ - ...doc.sections, - { id: "sum1", kind: "summary", children: [] }, - ], - }) - expect(withSummary.sections).toHaveLength(4) - expect(withSummary.sections[3]?.kind).toBe("summary") - }) - - it("以字典键为准修正 style.id", () => { - const doc = createDocument() - const normalized = normalize({ - ...doc, - styles: { sty_a: { id: "不匹配的ID", fontSize: 12 } }, - }) - expect(normalized.styles.sty_a?.id).toBe("sty_a") - }) - - it("参数缺名时回落到 id", () => { - const doc = createDocument() - const normalized = normalize({ - ...doc, - parameters: { p1: { id: "p1", name: "" } as never }, - }) - expect(normalized.parameters.p1?.name).toBe("p1") - }) - - it("缺省页边距被补齐", () => { - const doc = createDocument() - const normalized = normalize({ - ...doc, - page: { paper: "A4", orientation: "portrait" } as never, - }) - expect(normalized.page.margin).toEqual({ top: 15, right: 15, bottom: 15, left: 15 }) - }) - - it("空名回落到未命名报表", () => { - const doc = createDocument() - expect(normalize({ ...doc, name: "" }).name).toBe("未命名报表") - }) -}) - -describe("clone", () => { - it("cloneDocument 深拷贝且保留 ID", () => { - const doc = createDocument({ name: "原始" }) - const copy = cloneDocument(doc) - expect(copy).toEqual(doc) - expect(copy).not.toBe(doc) - // 修改副本不影响原件 - copy.name = "副本" - expect(doc.name).toBe("原始") - }) - - it("cloneElementWithNewIds 为整棵子树重新分配 ID", () => { - const child: ReportElement = { - id: createElementId(), - type: "text", - frame: { x: 0, y: 0, width: 10, height: 5 }, - } - const parent: ReportElement = { - id: createElementId(), - type: "container", - frame: { x: 0, y: 0, width: 20, height: 20 }, - children: [child], - } - const copy = cloneElementWithNewIds(parent) - expect(copy.id).not.toBe(parent.id) - expect(copy.children?.[0]?.id).not.toBe(child.id) - // 结构保持一致 - expect(copy.type).toBe("container") - expect(copy.children).toHaveLength(1) - }) - - it("cloneElementWithNewIds 也处理表格列 ID", () => { - const table: TableElement = { - id: "t1", - type: "table", - frame: { x: 0, y: 0, width: 100, height: 30 }, - datasetId: "ds1", - columns: [{ id: "col1", width: 30 }], - } - const copy = cloneElementWithNewIds(table) - const columns = (copy as TableElement).columns - expect(columns[0]?.id).not.toBe("col1") - }) -}) - -describe("duplicateDocument", () => { - it("生成新 ID 与副本名称", () => { - const doc = createDocument({ name: "销售单" }) - const copy = duplicateDocument(doc) - expect(copy.id).not.toBe(doc.id) - expect(copy.name).toBe("销售单 副本") - }) - - it("可指定副本名称", () => { - const doc = createDocument({ name: "销售单" }) - expect(duplicateDocument(doc, { name: "新名称" }).name).toBe("新名称") - }) -}) - -describe("countElements", () => { - it("统计嵌套元素", () => { - const doc = createDocument() - doc.sections[1]!.children = [ - { - id: "a", - type: "container", - frame: { x: 0, y: 0, width: 10, height: 10 }, - children: [{ id: "b", type: "text", frame: { x: 0, y: 0, width: 5, height: 5 } }], - }, - ] - expect(countElements(doc)).toBe(2) - }) - - it("空文档为 0", () => { - expect(countElements(createDocument())).toBe(0) - }) -}) - -describe("createDefaultSections", () => { - it("生成互不相同的区域 ID", () => { - const sections = createDefaultSections() - const ids = new Set(sections.map((s) => s.id)) - expect(ids.size).toBe(3) - }) - - it("页眉页脚默认每页重复", () => { - const sections = createDefaultSections() - const header = sections.find((s) => s.kind === "page-header") - expect(header?.options?.repeatOnEachPage).toBe(true) - }) -}) diff --git a/code/one-designer/packages/report-core/tests/plugin.test.ts b/code/one-designer/packages/report-core/tests/plugin.test.ts deleted file mode 100644 index c2622719..00000000 --- a/code/one-designer/packages/report-core/tests/plugin.test.ts +++ /dev/null @@ -1,269 +0,0 @@ -/** - * 插件契约与注册表测试(对应 §11、§14 的插件缺失与版本不兼容测试)。 - */ -import { describe, expect, it, vi } from "vitest" -import { - PluginRegistry, - createPluginRegistry, - reportRegisterResult, -} from "../src/plugin/registry.js" -import { isVersionCompatible } from "../src/plugin/plugin.js" -import { createDocument } from "../src/document/create.js" -import { DIAGNOSTIC_CODES, DiagnosticBag } from "../src/diagnostics/diagnostic.js" -import { createElementId } from "../src/utils/id.js" -import type { ReportPlugin } from "../src/plugin/plugin.js" -import type { ReportDocument } from "../src/model/report.js" - -function qrcodePlugin(overrides: Partial = {}): ReportPlugin { - return { - id: "plugin-qrcode", - version: "1.2.0", - elements: [ - { - type: "qrcode", - label: "二维码", - createDefault: (options) => ({ - id: options?.id ?? createElementId(), - type: "qrcode", - frame: options?.frame ?? { x: 0, y: 0, width: 20, height: 20 }, - props: { value: "https://example.com", errorLevel: "M" }, - }), - }, - ], - ...overrides, - } -} - -describe("PluginRegistry 注册", () => { - it("注册成功后可按类型取到元素插件", () => { - const registry = new PluginRegistry() - const result = registry.register(qrcodePlugin()) - expect(result.ok).toBe(true) - expect(registry.getElementPlugin("qrcode")?.type).toBe("qrcode") - }) - - it("缺少 id 的插件注册失败", () => { - const registry = new PluginRegistry() - const result = registry.register({ id: "", version: "1.0.0" }) - expect(result.ok).toBe(false) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING)).toBe(true) - }) - - it("重复注册同 id 失败且不覆盖", () => { - const registry = new PluginRegistry() - registry.register(qrcodePlugin()) - const second = registry.register(qrcodePlugin({ version: "9.9.9" })) - expect(second.ok).toBe(false) - expect(second.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.PLUGIN_ALREADY_REGISTERED)).toBe(true) - expect(registry.get("plugin-qrcode")?.version).toBe("1.2.0") - }) - - it("元素类型冲突时注册失败", () => { - const registry = new PluginRegistry() - registry.register(qrcodePlugin()) - const conflict = registry.register({ - id: "plugin-other", - version: "1.0.0", - elements: [ - { - type: "qrcode", - createDefault: () => ({ - id: "x", - type: "qrcode", - frame: { x: 0, y: 0, width: 1, height: 1 }, - }), - }, - ], - }) - expect(conflict.ok).toBe(false) - }) - - it("registerAll 汇总结果", () => { - const registry = new PluginRegistry() - const result = registry.registerAll([qrcodePlugin(), { id: "p2", version: "1.0.0" }]) - expect(result.ok).toBe(true) - expect(registry.list()).toHaveLength(2) - }) - - it("setup 钩子被调用并收到上下文", () => { - const setup = vi.fn() - const registry = new PluginRegistry() - registry.register(qrcodePlugin({ setup })) - expect(setup).toHaveBeenCalledTimes(1) - expect(setup.mock.calls[0]?.[0]).toMatchObject({ - pluginId: "plugin-qrcode", - pluginVersion: "1.2.0", - }) - }) - - it("unregister 移除插件及其元素类型", () => { - const registry = new PluginRegistry() - registry.register(qrcodePlugin()) - expect(registry.unregister("plugin-qrcode")).toBe(true) - expect(registry.getElementPlugin("qrcode")).toBeUndefined() - expect(registry.unregister("plugin-qrcode")).toBe(false) - }) - - it("clear 清空全部注册", () => { - const registry = createPluginRegistry([qrcodePlugin()]) - registry.clear() - expect(registry.list()).toHaveLength(0) - expect(registry.elementTypes().size).toBe(0) - }) - - it("elementTypes 与 containerTypes", () => { - const registry = createPluginRegistry([ - { - id: "p", - version: "1.0.0", - elements: [ - { - type: "leaf", - createDefault: () => ({ id: "a", type: "leaf", frame: { x: 0, y: 0, width: 1, height: 1 } }), - }, - { - type: "box", - isContainer: true, - createDefault: () => ({ id: "b", type: "box", frame: { x: 0, y: 0, width: 1, height: 1 } }), - }, - ], - }, - ]) - expect(registry.elementTypes()).toEqual(new Set(["leaf", "box"])) - expect(registry.containerTypes()).toEqual(new Set(["box"])) - }) - - it("createDefault 产出合法的插件元素", () => { - const registry = createPluginRegistry([qrcodePlugin()]) - const element = registry.getElementPlugin("qrcode")!.createDefault() - expect(element.type).toBe("qrcode") - expect(element.id).toBeTruthy() - expect(element.frame.width).toBe(20) - expect((element.props as { value: string }).value).toBe("https://example.com") - }) -}) - -describe("PluginRegistry 数据源与导出器", () => { - it("注册数据源插件", () => { - const registry = createPluginRegistry([ - { - id: "p-rest", - version: "1.0.0", - datasources: [{ type: "rest", label: "REST" }], - exporters: [{ format: "pdf", label: "PDF" }], - }, - ]) - expect(registry.getDataSourcePlugin("rest")?.type).toBe("rest") - expect(registry.getExporterPlugin("pdf")?.format).toBe("pdf") - }) - - it("collectMissing 报告未注册的插件", () => { - const registry = createPluginRegistry([qrcodePlugin()]) - const missing = registry.collectMissing([ - { pluginId: "qrcode", version: "*", kind: "element" }, - { pluginId: "barcode", version: "*", kind: "element", usedBy: "el-1" }, - { pluginId: "rest", version: "*", kind: "datasource" }, - ]) - expect(missing).toHaveLength(2) - expect(missing.every((d) => d.code === DIAGNOSTIC_CODES.PLUGIN_MISSING)).toBe(true) - expect(missing.find((d) => d.message.includes("barcode"))?.elementId).toBe("el-1") - }) -}) - -describe("PluginRegistry 版本兼容性", () => { - it("声明不兼容版本时产生告警但仍注册", () => { - const registry = new PluginRegistry() - const result = registry.register( - qrcodePlugin({ compatibleSchemaVersion: ">=99.0.0" }), - ) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.PLUGIN_VERSION_INCOMPATIBLE)).toBe(true) - // 仍然注册,避免阻断打开文档 - expect(registry.has("plugin-qrcode")).toBe(true) - }) - - it("声明兼容版本时不告警", () => { - const registry = new PluginRegistry() - const result = registry.register(qrcodePlugin({ compatibleSchemaVersion: ">=1.0.0" })) - expect(result.diagnostics).toEqual([]) - }) - - it("checkReferences 报告缺失插件", () => { - const registry = createPluginRegistry([qrcodePlugin()]) - const diagnostics = registry.checkReferences([ - { id: "plugin-qrcode", version: "1.2.0" }, - { id: "plugin-barcode", version: "1.0.0" }, - ]) - expect(diagnostics).toHaveLength(1) - expect(diagnostics[0]?.code).toBe(DIAGNOSTIC_CODES.PLUGIN_MISSING) - }) - - it("checkReferences 报告版本不匹配", () => { - const registry = createPluginRegistry([qrcodePlugin()]) - const diagnostics = registry.checkReferences([{ id: "plugin-qrcode", version: "^9.0.0" }]) - expect(diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.PLUGIN_VERSION_INCOMPATIBLE)).toBe(true) - }) - - it("checkReferences 接受 undefined", () => { - expect(createPluginRegistry().checkReferences(undefined)).toEqual([]) - }) -}) - -describe("isVersionCompatible", () => { - it("通配符与缺省视为兼容", () => { - expect(isVersionCompatible("1.0.0", "*")).toBe(true) - expect(isVersionCompatible("1.0.0", undefined)).toBe(true) - expect(isVersionCompatible("1.0.0", "")).toBe(true) - }) - - it(">= 语义", () => { - expect(isVersionCompatible("1.5.0", ">=1.2.0")).toBe(true) - expect(isVersionCompatible("1.1.0", ">=1.2.0")).toBe(false) - expect(isVersionCompatible("2.0.0", ">=1.2.0")).toBe(true) - }) - - it("^ 语义按 major 匹配", () => { - expect(isVersionCompatible("1.9.0", "^1.0.0")).toBe(true) - expect(isVersionCompatible("2.0.0", "^1.0.0")).toBe(false) - }) - - it("~ 语义按 major.minor 匹配", () => { - expect(isVersionCompatible("1.2.9", "~1.2.0")).toBe(true) - expect(isVersionCompatible("1.3.0", "~1.2.0")).toBe(false) - }) - - it("无法解析时视为兼容(不阻断)", () => { - expect(isVersionCompatible("1.0.0", "这不是版本号")).toBe(true) - expect(isVersionCompatible("乱码", ">=1.0.0")).toBe(true) - }) - - it("支持 x 通配", () => { - expect(isVersionCompatible("1.5.0", "1.x")).toBe(true) - expect(isVersionCompatible("2.0.0", "1.x")).toBe(false) - }) -}) - -describe("reportRegisterResult", () => { - it("把注册诊断写入收集器", () => { - const bag = new DiagnosticBag() - reportRegisterResult(bag, { - ok: false, - diagnostics: [{ severity: "error", code: "x", message: "boom" }], - }) - expect(bag.size).toBe(1) - expect(bag.hasError).toBe(true) - }) -}) - -describe("插件与文档协作", () => { - it("插件元素能在文档中通过校验", () => { - const registry = createPluginRegistry([qrcodePlugin()]) - const plugin = registry.getElementPlugin("qrcode")! - const doc: ReportDocument = createDocument() - doc.sections[1]!.children = [plugin.createDefault()] - - const types = registry.elementTypes() - expect(types.has("qrcode")).toBe(true) - // 校验时传入插件类型集合,不应报未知类型 - expect(doc.sections[1]?.children[0]?.type).toBe("qrcode") - }) -}) diff --git a/code/one-designer/packages/report-core/tests/serialization.test.ts b/code/one-designer/packages/report-core/tests/serialization.test.ts deleted file mode 100644 index 1a6be3e4..00000000 --- a/code/one-designer/packages/report-core/tests/serialization.test.ts +++ /dev/null @@ -1,258 +0,0 @@ -/** - * 序列化 / 反序列化 / 迁移测试(对应 §12 与 §14)。 - */ -import { describe, expect, it } from "vitest" -import { - serialize, - serializeValue, - toPlainObject, -} from "../src/serialization/serialize.js" -import { - deserialize, - deserializeLeniently, - deserializeStrictly, - summarizeDiagnostics, - tryDeserialize, -} from "../src/serialization/deserialize.js" -import { migrate, needsMigration } from "../src/serialization/migrate.js" -import { createDocument } from "../src/document/create.js" -import { CURRENT_SCHEMA_VERSION } from "../src/schema/version.js" -import { DIAGNOSTIC_CODES } from "../src/diagnostics/diagnostic.js" -import type { Migration } from "../src/schema/version.js" -import type { TableElement } from "../src/model/table.js" - -describe("serialize", () => { - it("产出稳定排序的 JSON", () => { - const doc = createDocument({ name: "订单" }) - const a = serialize(doc) - const b = serialize(doc) - expect(a).toBe(b) - // 键名按字典序排列:id 在 name 之前 - const parsed = JSON.parse(a) as Record - const keys = Object.keys(parsed) - expect(keys).toEqual([...keys].sort()) - }) - - it("pretty 输出含换行", () => { - const doc = createDocument() - expect(serialize(doc, { pretty: true })).toContain("\n") - expect(serialize(doc)).not.toContain("\n") - }) - - it("序列化前自动带上当前 schemaVersion", () => { - const doc = createDocument() - const parsed = JSON.parse(serialize(doc)) as { schemaVersion: number } - expect(parsed.schemaVersion).toBe(CURRENT_SCHEMA_VERSION) - }) - - it("拒绝含函数的文档(§3.5 纯数据约束)", () => { - const doc = createDocument() - ;(doc as unknown as Record).bad = () => 1 - expect(() => serialize(doc)).toThrow(TypeError) - }) - - it("serializeValue 拒绝函数", () => { - expect(() => serializeValue({ fn: () => 1 })).toThrow(TypeError) - }) - - it("toPlainObject 返回可写盘对象", () => { - const plain = toPlainObject(createDocument({ name: "X" })) - expect(plain.schemaVersion).toBe(CURRENT_SCHEMA_VERSION) - expect(() => JSON.stringify(plain)).not.toThrow() - }) -}) - -describe("deserialize", () => { - it("往返一致", () => { - const doc = createDocument({ name: "往返测试" }) - const result = deserialize(serialize(doc)) - expect(result.ok).toBe(true) - expect(result.document?.name).toBe("往返测试") - expect(result.document?.id).toBe(doc.id) - }) - - it("保留元素内容", () => { - const doc = createDocument() - doc.sections[1]!.children = [ - { id: "e1", type: "text", frame: { x: 1, y: 2, width: 3, height: 4 }, props: { text: "你好" } }, - ] - const result = deserialize(serialize(doc)) - const element = result.document?.sections[1]?.children[0] - expect(element?.id).toBe("e1") - expect((element?.props as { text: string }).text).toBe("你好") - expect(element?.frame).toEqual({ x: 1, y: 2, width: 3, height: 4 }) - }) - - it("JSON 语法错误时返回 ok:false 且不抛异常", () => { - const result = deserialize("{ 不是合法 JSON") - expect(result.ok).toBe(false) - expect(result.document).toBeNull() - expect(result.diagnostics[0]?.code).toBe(DIAGNOSTIC_CODES.SCHEMA_INVALID) - }) - - it("根节点非对象时失败", () => { - const result = deserialize("[]") - expect(result.ok).toBe(false) - expect(result.document).toBeNull() - }) - - it("缺少 schemaVersion 时给出诊断", () => { - const doc = createDocument() - const raw = JSON.parse(serialize(doc)) as Record - delete raw.schemaVersion - const result = deserialize(JSON.stringify(raw)) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.SCHEMA_VERSION_MISSING)).toBe(true) - }) - - it("未注册的插件元素类型产生告警而非失败", () => { - const doc = createDocument() - doc.sections[1]!.children = [ - { id: "q1", type: "qrcode", frame: { x: 0, y: 0, width: 20, height: 20 } }, - ] - const json = serialize(doc) - const result = deserialize(json, { pluginElementTypes: new Set(["text"]) }) - expect(result.document).not.toBeNull() - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE)).toBe(true) - }) - - it("已注册的插件元素类型不产生告警", () => { - const doc = createDocument() - doc.sections[1]!.children = [ - { id: "q1", type: "qrcode", frame: { x: 0, y: 0, width: 20, height: 20 } }, - ] - const result = deserialize(serialize(doc), { pluginElementTypes: new Set(["qrcode"]) }) - expect( - result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE), - ).toBe(false) - }) - - it("引用不存在的数据集给出诊断", () => { - const doc = createDocument() - doc.sections[1]!.children = [ - { - id: "t1", - type: "table", - frame: { x: 0, y: 0, width: 100, height: 30 }, - datasetId: "不存在", - columns: [{ id: "c1", width: 30 }], - } as TableElement, - ] - const result = deserialize(serialize(doc)) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.REF_DANGLING_DATASET)).toBe(true) - }) - - it("严格模式在结构错误时直接失败", () => { - const result = deserializeStrictly(JSON.stringify({ id: "x" })) - expect(result.ok).toBe(false) - expect(result.document).toBeNull() - }) - - it("宽松模式仍然返回文档", () => { - const result = deserializeLeniently(JSON.stringify({ id: "x", name: "y", page: { paper: "A4" }, sections: [] })) - expect(result.document).not.toBeNull() - }) - - it("tryDeserialize 只返回文档", () => { - const doc = createDocument({ name: "便捷" }) - expect(tryDeserialize(serialize(doc))?.name).toBe("便捷") - expect(tryDeserialize("坏 JSON")).toBeNull() - }) - - it("summarizeDiagnostics 汇总计数", () => { - expect(summarizeDiagnostics([])).toBe("无诊断信息") - const summary = summarizeDiagnostics([ - { severity: "error", code: "a", message: "m" }, - { severity: "warning", code: "b", message: "m" }, - ]) - expect(summary).toContain("错误 1") - expect(summary).toContain("警告 1") - }) - - it("拒绝高于当前版本的文档", () => { - const doc = createDocument() - const raw = JSON.parse(serialize(doc)) as Record - raw.schemaVersion = CURRENT_SCHEMA_VERSION + 5 - const result = deserialize(JSON.stringify(raw)) - expect(result.ok).toBe(false) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.SCHEMA_VERSION_UNKNOWN)).toBe(true) - }) -}) - -describe("migrate", () => { - it("同版本不产生迁移步骤", () => { - const result = migrate({ schemaVersion: CURRENT_SCHEMA_VERSION }) - expect(result.applied).toEqual([]) - expect(result.fromVersion).toBe(CURRENT_SCHEMA_VERSION) - }) - - it("缺少 schemaVersion 时失败", () => { - const result = migrate({ id: "x" }) - expect(result.diagnostics.some((d) => d.severity === "error")).toBe(true) - }) - - it("按版本逐步执行迁移", () => { - const migrations: Migration[] = [ - { - from: 1, - to: 2, - description: "重命名字段 name → title", - migrate: (doc) => { - const out = { ...doc } - out.title = doc.name - delete out.name - return out - }, - }, - { - from: 2, - to: 3, - description: "补上 units 字段", - migrate: (doc) => ({ ...doc, units: "mm" }), - }, - ] - const result = migrate({ schemaVersion: 1, name: "旧文档" }, 3, migrations) - expect(result.toVersion).toBe(3) - expect(result.applied).toHaveLength(2) - expect(result.document.title).toBe("旧文档") - expect(result.document.units).toBe("mm") - expect(result.document.name).toBeUndefined() - }) - - it("缺失中间迁移时报告失败", () => { - const migrations: Migration[] = [ - { from: 2, to: 3, description: "only", migrate: (doc) => doc }, - ] - const result = migrate({ schemaVersion: 1 }, 3, migrations) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.SCHEMA_MIGRATION_FAILED)).toBe(true) - }) - - it("禁止跨版本迁移", () => { - const migrations: Migration[] = [ - { from: 1, to: 3, description: "跳版本", migrate: (doc) => doc }, - ] - const result = migrate({ schemaVersion: 1 }, 3, migrations) - expect(result.diagnostics.some((d) => d.code === DIAGNOSTIC_CODES.SCHEMA_MIGRATION_FAILED)).toBe(true) - }) - - it("迁移函数抛异常时不崩溃", () => { - const migrations: Migration[] = [ - { - from: 1, - to: 2, - description: "会爆炸的迁移", - migrate: () => { - throw new Error("boom") - }, - }, - ] - const result = migrate({ schemaVersion: 1 }, 2, migrations) - expect(result.diagnostics.some((d) => d.severity === "error")).toBe(true) - expect(result.toVersion).toBe(1) - }) - - it("needsMigration 判断", () => { - expect(needsMigration({ schemaVersion: 0 })).toBe(false) - expect(needsMigration({ schemaVersion: CURRENT_SCHEMA_VERSION })).toBe(false) - expect(needsMigration({})).toBe(false) - }) -}) diff --git a/code/one-designer/packages/report-core/tests/validation.test.ts b/code/one-designer/packages/report-core/tests/validation.test.ts deleted file mode 100644 index 21c52ca7..00000000 --- a/code/one-designer/packages/report-core/tests/validation.test.ts +++ /dev/null @@ -1,346 +0,0 @@ -/** - * 结构校验与引用完整性测试(对应 §12、§13、§14)。 - */ -import { describe, expect, it } from "vitest" -import { - detectStyleCycles, - validateDocument, - validateStructure, -} from "../src/schema/validation.js" -import { createDocument } from "../src/document/create.js" -import { DIAGNOSTIC_CODES } from "../src/diagnostics/diagnostic.js" -import { CURRENT_SCHEMA_VERSION } from "../src/schema/version.js" -import type { ReportDocument } from "../src/model/report.js" -import type { StyleDefinition } from "../src/model/style.js" -import type { TableElement } from "../src/model/table.js" - -function baseDocument(): ReportDocument { - return createDocument({ name: "校验测试" }) -} - -describe("validateStructure", () => { - it("合法文档无诊断", () => { - expect(validateStructure(baseDocument())).toEqual([]) - }) - - it("非对象根节点报错", () => { - const d = validateStructure(null) - expect(d[0]?.code).toBe(DIAGNOSTIC_CODES.SCHEMA_INVALID) - }) - - it("缺少必填字段报错并指出路径", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - delete doc.name - const d = validateStructure(doc) - const missing = d.find((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING) - expect(missing?.path).toBe("/name") - }) - - it("非法 paper 值报错", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - ;(doc.page as Record).paper = "B5" - const d = validateStructure(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_ENUM_INVALID && x.path === "/page/paper")).toBe(true) - }) - - it("自定义纸张必须有正尺寸", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - ;(doc.page as Record).paper = "custom" - ;(doc.page as Record).customSize = { width: 0, height: 100 } - const d = validateStructure(doc) - expect(d.some((x) => x.path === "/page/customSize/width")).toBe(true) - }) - - it("元素缺少 id 报错", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - ;(doc.sections as Record[])[1]!.children = [ - { type: "text", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ] - const d = validateStructure(doc) - expect(d.some((x) => x.path === "/sections/1/children/0/id")).toBe(true) - }) - - it("元素 frame 非对象报错", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - ;(doc.sections as Record[])[1]!.children = [ - { id: "e1", type: "text", frame: "bad" }, - ] - const d = validateStructure(doc) - expect(d.some((x) => x.path === "/sections/1/children/0/frame")).toBe(true) - }) - - it("拒绝不可序列化的值", () => { - const doc = baseDocument() as unknown as Record - doc.fn = () => 1 - const d = validateStructure(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_INVALID)).toBe(true) - }) - - it("sections 非数组报错", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - doc.sections = "bad" - const d = validateStructure(doc) - expect(d.some((x) => x.path === "/sections")).toBe(true) - }) - - it("schemaVersion 非整数报错", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - doc.schemaVersion = 1.5 - const d = validateStructure(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_VERSION_UNKNOWN)).toBe(true) - }) -}) - -describe("validateDocument", () => { - it("合法文档无诊断", () => { - expect(validateDocument(baseDocument())).toEqual([]) - }) - - it("检测重复元素 ID", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "dup", type: "text", frame: { x: 0, y: 0, width: 1, height: 1 } }, - { id: "dup", type: "text", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.REF_DUPLICATE_ID)).toBe(true) - }) - - it("检测指向不存在样式", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "e1", type: "text", frame: { x: 0, y: 0, width: 1, height: 1 }, styleId: "nope" }, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.REF_DANGLING_STYLE)).toBe(true) - }) - - it("检测指向不存在的数据集", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { - id: "t1", - type: "table", - frame: { x: 0, y: 0, width: 50, height: 20 }, - datasetId: "nope", - columns: [{ id: "c1", width: 20 }], - } as TableElement, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.REF_DANGLING_DATASET)).toBe(true) - }) - - it("数据集引用不存在的数据源产生告警", () => { - const doc = baseDocument() - doc.datasets = { ds1: { id: "ds1", sourceId: "nope" } } - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.REF_DANGLING_DATASOURCE)).toBe(true) - }) - - it("未知元素类型在提供插件清单时视为错误", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "x1", type: "unknown-widget", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ] - const d = validateDocument(doc, { pluginElementTypes: new Set(["qrcode"]) }) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE && x.severity === "error")).toBe(true) - }) - - it("未知元素类型在未提供插件清单时降级为告警", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "x1", type: "unknown-widget", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE && x.severity === "warning")).toBe(true) - }) - - it("已注册的插件元素类型不报错", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "q1", type: "qrcode", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ] - const d = validateDocument(doc, { pluginElementTypes: new Set(["qrcode"]) }) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE)).toBe(false) - }) - - it("叶子元素带 children 报错", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { - id: "t1", - type: "text", - frame: { x: 0, y: 0, width: 1, height: 1 }, - children: [{ id: "c1", type: "text", frame: { x: 0, y: 0, width: 1, height: 1 } }], - }, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.ELEMENT_CHILD_NOT_ALLOWED)).toBe(true) - }) - - it("负宽高报错", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "e1", type: "text", frame: { x: 0, y: 0, width: -5, height: 1 } }, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.ELEMENT_FRAME_INVALID)).toBe(true) - }) - - it("明细表列宽必须为正", () => { - const doc = baseDocument() - doc.datasets = { ds1: { id: "ds1" } } - doc.sections[1]!.children = [ - { - id: "t1", - type: "table", - frame: { x: 0, y: 0, width: 50, height: 20 }, - datasetId: "ds1", - columns: [{ id: "c1", width: 0 }], - } as TableElement, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_RANGE_INVALID)).toBe(true) - }) - - it("明细表缺少 datasetId 报错", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { - id: "t1", - type: "table", - frame: { x: 0, y: 0, width: 50, height: 20 }, - columns: [{ id: "c1", width: 20 }], - } as never, - ] - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING)).toBe(true) - }) - - it("非法参数名报错", () => { - const doc = baseDocument() - doc.parameters = { p1: { id: "p1", name: "非法 名称" } } - const d = validateDocument(doc) - expect(d.some((x) => x.path === "/parameters/p1/name")).toBe(true) - }) - - it("重复参数名报错", () => { - const doc = baseDocument() - doc.parameters = { - p1: { id: "p1", name: "same" }, - p2: { id: "p2", name: "same" }, - } - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.REF_DUPLICATE_ID)).toBe(true) - }) - - it("保留区域产生提示性告警", () => { - const doc = baseDocument() - doc.sections.push({ id: "s9", kind: "summary", children: [] }) - const d = validateDocument(doc) - expect(d.some((x) => x.path === "/sections/3/kind")).toBe(true) - }) - - it("嵌套元素也会被校验", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { - id: "ct1", - type: "container", - frame: { x: 0, y: 0, width: 50, height: 50 }, - children: [ - { id: "bad", type: "nope-plugin", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ], - }, - ] - const d = validateDocument(doc, { pluginElementTypes: new Set() }) - expect( - d.some( - (x) => - x.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE && - x.path === "/sections/1/children/0/children/0/type", - ), - ).toBe(true) - }) - - it("表格单元格内元素也会被校验", () => { - const doc = baseDocument() - doc.datasets = { ds1: { id: "ds1" } } - doc.sections[1]!.children = [ - { - id: "t1", - type: "table", - frame: { x: 0, y: 0, width: 50, height: 20 }, - datasetId: "ds1", - columns: [ - { - id: "c1", - width: 20, - children: [ - { id: "bad", type: "nope-plugin", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ], - }, - ], - } as TableElement, - ] - const d = validateDocument(doc, { pluginElementTypes: new Set() }) - expect(d.some((x) => x.elementId === "bad")).toBe(true) - }) - - it("诊断指向具体元素 ID", () => { - const doc = baseDocument() - doc.sections[1]!.children = [ - { id: "el-42", type: "nope", frame: { x: 0, y: 0, width: 1, height: 1 } }, - ] - const d = validateDocument(doc, { pluginElementTypes: new Set() }) - const target = d.find((x) => x.code === DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE) - expect(target?.elementId).toBe("el-42") - }) -}) - -describe("detectStyleCycles", () => { - it("无循环时返回空", () => { - const styles: Record = { - a: { id: "a" }, - b: { id: "b", extends: "a" }, - } - expect(detectStyleCycles(styles)).toEqual([]) - }) - - it("检测直接自引用", () => { - const cycles = detectStyleCycles({ a: { id: "a", extends: "a" } }) - expect(cycles.length).toBeGreaterThan(0) - }) - - it("检测多级循环", () => { - const cycles = detectStyleCycles({ - a: { id: "a", extends: "b" }, - b: { id: "b", extends: "a" }, - }) - expect(cycles.length).toBeGreaterThan(0) - }) - - it("循环继承在校验中报错", () => { - const doc = baseDocument() - doc.styles = { - a: { id: "a", extends: "b" }, - b: { id: "b", extends: "a" }, - } - const d = validateDocument(doc) - expect(d.some((x) => x.code === DIAGNOSTIC_CODES.REF_CYCLE_DETECTED)).toBe(true) - }) -}) - -describe("schemaVersion 边界", () => { - it("当前版本被接受", () => { - const doc = baseDocument() - doc.schemaVersion = CURRENT_SCHEMA_VERSION - expect(validateStructure(doc)).toEqual([]) - }) - - it("版本 0 被拒绝", () => { - const doc = JSON.parse(JSON.stringify(baseDocument())) as Record - doc.schemaVersion = 0 - expect(validateStructure(doc).some((x) => x.code === DIAGNOSTIC_CODES.SCHEMA_VERSION_UNKNOWN)).toBe(true) - }) -}) diff --git a/code/one-designer/packages/report-core/tsconfig.json b/code/one-designer/packages/report-core/tsconfig.json deleted file mode 100644 index ae429f46..00000000 --- a/code/one-designer/packages/report-core/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src" - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist", "tests"] -} diff --git a/code/one-designer/packages/report-core/tsconfig.test.json b/code/one-designer/packages/report-core/tsconfig.test.json deleted file mode 100644 index 6cefc694..00000000 --- a/code/one-designer/packages/report-core/tsconfig.test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "noEmit": true, - "types": ["node", "vitest/globals"] - }, - "include": ["src/**/*.ts", "tests/**/*.ts", "*.config.ts"] -} diff --git a/code/one-designer/packages/report-core/tsup.config.ts b/code/one-designer/packages/report-core/tsup.config.ts deleted file mode 100644 index be47bf93..00000000 --- a/code/one-designer/packages/report-core/tsup.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "tsup" - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["esm", "cjs"], - dts: true, - sourcemap: true, - clean: true, - treeshake: true, - target: "es2022", -}) diff --git a/code/one-designer/packages/report-core/vitest.config.ts b/code/one-designer/packages/report-core/vitest.config.ts deleted file mode 100644 index 0af27743..00000000 --- a/code/one-designer/packages/report-core/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "vitest/config" - -export default defineConfig({ - test: { - include: ["tests/**/*.test.ts"], - environment: "node", - }, -}) diff --git a/code/one-designer/packages/report-designer-vue/package.json b/code/one-designer/packages/report-designer-vue/package.json deleted file mode 100644 index 02753eab..00000000 --- a/code/one-designer/packages/report-designer-vue/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@report/designer-vue", - "version": "0.1.0", - "description": "报表设计器的 Vue 组件层(画布、工具栏、面板、状态栏),Headless 思路,宿主可覆写主题", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" - }, - "./style.css": "./dist/style.css" - }, - "files": ["dist"], - "scripts": { - "build": "vite build", - "dev": "vite build --watch", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "vue-tsc --noEmit -p tsconfig.test.json" - }, - "dependencies": { - "@report/core": "workspace:*", - "@report/layout": "workspace:*", - "@report/designer": "workspace:*" - }, - "peerDependencies": { - "vue": "^3.4.0" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^5.2.1", - "@vue/test-utils": "^2.4.6", - "jsdom": "^25.0.1", - "typescript": "^5.7.2", - "vite": "^5.4.11", - "vitest": "^2.1.8", - "vue": "^3.5.13", - "vue-tsc": "^2.1.10" - } -} diff --git a/code/one-designer/packages/report-designer-vue/src/ReportDesigner.vue b/code/one-designer/packages/report-designer-vue/src/ReportDesigner.vue deleted file mode 100644 index 964d7211..00000000 --- a/code/one-designer/packages/report-designer-vue/src/ReportDesigner.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/components/ReportCanvas.vue b/code/one-designer/packages/report-designer-vue/src/components/ReportCanvas.vue deleted file mode 100644 index ed35c081..00000000 --- a/code/one-designer/packages/report-designer-vue/src/components/ReportCanvas.vue +++ /dev/null @@ -1,317 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/components/ReportProperties.vue b/code/one-designer/packages/report-designer-vue/src/components/ReportProperties.vue deleted file mode 100644 index 3d131ad5..00000000 --- a/code/one-designer/packages/report-designer-vue/src/components/ReportProperties.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/components/ReportRuler.vue b/code/one-designer/packages/report-designer-vue/src/components/ReportRuler.vue deleted file mode 100644 index 8ce10e50..00000000 --- a/code/one-designer/packages/report-designer-vue/src/components/ReportRuler.vue +++ /dev/null @@ -1,141 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/components/ReportStatusbar.vue b/code/one-designer/packages/report-designer-vue/src/components/ReportStatusbar.vue deleted file mode 100644 index 79f77502..00000000 --- a/code/one-designer/packages/report-designer-vue/src/components/ReportStatusbar.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/components/ReportToolbar.vue b/code/one-designer/packages/report-designer-vue/src/components/ReportToolbar.vue deleted file mode 100644 index 34669d29..00000000 --- a/code/one-designer/packages/report-designer-vue/src/components/ReportToolbar.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/components/ReportToolbox.vue b/code/one-designer/packages/report-designer-vue/src/components/ReportToolbox.vue deleted file mode 100644 index 7301e110..00000000 --- a/code/one-designer/packages/report-designer-vue/src/components/ReportToolbox.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - - - diff --git a/code/one-designer/packages/report-designer-vue/src/index.ts b/code/one-designer/packages/report-designer-vue/src/index.ts deleted file mode 100644 index 7cd21b09..00000000 --- a/code/one-designer/packages/report-designer-vue/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @report/designer-vue 公共入口(对应设计文档 §4.6、§14)。 - * - * 只负责 Vue 组件、面板和样式实现,不向 Core 泄漏 Vue 类型。 - * 组件采用 Headless 思路,宿主可覆写主题(通过 CSS 变量)。 - */ -import ReportDesigner from "./ReportDesigner.vue" -import ReportToolbar from "./components/ReportToolbar.vue" -import ReportToolbox from "./components/ReportToolbox.vue" -import ReportCanvas from "./components/ReportCanvas.vue" -import ReportRuler from "./components/ReportRuler.vue" -import ReportProperties from "./components/ReportProperties.vue" -import ReportStatusbar from "./components/ReportStatusbar.vue" - -export { - ReportDesigner, - ReportToolbar, - ReportToolbox, - ReportCanvas, - ReportRuler, - ReportProperties, - ReportStatusbar, -} - -export { themeCss, injectThemeStyle } from "./theme.js" -export { useEditor } from "./use-editor.js" -export { useShortcuts } from "./use-shortcuts.js" diff --git a/code/one-designer/packages/report-designer-vue/src/ruler.ts b/code/one-designer/packages/report-designer-vue/src/ruler.ts deleted file mode 100644 index 94f90c41..00000000 --- a/code/one-designer/packages/report-designer-vue/src/ruler.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 标尺刻度计算(对应设计文档 §14.7 画布规范)。 - * - * 抽成纯函数的原因:步长选择、标签密度这类逻辑很容易在缩放时出边界问题, - * 放在组件里只能靠渲染结果间接验证,单独拿出来可以直接断言。 - * - * 坐标约定:刻度位置 `px` 是**距页面原点的显示像素**,已含缩放; - * `mm` 是距页面原点的毫米值(即文档坐标)。 - */ -import { mmToPx } from "@report/layout" - -/** 主刻度候选步长(mm)。 */ -const TICK_CANDIDATES_MM = [1, 2, 5, 10, 20, 50] as const - -/** 标签候选步长(mm),需比主刻度更稀疏。 */ -const LABEL_CANDIDATES_MM = [1, 2, 5, 10, 20, 50, 100] as const - -/** 主刻度最小视觉间距(px),低于此值刻度会糊成一片。 */ -const MIN_TICK_SPACING_PX = 8 - -/** 标签最小视觉间距(px),低于此值数字会重叠。 */ -const MIN_LABEL_SPACING_PX = 40 - -/** 刻度数量上限,防止自定义纸张尺寸过大时生成海量 DOM。 */ -const MAX_TICKS = 1000 - -/** 一根刻度。 */ -export interface RulerTick { - /** 距页面原点的毫米值。 */ - mm: number - /** 距页面原点的显示像素(已含缩放)。 */ - px: number - /** 需要显示的数字标签;次刻度为 undefined。 */ - label?: string -} - -/** 从候选步长里取第一个在给定缩放下间距达标的。 */ -function firstFitting( - candidates: readonly number[], - zoom: number, - minSpacingPx: number, - atLeastMm = 0, -): number { - for (const candidate of candidates) { - if (candidate < atLeastMm) continue - if (mmToPx(candidate) * zoom >= minSpacingPx) return candidate - } - return candidates[candidates.length - 1]! -} - -/** 按缩放选择主刻度步长(mm)。 */ -export function chooseRulerStepMm(zoom: number): number { - return firstFitting(TICK_CANDIDATES_MM, zoom, MIN_TICK_SPACING_PX) -} - -/** - * 生成标尺刻度。 - * - * @param lengthMm 标尺覆盖的长度(mm),通常是纸张宽/高。 - * @param zoom 当前缩放比例。 - */ -export function buildRulerTicks(lengthMm: number, zoom: number): RulerTick[] { - if (!(lengthMm > 0) || !(zoom > 0)) return [] - - const stepMm = chooseRulerStepMm(zoom) - // 标签步长与主刻度步长都取自同一套候选值,因此 labelEvery 一定是正整数。 - const labelStepMm = firstFitting( - LABEL_CANDIDATES_MM, - zoom, - MIN_LABEL_SPACING_PX, - stepMm, - ) - const labelEvery = Math.max(1, Math.round(labelStepMm / stepMm)) - - const ticks: RulerTick[] = [] - // 加 1e-9 防止 210 / 5 这类整除因浮点误差少算一根。 - const count = Math.min(MAX_TICKS - 1, Math.floor(lengthMm / stepMm + 1e-9)) - for (let i = 0; i <= count; i += 1) { - const mm = i * stepMm - const px = mmToPx(mm) * zoom - if (i % labelEvery === 0) { - ticks.push({ mm, px, label: String(Math.round(mm)) }) - } else { - ticks.push({ mm, px }) - } - } - return ticks -} diff --git a/code/one-designer/packages/report-designer-vue/src/theme.ts b/code/one-designer/packages/report-designer-vue/src/theme.ts deleted file mode 100644 index bc06c6f9..00000000 --- a/code/one-designer/packages/report-designer-vue/src/theme.ts +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 设计令牌(对应设计文档 §14.4)。 - * - * 使用 CSS 自定义属性作为主题契约,提供亮色与暗色两套主题。 - * 宿主应用可通过覆写这些变量来定制品牌色,但必须保持语义: - * background / canvas / foreground / muted / border / primary / - * destructive / selection。 - * - * 颜色使用 HSL 空间(h s% l% 三元组),便于组件里用 hsl(var(--x)) 拼装。 - */ -export const themeCss = /* css */ ` -:root { - --rd-background: 0 0% 100%; - --rd-foreground: 222 47% 11%; - --rd-muted: 210 40% 96%; - --rd-muted-foreground: 215 16% 47%; - --rd-border: 214 32% 91%; - --rd-input: 214 32% 91%; - --rd-primary: 221 83% 53%; - --rd-primary-foreground: 210 40% 98%; - --rd-destructive: 0 72% 51%; - --rd-canvas: 220 14% 96%; - --rd-selection: 221 83% 53%; - --rd-radius: 8px; - - /* 纸张与墨色:属于文档表面,不随亮/暗主题切换(§14.7)。 */ - --rd-paper: 0 0% 100%; - --rd-ink: 222 47% 11%; -} - -.dark { - --rd-background: 222 47% 11%; - --rd-foreground: 210 40% 98%; - --rd-muted: 217 33% 17%; - --rd-muted-foreground: 215 20% 65%; - --rd-border: 217 33% 17%; - --rd-input: 217 33% 17%; - --rd-primary: 217 91% 60%; - --rd-primary-foreground: 222 47% 11%; - --rd-destructive: 0 63% 31%; - --rd-canvas: 222 47% 8%; - --rd-selection: 217 91% 60%; -} - -.rd-designer { - color: hsl(var(--rd-foreground)); - background: hsl(var(--rd-background)); - font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", - "PingFang SC", "Microsoft YaHei", sans-serif; - font-size: 13px; - line-height: 1.4; -} - -.rd-designer * { - box-sizing: border-box; -} -` - -/** 注入主题样式到文档 head(幂等)。 */ -export function injectThemeStyle(): void { - if (typeof document === "undefined") return - const id = "rd-designer-theme" - if (document.getElementById(id)) return - const style = document.createElement("style") - style.id = id - style.textContent = themeCss - document.head.appendChild(style) -} diff --git a/code/one-designer/packages/report-designer-vue/src/use-editor.ts b/code/one-designer/packages/report-designer-vue/src/use-editor.ts deleted file mode 100644 index 55c8d92e..00000000 --- a/code/one-designer/packages/report-designer-vue/src/use-editor.ts +++ /dev/null @@ -1,185 +0,0 @@ -/** - * 编辑器响应式绑定(composable)。 - * - * 把 designer 包的 EditorSession(非响应式类)包装成 Vue 响应式状态, - * 供组件消费。文档与状态变化时触发重渲染。 - * - * 这里只暴露组件真正用到的能力。designer 包里还有 pan / hoveredId 等 - * 状态,但当前画布用滚动容器承载平移、也没有 hover 高亮,故暂不暴露, - * 避免出现「有 API 没人用」的死代码。 - */ -import { reactive, readonly, computed } from "vue" -import type { ReportDocument, ReportElement, Rect } from "@report/core" -import type { EditorSession } from "@report/designer" - -/** 把 EditorSession 包装成响应式视图。 */ -export function useEditor(editor: EditorSession) { - // 用一个自增版本号驱动重渲染:EditorSession 内部是不可变替换, - // 没有 Vue 的响应式钩子,这里在每次操作后手动 bump。 - const state = reactive({ - version: 0, - document: editor.getDocument() as ReportDocument, - selectedIds: [] as string[], - zoom: editor.getState().zoom, - /** 是否正在拖拽(用于切换光标)。 */ - dragging: false, - }) - - /** 同步编辑器最新状态到响应式视图。 */ - function sync(): void { - state.version += 1 - state.document = editor.getDocument() - state.selectedIds = editor.getSelectedIds() - state.zoom = editor.getState().zoom - state.dragging = editor.isDragging() - } - - // ------------------------------------------------------------------------- - // 选择 - // ------------------------------------------------------------------------- - - /** 选中单个元素。 */ - function select(id: string): void { - editor.select(id) - sync() - } - - /** 多选。 */ - function selectMany(ids: string[]): void { - editor.selectMany(ids) - sync() - } - - /** 切换单个元素的选中态(Ctrl/Cmd + 点击)。 */ - function toggleSelect(id: string): void { - editor.toggleSelect(id) - sync() - } - - /** 清空选中。 */ - function clearSelection(): void { - editor.clearSelection() - sync() - } - - // ------------------------------------------------------------------------- - // 编辑操作 - // ------------------------------------------------------------------------- - - /** 移动元素(frame 为文档绝对坐标 mm)。 */ - function move(frames: Record): void { - editor.moveElements(frames) - sync() - } - - /** 删除当前选中的元素。 */ - function deleteSelected(): void { - editor.deleteSelected() - sync() - } - - /** 复制当前选中元素到剪贴板。 */ - function copy(): void { - editor.copy() - } - - /** 粘贴剪贴板元素到指定区域。 */ - function paste(sectionId: string): void { - editor.paste(sectionId) - sync() - } - - // ------------------------------------------------------------------------- - // 拖拽 - // ------------------------------------------------------------------------- - - /** - * 开始拖拽。 - * - * startX / startY 为指针对应的文档坐标(mm),仅用于记录起点。 - */ - function beginDrag(startX: number, startY: number): void { - editor.beginDrag(startX, startY) - sync() - } - - /** - * 拖拽更新。 - * - * dx / dy 必须是**文档坐标(mm)**位移量——调用方负责把屏幕像素 - * 除以缩放比例再换算成 mm。吸附由 EditorSession 内部处理。 - */ - function updateDrag(dx: number, dy: number): void { - editor.updateDrag(dx, dy) - sync() - } - - /** 结束拖拽。 */ - function endDrag(): void { - editor.endDrag() - sync() - } - - /** 是否正在拖拽。 */ - function isDragging(): boolean { - return editor.isDragging() - } - - // ------------------------------------------------------------------------- - // 撤销 / 重做 / 视图 - // ------------------------------------------------------------------------- - - /** 撤销。 */ - function undo(): void { - editor.undo() - sync() - } - - /** 重做。 */ - function redo(): void { - editor.redo() - sync() - } - - /** 缩放。 */ - function setZoom(zoom: number): void { - editor.setZoom(zoom) - sync() - } - - /** 收集文档所有顶层元素(供画布渲染)。 */ - function elements(): ReportElement[] { - const doc = state.document - const detail = doc.sections.find((s) => s.kind === "detail") - if (!detail) return [] - return detail.children - } - - return { - state: readonly(state), - editor, - sync, - select, - selectMany, - toggleSelect, - clearSelection, - move, - deleteSelected, - copy, - paste, - beginDrag, - updateDrag, - endDrag, - isDragging, - undo, - redo, - setZoom, - elements, - // canUndo/canRedo 必须依赖响应式的 version 计数器: - // EditorSession 是普通类,其内部变化 Vue 无法追踪, - // 若只调用 editor.canUndo(),computed 将永远停留在初始值 false, - // 撤销/重做按钮永远禁用。读一下 state.version 让 sync() 后重新求值。 - canUndo: computed(() => (state.version >= 0, editor.canUndo())), - canRedo: computed(() => (state.version >= 0, editor.canRedo())), - } -} diff --git a/code/one-designer/packages/report-designer-vue/src/use-shortcuts.ts b/code/one-designer/packages/report-designer-vue/src/use-shortcuts.ts deleted file mode 100644 index 52dbfb39..00000000 --- a/code/one-designer/packages/report-designer-vue/src/use-shortcuts.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 编辑器快捷键(对应设计文档 §14.9)。 - * - * 监听挂在 window 上:画布本身不可聚焦,挂在组件根上会因焦点不在其中而失效。 - * - * 关键约束:属性面板里有文本输入框,若不过滤输入态,用户在输入框里按 - * Delete / Backspace 会连带删除画布上选中的元素。 - */ -import { onBeforeUnmount, onMounted } from "vue" -import { useEditor } from "./use-editor.js" - -/** 事件目标是否处于文本编辑态。 */ -function isEditingTarget(target: EventTarget | null): boolean { - if (!(target instanceof HTMLElement)) return false - const tag = target.tagName - return tag === "INPUT" || tag === "TEXTAREA" || target.isContentEditable -} - -/** 注册编辑器快捷键,组件卸载时自动解绑。 */ -export function useShortcuts(editor: ReturnType): void { - function onKeyDown(event: KeyboardEvent): void { - if (isEditingTarget(event.target)) return - - const mod = event.ctrlKey || event.metaKey - const key = event.key.toLowerCase() - - if (mod && key === "z") { - event.preventDefault() - // Ctrl+Shift+Z 是重做,与 Ctrl+Z 对称。 - if (event.shiftKey) editor.redo() - else editor.undo() - return - } - - // Ctrl+Y:Windows 习惯的重做键。 - if (mod && key === "y") { - event.preventDefault() - editor.redo() - return - } - - if (mod && key === "c") { - event.preventDefault() - editor.copy() - return - } - - if (mod && key === "v") { - event.preventDefault() - // 粘贴目标固定为明细区,与工具箱新增元素的口径一致。 - const detail = editor.state.document.sections.find((s) => s.kind === "detail") - if (detail) editor.paste(detail.id) - return - } - - if (event.key === "Delete" || event.key === "Backspace") { - event.preventDefault() - editor.deleteSelected() - return - } - - if (event.key === "Escape") { - editor.clearSelection() - } - } - - onMounted(() => window.addEventListener("keydown", onKeyDown)) - onBeforeUnmount(() => window.removeEventListener("keydown", onKeyDown)) -} diff --git a/code/one-designer/packages/report-designer-vue/tests/designer-vue.test.ts b/code/one-designer/packages/report-designer-vue/tests/designer-vue.test.ts deleted file mode 100644 index f0dcbad5..00000000 --- a/code/one-designer/packages/report-designer-vue/tests/designer-vue.test.ts +++ /dev/null @@ -1,404 +0,0 @@ -/** - * report-designer-vue 组件测试。 - * - * 验证: - * - 主布局挂载后渲染三栏结构(工具栏/工具箱/属性面板/状态栏/画布)。 - * - 工具箱可新增元素并反映到画布。 - * - 点击画布元素可选中,属性面板显示其信息;点击空白取消选中。 - * - 工具栏撤销可用。 - * - 画布缩放、页面尺寸、标尺刻度。 - * - 拖拽移动元素,且连续拖拽合并为一步撤销。 - * - 快捷键(Delete / Ctrl+Z),输入态下不触发。 - * - 主题样式注入是幂等的。 - */ -import { describe, expect, it, beforeEach } from "vitest" -import { mount, flushPromises } from "@vue/test-utils" -import { createDocument, type ReportDocument } from "@report/core" -import { mmToPx } from "@report/layout" -import ReportDesigner from "../src/ReportDesigner.vue" -import ReportToolbar from "../src/components/ReportToolbar.vue" -import ReportToolbox from "../src/components/ReportToolbox.vue" -import ReportCanvas from "../src/components/ReportCanvas.vue" -import ReportProperties from "../src/components/ReportProperties.vue" -import ReportStatusbar from "../src/components/ReportStatusbar.vue" -import { useEditor } from "../src/use-editor.js" -import { injectThemeStyle } from "../src/theme.js" -import { buildRulerTicks, chooseRulerStepMm } from "../src/ruler.js" -import { createEditorSession } from "@report/designer" - -function sampleDoc(): ReportDocument { - const doc = createDocument({ name: "UI 测试" }) - const detail = doc.sections.find((s) => s.kind === "detail")! - detail.children.push({ - id: "t1", - type: "text", - frame: { x: 0, y: 0, width: 50, height: 8 }, - props: { text: "标题" }, - }) - return doc -} - -/** 取画布页面的实际宽度(px),从内联样式解析。 */ -function pageWidthPx(wrapper: ReturnType): number { - const style = wrapper.find(".rd-canvas-page").attributes("style") ?? "" - const match = /width:\s*([\d.]+)px/.exec(style) - return match ? Number(match[1]) : Number.NaN -} - -/** 取画布 sizer 的宽度(px)。 */ -function sizerWidthPx(wrapper: ReturnType): number { - const style = wrapper.find(".rd-canvas-sizer").attributes("style") ?? "" - const match = /width:\s*([\d.]+)px/.exec(style) - return match ? Number(match[1]) : Number.NaN -} - -/** 在工具栏里按 aria-label 找按钮。 */ -function toolbarButton(wrapper: ReturnType, label: string) { - return wrapper - .findComponent(ReportToolbar) - .findAll("button") - .find((b) => b.attributes("aria-label") === label)! -} - -describe("ReportDesigner 主布局", () => { - it("挂载后渲染三栏结构与五个区域", () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - expect(wrapper.findComponent(ReportToolbar).exists()).toBe(true) - expect(wrapper.findComponent(ReportToolbox).exists()).toBe(true) - expect(wrapper.findComponent(ReportCanvas).exists()).toBe(true) - expect(wrapper.findComponent(ReportProperties).exists()).toBe(true) - expect(wrapper.findComponent(ReportStatusbar).exists()).toBe(true) - }) - - it("画布渲染文档中的元素", () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - const canvas = wrapper.findComponent(ReportCanvas) - expect(canvas.findAll(".rd-canvas-element").length).toBe(1) - expect(canvas.text()).toContain("标题") - }) - - it("点击画布元素后属性面板显示信息", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - const element = wrapper.find(".rd-canvas-element") - await element.trigger("mousedown") - await flushPromises() - - const properties = wrapper.findComponent(ReportProperties) - expect(properties.text()).toContain("t1") - expect(properties.text()).toContain("text") - - // mousedown 会挂上全局拖拽监听,测试结束必须卸载以解绑。 - wrapper.unmount() - }) - - it("属性面板可编辑文本内容", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - await wrapper.find(".rd-canvas-element").trigger("mousedown") - await flushPromises() - - const input = wrapper.find(".rd-prop-input") - expect(input.exists()).toBe(true) - await input.setValue("改后的标题") - await flushPromises() - - // 画布同步显示新文本 - expect(wrapper.findComponent(ReportCanvas).text()).toContain("改后的标题") - - wrapper.unmount() - }) - - it("工具箱新增文本元素并出现在画布", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - const before = wrapper.findAll(".rd-canvas-element").length - - const toolbox = wrapper.findComponent(ReportToolbox) - await toolbox.find("button").trigger("click") - await flushPromises() - - const after = wrapper.findAll(".rd-canvas-element").length - expect(after).toBe(before + 1) - }) - - it("工具栏撤销新增操作", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - const before = wrapper.findAll(".rd-canvas-element").length - - await wrapper.findComponent(ReportToolbox).find("button").trigger("click") - await flushPromises() - expect(wrapper.findAll(".rd-canvas-element").length).toBe(before + 1) - - const toolbar = wrapper.findComponent(ReportToolbar) - const undoBtn = toolbar.findAll("button").find((b) => b.attributes("aria-label") === "撤销")! - await undoBtn.trigger("click") - await flushPromises() - - expect(wrapper.findAll(".rd-canvas-element").length).toBe(before) - }) - - it("无选中时属性面板显示空态", () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - const properties = wrapper.findComponent(ReportProperties) - expect(properties.text()).toContain("未选中元素") - }) -}) - -describe("useEditor composable", () => { - it("select 与 move 反映到状态", () => { - const doc = sampleDoc() - const session = createEditorSession(doc) - const editor = useEditor(session) - - editor.select("t1") - expect(editor.state.selectedIds).toContain("t1") - - editor.move({ t1: { x: 20, y: 30, width: 50, height: 8 } }) - const moved = editor.state.document.sections - .find((s) => s.kind === "detail")!.children[0]!.frame - expect(moved.x).toBe(20) - expect(moved.y).toBe(30) - }) - - it("undo 后文档恢复", () => { - const doc = sampleDoc() - const session = createEditorSession(doc) - const editor = useEditor(session) - - editor.move({ t1: { x: 99, y: 99, width: 50, height: 8 } }) - editor.undo() - const restored = editor.state.document.sections - .find((s) => s.kind === "detail")!.children[0]!.frame - expect(restored.x).toBe(0) - }) -}) - -describe("主题注入", () => { - beforeEach(() => { - document.head.innerHTML = "" - }) - - it("注入主题样式到 head", () => { - injectThemeStyle() - const style = document.getElementById("rd-designer-theme") - expect(style).not.toBeNull() - expect(style!.textContent).toContain("--rd-background") - expect(style!.textContent).toContain(".dark") - }) - - it("重复注入是幂等的", () => { - injectThemeStyle() - injectThemeStyle() - const styles = document.querySelectorAll("#rd-designer-theme") - expect(styles.length).toBe(1) - }) -}) - -describe("标尺刻度计算", () => { - it("步长随缩放自适应,保证刻度不会挤在一起", () => { - // mmToPx(1)=3.78px、2=7.56px、5=18.9px,阈值 8px - expect(chooseRulerStepMm(1)).toBe(5) - expect(chooseRulerStepMm(2)).toBe(2) - expect(chooseRulerStepMm(0.5)).toBe(5) - }) - - it("刻度从页面原点开始且不超出纸张长度", () => { - const ticks = buildRulerTicks(210, 1) - expect(ticks.length).toBeGreaterThan(0) - expect(ticks[0]!.mm).toBe(0) - expect(ticks[0]!.px).toBe(0) - - const last = ticks[ticks.length - 1]! - expect(last.mm).toBeLessThanOrEqual(210) - // px 必须是 mm 换算后乘缩放的结果 - expect(last.px).toBeCloseTo(mmToPx(last.mm) * 1, 6) - }) - - it("标签间距不小于 40px,避免数字重叠", () => { - const labeled = buildRulerTicks(210, 1).filter((t) => t.label !== undefined) - expect(labeled.length).toBeGreaterThan(1) - for (let i = 1; i < labeled.length; i += 1) { - expect(labeled[i]!.px - labeled[i - 1]!.px).toBeGreaterThanOrEqual(40) - } - }) - - it("放大后刻度更密", () => { - expect(buildRulerTicks(210, 2).length).toBeGreaterThan( - buildRulerTicks(210, 1).length, - ) - }) - - it("非法输入返回空数组", () => { - expect(buildRulerTicks(0, 1)).toEqual([]) - expect(buildRulerTicks(210, 0)).toEqual([]) - }) -}) - -describe("标尺渲染", () => { - it("画布渲染水平与垂直标尺及刻度", () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - expect(wrapper.find(".rd-canvas-ruler-h").exists()).toBe(true) - expect(wrapper.find(".rd-canvas-ruler-v").exists()).toBe(true) - expect(wrapper.findAll(".rd-ruler-tick").length).toBeGreaterThan(0) - expect(wrapper.findAll(".rd-ruler-label").length).toBeGreaterThan(0) - }) - - it("标尺随滚动同步偏移", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - const viewport = wrapper.find(".rd-canvas-viewport") - // jsdom 没有真实布局,直接造一个滚动量再派发 scroll。 - Object.defineProperty(viewport.element, "scrollLeft", { - value: 40, - configurable: true, - }) - await viewport.trigger("scroll") - - // 轨道偏移 = 纸张起点(24) − 滚动量(40) = −16 - const track = wrapper.find(".rd-canvas-ruler-h .rd-ruler-track") - expect(track.attributes("style")).toContain("left: -16px") - }) -}) - -describe("画布页面尺寸与缩放", () => { - it("页面尺寸取自文档页面设置(A4 竖版)", () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - expect(pageWidthPx(wrapper)).toBeCloseTo(mmToPx(210), 3) - }) - - it("换成 A5 后页面尺寸随之变化", () => { - const doc = sampleDoc() - doc.page.paper = "A5" - const wrapper = mount(ReportDesigner, { props: { document: doc } }) - expect(pageWidthPx(wrapper)).toBeCloseTo(mmToPx(148), 3) - }) - - it("缩放真实作用于页面(transform),并撑开滚动区域", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - expect(wrapper.find(".rd-canvas-page").attributes("style")).toContain("scale(1)") - const beforeSizer = sizerWidthPx(wrapper) - - await toolbarButton(wrapper, "放大").trigger("click") - await flushPromises() - - // 回归:旧实现只改状态栏数字,页面 transform 不变 - expect(wrapper.find(".rd-canvas-page").attributes("style")).toContain("scale(1.25)") - expect(sizerWidthPx(wrapper)).toBeGreaterThan(beforeSizer) - }) -}) - -describe("画布拖拽", () => { - /** 直接挂 ReportCanvas,便于从 session 读取拖拽结果。 */ - function mountCanvas() { - const doc = sampleDoc() - const session = createEditorSession(doc) - const editor = useEditor(session) - const wrapper = mount(ReportCanvas, { props: { editor } }) - return { wrapper, session, editor } - } - - it("拖拽改变元素 frame,结束后退出拖拽态", async () => { - const { wrapper, session, editor } = mountCanvas() - - await wrapper.find(".rd-canvas-element").trigger("mousedown", { - clientX: 100, - clientY: 100, - }) - expect(editor.isDragging()).toBe(true) - - // 屏幕位移 96px = 25.4mm,吸附到整数 mm → 25 - document.dispatchEvent(new MouseEvent("mousemove", { clientX: 196, clientY: 100 })) - await flushPromises() - - const frame = session - .getDocument() - .sections.find((s) => s.kind === "detail")!.children[0]!.frame - expect(frame.x).toBe(25) - expect(frame.y).toBe(0) - - document.dispatchEvent(new MouseEvent("mouseup")) - await flushPromises() - expect(editor.isDragging()).toBe(false) - - wrapper.unmount() - }) - - it("一次拖拽的多次位移合并为一步撤销", async () => { - const { wrapper, session } = mountCanvas() - const detail = () => session.getDocument().sections.find((s) => s.kind === "detail")! - - await wrapper.find(".rd-canvas-element").trigger("mousedown", { - clientX: 100, - clientY: 100, - }) - // 模拟拖拽过程中的多次 mousemove - for (const x of [130, 160, 196]) { - document.dispatchEvent(new MouseEvent("mousemove", { clientX: x, clientY: 100 })) - } - document.dispatchEvent(new MouseEvent("mouseup")) - await flushPromises() - - expect(detail().children[0]!.frame.x).toBe(25) - - // 依赖 moveElementsCommand 的 mergeKey,一次撤销即回到原位 - session.undo() - expect(detail().children[0]!.frame.x).toBe(0) - - wrapper.unmount() - }) - - it("点击画布空白取消选中", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - await wrapper.find(".rd-canvas-element").trigger("mousedown") - await flushPromises() - expect(wrapper.findComponent(ReportProperties).text()).toContain("t1") - - await wrapper.find(".rd-canvas-viewport").trigger("mousedown") - await flushPromises() - expect(wrapper.findComponent(ReportProperties).text()).toContain("未选中元素") - - wrapper.unmount() - }) -}) - -describe("快捷键", () => { - it("Delete 删除选中元素", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - await wrapper.find(".rd-canvas-element").trigger("mousedown") - await flushPromises() - expect(wrapper.findAll(".rd-canvas-element").length).toBe(1) - - window.dispatchEvent(new KeyboardEvent("keydown", { key: "Delete" })) - await flushPromises() - expect(wrapper.findAll(".rd-canvas-element").length).toBe(0) - - wrapper.unmount() - }) - - it("Ctrl+Z 撤销", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - await wrapper.findComponent(ReportToolbox).find("button").trigger("click") - await flushPromises() - expect(wrapper.findAll(".rd-canvas-element").length).toBe(2) - - window.dispatchEvent(new KeyboardEvent("keydown", { key: "z", ctrlKey: true })) - await flushPromises() - expect(wrapper.findAll(".rd-canvas-element").length).toBe(1) - - wrapper.unmount() - }) - - it("输入框内按 Delete 不删除画布元素", async () => { - const wrapper = mount(ReportDesigner, { props: { document: sampleDoc() } }) - await wrapper.find(".rd-canvas-element").trigger("mousedown") - await flushPromises() - - const input = wrapper.find(".rd-prop-input") - expect(input.exists()).toBe(true) - // 以输入框为 target 冒泡到 window,快捷键必须让位给打字 - input.element.dispatchEvent( - new KeyboardEvent("keydown", { key: "Delete", bubbles: true }), - ) - await flushPromises() - expect(wrapper.findAll(".rd-canvas-element").length).toBe(1) - - wrapper.unmount() - }) -}) diff --git a/code/one-designer/packages/report-designer-vue/tsconfig.json b/code/one-designer/packages/report-designer-vue/tsconfig.json deleted file mode 100644 index 31d6714d..00000000 --- a/code/one-designer/packages/report-designer-vue/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src", - "types": ["node"], - "jsx": "preserve", - "lib": ["ES2022", "DOM", "DOM.Iterable"] - }, - "include": ["src/**/*.ts", "src/**/*.vue"], - "exclude": ["node_modules", "dist", "tests"] -} diff --git a/code/one-designer/packages/report-designer-vue/tsconfig.test.json b/code/one-designer/packages/report-designer-vue/tsconfig.test.json deleted file mode 100644 index d23fbd05..00000000 --- a/code/one-designer/packages/report-designer-vue/tsconfig.test.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "noEmit": true, - "types": ["node", "vitest/globals"], - "jsx": "preserve", - "lib": ["ES2022", "DOM", "DOM.Iterable"] - }, - "include": ["src/**/*.ts", "src/**/*.vue", "tests/**/*.ts", "*.config.ts"] -} diff --git a/code/one-designer/packages/report-designer-vue/vite.config.ts b/code/one-designer/packages/report-designer-vue/vite.config.ts deleted file mode 100644 index dd248be1..00000000 --- a/code/one-designer/packages/report-designer-vue/vite.config.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { defineConfig } from "vite" -import vue from "@vitejs/plugin-vue" -import { resolve } from "node:path" - -export default defineConfig({ - plugins: [vue()], - build: { - lib: { - entry: resolve(__dirname, "src/index.ts"), - // 显式指定 es + cjs:缺省的 umd 需要 output.globals, - // 库场景下宿主走打包器消费,不需要 UMD。 - formats: ["es", "cjs"], - fileName: (format) => (format === "es" ? "index.js" : "index.cjs"), - }, - rollupOptions: { - // 工作区兄弟包与 vue 保持 external,由宿主提供。 - external: ["vue", "@report/core", "@report/layout", "@report/designer"], - output: { - // 只用具名导出,避免 ESM/CJS 互操作时 .default 歧义。 - exports: "named", - }, - }, - sourcemap: true, - }, -}) diff --git a/code/one-designer/packages/report-designer-vue/vitest.config.ts b/code/one-designer/packages/report-designer-vue/vitest.config.ts deleted file mode 100644 index d9254911..00000000 --- a/code/one-designer/packages/report-designer-vue/vitest.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { defineConfig } from "vitest/config" -import vue from "@vitejs/plugin-vue" - -export default defineConfig({ - plugins: [vue()], - test: { - include: ["tests/**/*.test.ts"], - environment: "jsdom", - }, -}) diff --git a/code/one-designer/packages/report-designer/package.json b/code/one-designer/packages/report-designer/package.json deleted file mode 100644 index 3e0f8240..00000000 --- a/code/one-designer/packages/report-designer/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@report/designer", - "version": "0.1.0", - "description": "报表编辑器的状态、命令、选择、坐标转换与交互逻辑(无 UI)", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" - } - }, - "files": ["dist"], - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit -p tsconfig.test.json" - }, - "dependencies": { - "@report/core": "workspace:*", - "@report/layout": "workspace:*" - }, - "devDependencies": { - "@report/renderer": "workspace:*", - "tsup": "^8.3.5", - "typescript": "^5.7.2", - "vitest": "^2.1.8" - } -} diff --git a/code/one-designer/packages/report-designer/src/commands.ts b/code/one-designer/packages/report-designer/src/commands.ts deleted file mode 100644 index fb54ae4f..00000000 --- a/code/one-designer/packages/report-designer/src/commands.ts +++ /dev/null @@ -1,213 +0,0 @@ -/** - * Designer 编辑命令(对应设计文档 §4.5)。 - * - * Designer 通过 Core 的命令接口修改文档,不直接实现报表业务规则。 - * 这里的命令都是纯函数:接收文档 + payload,返回新文档(整体替换), - * 由 EditSession 负责历史记录与撤销。 - */ -import type { ReportDocument, ReportElement, Rect } from "@report/core" -import { cloneDocument, createCommand, createElementId } from "@report/core" -import type { Command } from "@report/core" - -/** 移动/缩放元素的 payload。 */ -export interface MoveElementPayload { - /** 元素 ID → 新 frame(绝对坐标,mm)。 */ - frames: Record -} - -/** 修改元素属性的 payload。 */ -export interface UpdateElementPayload { - elementId: string - /** 属性名,如 "name"、"locked"、"hidden"、"props.text"。 */ - path: string - value: unknown -} - -/** 新增元素的 payload。 */ -export interface AddElementPayload { - /** 目标区域 ID。 */ - sectionId: string - /** 新增元素(含 id)。 */ - element: ReportElement - /** 插入位置索引,省略则追加到末尾。 */ - index?: number -} - -/** 删除元素的 payload。 */ -export interface DeleteElementsPayload { - /** 要删除的元素 ID 集合。 */ - elementIds: ReadonlySet | string[] -} - -/** - * 移动元素(可合并:拖拽时连续调用会合并为一步撤销)。 - * - * payload.frames 给出目标 frame,命令把文档中对应元素替换为新 frame。 - */ -export const moveElementsCommand: Command = createCommand( - "designer.move-elements", - (document, payload) => { - const next = cloneDocument(document) - const targets = new Map(Object.entries(payload.frames)) - let moved = 0 - for (const section of next.sections) { - moved += applyFrames(section.children, targets) - } - if (moved === 0) return next - return next - }, - { mergeKey: "move-elements" }, -) - -function applyFrames( - elements: ReportElement[], - targets: Map, -): number { - let count = 0 - for (const element of elements) { - const target = targets.get(element.id) - if (target) { - element.frame = { ...target } - count += 1 - } - if (element.children?.length) count += applyFrames(element.children, targets) - const columns = (element as { columns?: { children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - if (column.children?.length) count += applyFrames(column.children, targets) - } - } - } - return count -} - -/** - * 修改元素属性。 - * - * path 支持点号分隔的嵌套路径,如 "props.text"、"frame.width"。 - * 用简单解析避免引入深层路径库。 - */ -export const updateElementCommand: Command = createCommand( - "designer.update-element", - (document, payload) => { - const next = cloneDocument(document) - const found = findAndUpdate(next, payload.elementId, payload.path, payload.value) - if (!found) { - return { document: null, diagnostics: [{ severity: "warning", code: "designer.element-missing", message: `未找到元素 "${payload.elementId}"` }] } - } - return next - }, -) - -function findAndUpdate( - document: ReportDocument, - elementId: string, - path: string, - value: unknown, -): boolean { - const walk = (elements: ReportElement[]): boolean => { - for (const element of elements) { - if (element.id === elementId) { - setByPath(element, path, value) - return true - } - if (element.children?.length && walk(element.children)) return true - const columns = (element as { columns?: { children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - if (column.children?.length && walk(column.children)) return true - } - } - } - return false - } - for (const section of document.sections) { - if (walk(section.children)) return true - } - return false -} - -function setByPath(target: object, path: string, value: unknown): void { - const parts = path.split(".") - let current: Record = target as Record - for (let i = 0; i < parts.length - 1; i += 1) { - const key = parts[i]! - const existing = current[key] - if (existing === null || typeof existing !== "object" || Array.isArray(existing)) { - current[key] = {} - } - current = current[key] as Record - } - current[parts[parts.length - 1]!] = value -} - -/** - * 新增元素到指定区域。 - */ -export const addElementCommand: Command = createCommand( - "designer.add-element", - (document, payload) => { - const next = cloneDocument(document) - const section = next.sections.find((s) => s.id === payload.sectionId) - if (!section) { - return { document: null, diagnostics: [{ severity: "warning", code: "designer.section-missing", message: `未找到区域 "${payload.sectionId}"` }] } - } - const element = cloneElement(payload.element) - if (payload.index !== undefined && payload.index >= 0 && payload.index <= section.children.length) { - section.children.splice(payload.index, 0, element) - } else { - section.children.push(element) - } - return next - }, -) - -function cloneElement(element: ReportElement): ReportElement { - return JSON.parse(JSON.stringify(element)) as ReportElement -} - -/** - * 删除元素集合。 - */ -export const deleteElementsCommand: Command = createCommand( - "designer.delete-elements", - (document, payload) => { - const next = cloneDocument(document) - const ids = new Set(payload.elementIds) - let removed = 0 - for (const section of next.sections) { - removed += removeElements(section.children, ids) - } - return next - }, -) - -function removeElements(elements: ReportElement[], ids: Set): number { - let removed = 0 - for (let i = elements.length - 1; i >= 0; i -= 1) { - const element = elements[i]! - if (ids.has(element.id)) { - elements.splice(i, 1) - removed += 1 - continue - } - if (element.children?.length) removed += removeElements(element.children, ids) - const columns = (element as { columns?: { children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - if (column.children?.length) removed += removeElements(column.children, ids) - } - } - } - return removed -} - -/** 创建一个新的文本元素(含自动生成的 ID)。 */ -export function createTextElement(frame: Rect, text = "文本"): ReportElement { - return { id: createElementId(), type: "text", frame, props: { text } } -} - -/** 创建一个新的矩形元素。 */ -export function createRectElement(frame: Rect): ReportElement { - return { id: createElementId(), type: "rect", frame } -} diff --git a/code/one-designer/packages/report-designer/src/coords.ts b/code/one-designer/packages/report-designer/src/coords.ts deleted file mode 100644 index 19a8dd19..00000000 --- a/code/one-designer/packages/report-designer/src/coords.ts +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 坐标转换(对应设计文档 §4.5「画布和坐标转换」、§7)。 - * - * 文档内部统一使用 mm;Designer 显示层使用 px。 - * 转换链路:屏幕 px →(除以 zoom、减 pan)→ 画布 px →(mmToPx)→ mm。 - * - * 注意:这里的"画布 px"指缩放后用于显示的像素,与文档 mm 的换算 - * 走 1in = 96px(§7)。 - */ -import { mmToPx, pxToMm } from "@report/layout" -import type { DesignerState } from "./state.js" - -/** 屏幕坐标(浏览器事件坐标)。 */ -export interface ScreenPoint { - x: number - y: number -} - -/** 文档坐标(mm)。 */ -export interface DocPoint { - x: number - y: number -} - -/** - * 屏幕坐标 → 文档坐标(mm)。 - * - * @param point 屏幕/事件坐标(px) - * @param state 编辑器状态(含 zoom 与 pan) - */ -export function screenToDoc(point: ScreenPoint, state: DesignerState): DocPoint { - // 先减去平移,再除以缩放,得到画布 px - const canvasX = (point.x - state.panX) / state.zoom - const canvasY = (point.y - state.panY) / state.zoom - return { - x: pxToMm(canvasX), - y: pxToMm(canvasY), - } -} - -/** - * 文档坐标(mm)→ 屏幕坐标(px)。 - */ -export function docToScreen(point: DocPoint, state: DesignerState): ScreenPoint { - const canvasX = mmToPx(point.x) - const canvasY = mmToPx(point.y) - return { - x: canvasX * state.zoom + state.panX, - y: canvasY * state.zoom + state.panY, - } -} - -/** - * 判断屏幕点是否落在某元素的 frame 内(命中测试)。 - * - * frame 是文档 mm 坐标,point 是屏幕坐标,因此需要换算后比较。 - */ -export function hitTest( - point: ScreenPoint, - frame: { x: number; y: number; width: number; height: number }, - state: DesignerState, -): boolean { - const doc = screenToDoc(point, state) - return ( - doc.x >= frame.x && - doc.x <= frame.x + frame.width && - doc.y >= frame.y && - doc.y <= frame.y + frame.height - ) -} - -/** - * 吸附:把文档坐标吸附到最近的辅助线。 - * - * V1 只做"吸附到整数 mm"的简化实现,完整辅助线吸附放到后续。 - * 返回吸附后的坐标。 - */ -export function snapToGrid(value: number, state: DesignerState): number { - if (!state.snapEnabled) return value - // 吸附到 1mm 整数 - return Math.round(value) -} - -/** 限制缩放范围。 */ -export function clampZoom(zoom: number): number { - return Math.min(2, Math.max(0.5, zoom)) -} diff --git a/code/one-designer/packages/report-designer/src/editor.ts b/code/one-designer/packages/report-designer/src/editor.ts deleted file mode 100644 index 0449a2fc..00000000 --- a/code/one-designer/packages/report-designer/src/editor.ts +++ /dev/null @@ -1,281 +0,0 @@ -/** - * 编辑器会话(对应设计文档 §4.5)。 - * - * 组合 Core 的 EditSession(命令 + 历史)与 DesignerState(编辑器状态), - * 提供 Designer 直接可用的高层 API: - * 选择、移动、缩放、增删元素、复制粘贴、撤销重做、缩放视图。 - * - * 所有文档修改都通过命令走 EditSession,保证可撤销; - * 所有编辑器状态(选中、缩放、平移)都留在本对象内,不进文档(§3.2)。 - */ -import type { ReportDocument, ReportElement, Rect } from "@report/core" -import { createEditSession, cloneDocument, createElementId } from "@report/core" -import type { EditSession } from "@report/core" -import type { DesignerState, DragState } from "./state.js" -import { - createDesignerState, - setSelection, - clearSelection, - toggleSelection, - findElement, -} from "./state.js" -import { - moveElementsCommand, - updateElementCommand, - addElementCommand, - deleteElementsCommand, -} from "./commands.js" -import { clampZoom, snapToGrid } from "./coords.js" - -/** 编辑器会话配置。 */ -export interface EditorOptions { - /** 初始缩放。默认 1。 */ - zoom?: number -} - -/** - * 编辑器会话。 - * - * 典型用法: - * ```ts - * const editor = new EditorSession(createDocument()) - * editor.select("el-1") - * editor.moveElements({ "el-1": { x: 10, y: 10, width: 50, height: 20 } }) - * editor.undo() - * ``` - */ -export class EditorSession { - private readonly session: EditSession - private state: DesignerState - - constructor(document: ReportDocument, options: EditorOptions = {}) { - this.session = createEditSession(document) - this.state = createDesignerState({ zoom: options.zoom ?? 1 }) - } - - // ------------------------------------------------------------------------- - // 文档访问 - // ------------------------------------------------------------------------- - - /** 当前文档(只读视图)。 */ - getDocument(): ReportDocument { - return this.session.getDocument() - } - - /** 当前编辑器状态。 */ - getState(): DesignerState { - return this.state - } - - // ------------------------------------------------------------------------- - // 选择 - // ------------------------------------------------------------------------- - - /** 选中单个元素。 */ - select(elementId: string): void { - this.state = setSelection(this.state, [elementId]) - } - - /** 多选。 */ - selectMany(elementIds: string[]): void { - this.state = setSelection(this.state, elementIds) - } - - /** - * 切换单个元素的选中态(Ctrl/Cmd + 点击的语义)。 - * - * 与 select 的区别:已选中的会被取消选中,未选中的会被加入。 - */ - toggleSelect(elementId: string): void { - this.state = toggleSelection(this.state, elementId) - } - - /** 清空选中。 */ - clearSelection(): void { - this.state = clearSelection(this.state) - } - - /** 当前选中的元素 ID 列表。 */ - getSelectedIds(): string[] { - return [...this.state.selectedIds] - } - - // ------------------------------------------------------------------------- - // 编辑操作(都通过命令,可撤销) - // ------------------------------------------------------------------------- - - /** 移动/缩放元素(frame 为绝对 mm 坐标)。 */ - moveElements(frames: Record): void { - this.session.execute(moveElementsCommand, { frames }, { label: "移动元素" }) - } - - /** 修改元素属性。 */ - updateElement(elementId: string, path: string, value: unknown): void { - this.session.execute(updateElementCommand, { elementId, path, value }, { label: "修改属性" }) - } - - /** 新增元素。 */ - addElement(sectionId: string, element: ReportElement, index?: number): void { - this.session.execute(addElementCommand, { sectionId, element, index }, { label: "新增元素" }) - } - - /** 删除当前选中的元素。 */ - deleteSelected(): void { - const ids = [...this.state.selectedIds] - if (ids.length === 0) return - this.session.execute(deleteElementsCommand, { elementIds: ids }, { label: "删除元素" }) - this.state = clearSelection(this.state) - } - - /** - * 复制选中的元素到剪贴板(内存中),并粘贴为新元素。 - * - * 剪贴板属于编辑器状态,不进文档。 - */ - private clipboard: ReportElement[] = [] - - /** 复制当前选中元素。 */ - copy(): void { - const doc = this.getDocument() - const selected = [...this.state.selectedIds] - const elements: ReportElement[] = [] - for (const id of selected) { - const found = findElement(doc, id) - if (found) elements.push(found.element) - } - this.clipboard = elements.map((e) => JSON.parse(JSON.stringify(e)) as ReportElement) - } - - /** 粘贴剪贴板中的元素到指定区域(新 ID,偏移 5mm 避免重叠)。 */ - paste(sectionId: string): void { - if (this.clipboard.length === 0) return - const pastedIds: string[] = [] - for (const source of this.clipboard) { - const element = JSON.parse(JSON.stringify(source)) as ReportElement - element.id = createElementId() - element.frame = { - ...element.frame, - x: element.frame.x + 5, - y: element.frame.y + 5, - } - this.addElement(sectionId, element) - pastedIds.push(element.id) - } - // 粘贴后选中新元素,方便紧接着继续拖拽/微调。 - this.state = setSelection(this.state, pastedIds) - } - - // ------------------------------------------------------------------------- - // 撤销 / 重做 - // ------------------------------------------------------------------------- - - /** 撤销。 */ - undo(): boolean { - return this.session.undo() - } - - /** 重做。 */ - redo(): boolean { - return this.session.redo() - } - - canUndo(): boolean { - return this.session.history.canUndo - } - - canRedo(): boolean { - return this.session.history.canRedo - } - - // ------------------------------------------------------------------------- - // 视图(缩放、平移) - // ------------------------------------------------------------------------- - - /** 设置缩放。 */ - setZoom(zoom: number): void { - this.state = { ...this.state, zoom: clampZoom(zoom) } - } - - /** 缩放一档。 */ - zoomIn(): void { - this.setZoom(this.state.zoom * 1.25) - } - - zoomOut(): void { - this.setZoom(this.state.zoom / 1.25) - } - - /** 平移画布。 */ - pan(dx: number, dy: number): void { - this.state = { ...this.state, panX: this.state.panX + dx, panY: this.state.panY + dy } - } - - // ------------------------------------------------------------------------- - // 拖拽 - // ------------------------------------------------------------------------- - - /** 开始拖拽移动:记录选中元素的原始 frame,并开启拖拽事务。 */ - beginDrag(startX: number, startY: number): void { - const doc = this.getDocument() - const originalFrames: Record = {} - for (const id of this.state.selectedIds) { - const found = findElement(doc, id) - if (found) { - originalFrames[id] = { ...found.element.frame } - } - } - this.state = { - ...this.state, - drag: { kind: "move", startX, startY, originalFrames }, - } - // 开启跨事件事务,endDrag 时整体提交。 - // 不用命令自带的 mergeKey 时间窗合并:拖拽中途停顿超过合并窗口 - // 就会把一次拖拽拆成多条撤销记录,撤销时只能回退半截。 - this.session.beginTransaction("移动元素") - } - - /** - * 拖拽更新:根据位移量移动选中元素。 - * - * dx / dy 为**文档坐标(mm)**位移量,由调用方把屏幕像素除以缩放后换算得到。 - * - * 吸附作用在「结果坐标」而非「位移量」上:若吸附位移量,元素会落在 - * 非整数 mm 上;吸附结果坐标才能保证元素真正对齐到 mm 网格。 - * - * 这里走 applyWithinTransaction:只更新文档作为实时预览,不单独记历史, - * 由 endDrag 的事务提交统一落成一步撤销。 - */ - updateDrag(dx: number, dy: number): void { - const drag = this.state.drag - if (!drag) return - const frames: Record = {} - for (const [id, original] of Object.entries(drag.originalFrames)) { - frames[id] = { - x: snapToGrid(original.x + dx, this.state), - y: snapToGrid(original.y + dy, this.state), - width: original.width, - height: original.height, - } - } - this.session.applyWithinTransaction(moveElementsCommand, { frames }) - } - - /** 结束拖拽:提交事务,整个拖拽过程合成一步撤销。 */ - endDrag(): void { - if (this.state.drag === null) return - this.state = { ...this.state, drag: null } - this.session.commitTransaction() - } - - /** 是否正在拖拽。 */ - isDragging(): boolean { - return this.state.drag !== null - } -} - -/** 创建编辑器会话。 */ -export function createEditorSession( - document: ReportDocument, - options: EditorOptions = {}): EditorSession { - return new EditorSession(document, options) -} diff --git a/code/one-designer/packages/report-designer/src/index.ts b/code/one-designer/packages/report-designer/src/index.ts deleted file mode 100644 index f635a203..00000000 --- a/code/one-designer/packages/report-designer/src/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @report/designer 公共入口(对应设计文档 §4.5)。 - * - * 报表编辑器的状态、命令、坐标转换与交互逻辑(无 UI)。 - * Vue 组件层见 @report/designer-vue。 - * - * 关键边界(§3.2、§4.5): - * - 所有编辑器状态(选中、缩放、平移、拖拽、剪贴板)都留在此包, - * 绝不写入 ReportDocument。 - * - 所有文档修改通过 Core 的命令接口,保证可撤销。 - */ -export type { DesignerState, DragState } from "./state.js" -export { - createDesignerState, - toggleSelection, - setSelection, - clearSelection, - isSelected, - collectAllElementIds, - findElement, - sectionElements, -} from "./state.js" - -export type { ScreenPoint, DocPoint } from "./coords.js" -export { screenToDoc, docToScreen, hitTest, snapToGrid, clampZoom } from "./coords.js" - -export type { - MoveElementPayload, - UpdateElementPayload, - AddElementPayload, - DeleteElementsPayload, -} from "./commands.js" -export { - moveElementsCommand, - updateElementCommand, - addElementCommand, - deleteElementsCommand, - createTextElement, - createRectElement, -} from "./commands.js" - -export type { EditorOptions } from "./editor.js" -export { EditorSession, createEditorSession } from "./editor.js" diff --git a/code/one-designer/packages/report-designer/src/state.ts b/code/one-designer/packages/report-designer/src/state.ts deleted file mode 100644 index bdc8339c..00000000 --- a/code/one-designer/packages/report-designer/src/state.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** - * 编辑器状态模型(对应设计文档 §4.5、§3.2)。 - * - * 关键边界:以下所有状态都属于「编辑器状态」,明确禁止写入 - * ReportDocument(§3.2)。Designer 持有它们,Core 不感知。 - * - * - 当前选中项(selectedIds) - * - 缩放比例(zoom) - * - 画布滚动/平移(panX / panY) - * - 辅助线、吸附设置 - * - 悬停元素、拖拽进行中状态 - */ -import type { ReportElement, ReportSection } from "@report/core" - -/** 编辑器状态。 */ -export interface DesignerState { - /** 当前选中元素 ID 集合(支持多选)。 */ - selectedIds: ReadonlySet - /** 缩放比例,1 表示 100%。 */ - zoom: number - /** 画布水平平移(px,显示层坐标)。 */ - panX: number - /** 画布垂直平移(px,显示层坐标)。 */ - panY: number - /** 是否启用吸附。 */ - snapEnabled: boolean - /** 吸附阈值(px)。 */ - snapThreshold: number - /** 当前悬停元素 ID(用于高亮)。 */ - hoveredId: string | null - /** 拖拽进行中的临时状态。 */ - drag: DragState | null -} - -/** 拖拽进行中的状态。 */ -export interface DragState { - /** 拖拽类型。 */ - kind: "move" | "resize" - /** 起始指针位置(画布坐标 mm)。 */ - startX: number - startY: number - /** 拖拽起始时各元素的原始 frame(key 为元素 ID)。 */ - originalFrames: Record -} - -/** 创建默认编辑器状态。 */ -export function createDesignerState(partial: Partial = {}): DesignerState { - return { - selectedIds: new Set(), - zoom: 1, - panX: 0, - panY: 0, - snapEnabled: true, - snapThreshold: 5, - hoveredId: null, - drag: null, - ...partial, - } -} - -/** 选中/取消选中一个元素(返回新的 Set,保持不可变)。 */ -export function toggleSelection( - state: DesignerState, - elementId: string, -): DesignerState { - const next = new Set(state.selectedIds) - if (next.has(elementId)) next.delete(elementId) - else next.add(elementId) - return { ...state, selectedIds: next } -} - -/** 设置选中集合(单选或多选)。 */ -export function setSelection( - state: DesignerState, - ids: ReadonlySet | string[], -): DesignerState { - const next = new Set(ids) - return { ...state, selectedIds: next } -} - -/** 清空选中。 */ -export function clearSelection(state: DesignerState): DesignerState { - return { ...state, selectedIds: new Set() } -} - -/** 判断某元素是否被选中。 */ -export function isSelected(state: DesignerState, elementId: string): boolean { - return state.selectedIds.has(elementId) -} - -/** - * 收集文档中所有元素的 ID(含嵌套、表格列内元素)。 - * - * Designer 需要遍历元素树来做命中测试与图层面板。 - */ -export function collectAllElementIds(document: import("@report/core").ReportDocument): string[] { - const ids: string[] = [] - const walk = (elements: readonly ReportElement[]): void => { - for (const element of elements) { - ids.push(element.id) - if (element.children?.length) walk(element.children) - const columns = (element as { columns?: { children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - if (column.children?.length) walk(column.children) - } - } - } - } - for (const section of document.sections) walk(section.children) - return ids -} - -/** - * 在文档中查找元素(含嵌套),返回元素与它所属的父数组, - * 便于 Designer 做删除/替换操作。 - */ -export function findElement( - document: import("@report/core").ReportDocument, - elementId: string, -): { element: ReportElement; parent: ReportElement[] } | null { - const walk = (elements: ReportElement[]): { element: ReportElement; parent: ReportElement[] } | null => { - for (let i = 0; i < elements.length; i += 1) { - const element = elements[i]! - if (element.id === elementId) { - return { element, parent: elements } - } - if (element.children?.length) { - const found = walk(element.children) - if (found) return found - } - const columns = (element as { columns?: { children?: ReportElement[] }[] }).columns - if (Array.isArray(columns)) { - for (const column of columns) { - if (column.children?.length) { - const found = walk(column.children) - if (found) return found - } - } - } - } - return null - } - - for (const section of document.sections) { - const found = walk(section.children) - if (found) return found - } - return null -} - -/** 获取区域内的顶层元素。 */ -export function sectionElements(section: ReportSection): ReportElement[] { - return section.children -} diff --git a/code/one-designer/packages/report-designer/tests/designer.test.ts b/code/one-designer/packages/report-designer/tests/designer.test.ts deleted file mode 100644 index 2c4a12e1..00000000 --- a/code/one-designer/packages/report-designer/tests/designer.test.ts +++ /dev/null @@ -1,356 +0,0 @@ -/** - * Designer 编辑器测试(对应设计文档 §4.5)。 - * - * 核心断言: - * - 编辑器状态(选中、缩放、平移)独立于文档(§3.2)。 - * - 所有编辑操作通过命令,可撤销可重做。 - * - 坐标转换在屏幕 px 与文档 mm 之间正确换算。 - */ -import { describe, expect, it, vi } from "vitest" -import { createDocument, createElementId, type ReportDocument } from "@report/core" -import { EditorSession, createEditorSession } from "../src/editor.js" -import { screenToDoc, docToScreen, hitTest, clampZoom, snapToGrid } from "../src/coords.js" -import { createDesignerState } from "../src/state.js" -import { createTextElement, createRectElement } from "../src/commands.js" - -function sampleDoc(): ReportDocument { - const doc = createDocument({ name: "编辑器测试" }) - const detail = doc.sections.find((s) => s.kind === "detail")! - detail.children.push( - createTextElement({ x: 0, y: 0, width: 50, height: 8 }, "标题"), - createRectElement({ x: 0, y: 10, width: 50, height: 20 }), - ) - return doc -} - -describe("编辑器状态独立于文档", () => { - it("选中状态不写入文档", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = doc.sections.find((s) => s.kind === "detail")! - const firstId = detail.children[0]!.id - - editor.select(firstId) - // 文档序列化后不应包含任何选中状态 - const serialized = JSON.stringify(editor.getDocument()) - expect(serialized).not.toContain("selectedIds") - expect(editor.getSelectedIds()).toEqual([firstId]) - }) - - it("缩放与平移不写入文档", () => { - const editor = new EditorSession(sampleDoc()) - editor.setZoom(1.5) - editor.pan(10, 20) - const state = editor.getState() - expect(state.zoom).toBe(1.5) - expect(state.panX).toBe(10) - expect(state.panY).toBe(20) - // 文档本身不含这些字段 - expect(JSON.stringify(editor.getDocument())).not.toContain("zoom") - }) -}) - -describe("选择", () => { - it("选择单个元素", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = doc.sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - editor.select(id) - expect(editor.getSelectedIds()).toEqual([id]) - }) - - it("多选与清空", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = doc.sections.find((s) => s.kind === "detail")! - const ids = detail.children.map((c) => c.id) - editor.selectMany(ids) - expect(editor.getSelectedIds().length).toBe(2) - editor.clearSelection() - expect(editor.getSelectedIds()).toHaveLength(0) - }) -}) - -describe("编辑命令与撤销重做", () => { - it("移动元素可撤销", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = doc.sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - const before = { ...detail.children[0]!.frame } - - editor.select(id) - editor.moveElements({ [id]: { x: 100, y: 100, width: 50, height: 8 } }) - - const afterMove = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]!.frame - expect(afterMove.x).toBe(100) - - editor.undo() - const afterUndo = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]!.frame - expect(afterUndo.x).toBe(before.x) - - editor.redo() - const afterRedo = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]!.frame - expect(afterRedo.x).toBe(100) - }) - - it("新增元素可撤销", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const beforeCount = detail.children.length - - const newEl = createTextElement({ x: 0, y: 0, width: 30, height: 8 }, "新元素") - editor.addElement(detail.id, newEl) - - const afterAdd = editor.getDocument().sections.find((s) => s.kind === "detail")!.children.length - expect(afterAdd).toBe(beforeCount + 1) - - editor.undo() - const afterUndo = editor.getDocument().sections.find((s) => s.kind === "detail")!.children.length - expect(afterUndo).toBe(beforeCount) - }) - - it("删除选中元素", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const beforeCount = detail.children.length - const id = detail.children[0]!.id - - editor.select(id) - editor.deleteSelected() - - const afterDelete = editor.getDocument().sections.find((s) => s.kind === "detail")!.children.length - expect(afterDelete).toBe(beforeCount - 1) - expect(editor.getSelectedIds()).toHaveLength(0) - }) - - it("修改元素属性", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - - editor.updateElement(id, "props.text", "改后的标题") - const after = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]! - expect((after.props as { text: string }).text).toBe("改后的标题") - }) -}) - -describe("坐标转换", () => { - it("屏幕 px 与文档 mm 换算(zoom=1, pan=0)", () => { - const state = createDesignerState() - const doc = screenToDoc({ x: 96, y: 96 }, state) - // 96px = 1in = 25.4mm - expect(doc.x).toBeCloseTo(25.4, 2) - expect(doc.y).toBeCloseTo(25.4, 2) - - const screen = docToScreen({ x: 25.4, y: 25.4 }, state) - expect(screen.x).toBeCloseTo(96, 2) - expect(screen.y).toBeCloseTo(96, 2) - }) - - it("缩放影响换算", () => { - const state = createDesignerState({ zoom: 2 }) - const doc = screenToDoc({ x: 96, y: 0 }, state) - // 96px / 2 = 48px = 12.7mm - expect(doc.x).toBeCloseTo(12.7, 2) - }) - - it("命中测试", () => { - const state = createDesignerState() - const frame = { x: 0, y: 0, width: 25.4, height: 25.4 } - // 中心点 (48,48)px = 12.7mm 在 frame 内 - expect(hitTest({ x: 48, y: 48 }, frame, state)).toBe(true) - // 外部点不在 - expect(hitTest({ x: 200, y: 200 }, frame, state)).toBe(false) - }) - - it("缩放钳制在 [0.5, 2]", () => { - expect(clampZoom(0.1)).toBe(0.5) - expect(clampZoom(5)).toBe(2) - expect(clampZoom(1)).toBe(1) - }) -}) - -describe("拖拽", () => { - it("拖拽移动选中元素", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - const before = { ...detail.children[0]!.frame } - - editor.select(id) - editor.beginDrag(0, 0) - editor.updateDrag(10, 20) - editor.endDrag() - - const after = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]!.frame - expect(after.x).toBe(before.x + 10) - expect(after.y).toBe(before.y + 20) - expect(editor.isDragging()).toBe(false) - }) - - it("吸附作用在结果坐标上,拖动落点为整数 mm", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - - editor.select(id) - editor.beginDrag(0, 0) - editor.updateDrag(10.4, 20.6) - editor.endDrag() - - const after = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]!.frame - // 起点 x=0 y=0,位移取整后应为 10 / 21 - expect(after.x).toBe(10) - expect(after.y).toBe(21) - }) - - it("吸附取整的是落点而非位移量", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const id = detail.children[1]!.id - - // 关键:起点必须是非整数,否则「取整落点」与「取整位移量」结果相同, - // 这个用例就区分不出两种实现。 - editor.moveElements({ [id]: { x: 5.4, y: 10.4, width: 50, height: 20 } }) - - editor.select(id) - editor.beginDrag(0, 0) - editor.updateDrag(0.3, 0.3) - editor.endDrag() - - const after = editor.getDocument().sections.find((s) => s.kind === "detail")!.children[1]!.frame - // 落点 5.7 → 6、10.7 → 11。 - // 若改成对位移量取整,结果会是 5.4 和 10.4(位移 0.3 取整为 0),与期望不符。 - expect(after.x).toBe(6) - expect(after.y).toBe(11) - }) -}) - -describe("拖拽的事务语义", () => { - it("拖拽中途停顿超过时间窗,仍然只产生一步撤销", () => { - vi.useFakeTimers() - vi.setSystemTime(new Date("2026-01-01T00:00:00Z")) - try { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - const frame = () => - editor.getDocument().sections.find((s) => s.kind === "detail")!.children[0]!.frame - - editor.select(id) - editor.beginDrag(0, 0) - editor.updateDrag(10, 10) - - // 模拟用户拖到一半停手,闲置远超 History 的 500ms 合并窗口后继续拖。 - // 若靠 mergeKey 时间窗合并,这里会被拆成两条撤销记录。 - vi.setSystemTime(new Date("2026-01-01T00:00:10Z")) - editor.updateDrag(30, 30) - editor.endDrag() - - expect(frame().x).toBe(30) - - // 关键:一次撤销直接回到原位,而不是停在中间态 10 - editor.undo() - expect(frame().x).toBe(0) - } finally { - vi.useRealTimers() - } - }) - - it("拖拽没有产生位移时不写入撤销记录", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const id = detail.children[0]!.id - - editor.select(id) - editor.beginDrag(0, 0) - editor.endDrag() - - expect(editor.canUndo()).toBe(false) - }) -}) - -describe("吸附开关(snapToGrid)", () => { - it("开启时取整到整数 mm", () => { - const state = createDesignerState({ snapEnabled: true }) - expect(snapToGrid(10.4, state)).toBe(10) - expect(snapToGrid(10.6, state)).toBe(11) - }) - - it("关闭时原样返回", () => { - const state = createDesignerState({ snapEnabled: false }) - expect(snapToGrid(10.4, state)).toBe(10.4) - expect(snapToGrid(-3.7, state)).toBe(-3.7) - }) -}) - -describe("多选切换与剪贴板", () => { - it("toggleSelect 在选中与取消之间切换", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const first = detail.children[0]!.id - const second = detail.children[1]!.id - - editor.toggleSelect(first) - expect(editor.getSelectedIds()).toEqual([first]) - - // 再切一次同一个 → 取消选中 - editor.toggleSelect(first) - expect(editor.getSelectedIds()).toHaveLength(0) - - // 两个都切上 → 多选 - editor.toggleSelect(first) - editor.toggleSelect(second) - expect(editor.getSelectedIds().sort()).toEqual([first, second].sort()) - }) - - it("粘贴后选中新元素,而不是清空选中", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const sourceId = detail.children[0]!.id - const beforeCount = detail.children.length - - editor.select(sourceId) - editor.copy() - editor.paste(detail.id) - - const afterChildren = editor.getDocument().sections.find((s) => s.kind === "detail")!.children - expect(afterChildren.length).toBe(beforeCount + 1) - - // 回归:旧实现这里会把选中清空 - const selectedIds = editor.getSelectedIds() - expect(selectedIds).toHaveLength(1) - expect(selectedIds[0]).not.toBe(sourceId) - // 选中的确实是刚粘贴出来的那个 - expect(afterChildren.some((c) => c.id === selectedIds[0])).toBe(true) - }) - - it("粘贴的元素相对源元素偏移 5mm 避免重叠", () => { - const doc = sampleDoc() - const editor = new EditorSession(doc) - const detail = editor.getDocument().sections.find((s) => s.kind === "detail")! - const source = detail.children[0]! - - editor.select(source.id) - editor.copy() - editor.paste(detail.id) - - const pasted = editor.getDocument().sections - .find((s) => s.kind === "detail")! - .children.find((c) => c.id === editor.getSelectedIds()[0])! - expect(pasted.frame.x).toBe(source.frame.x + 5) - expect(pasted.frame.y).toBe(source.frame.y + 5) - }) -}) diff --git a/code/one-designer/packages/report-designer/tests/smoke.test.ts b/code/one-designer/packages/report-designer/tests/smoke.test.ts deleted file mode 100644 index b341d0ff..00000000 --- a/code/one-designer/packages/report-designer/tests/smoke.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 端到端链路冒烟测试(§17 V1 验收标准)。 - * - * 验证完整链路: - * ReportDocument(core) - * → 数据注入 + 布局(layout,含分组/聚合) - * → LayoutDocument - * → HTML/SVG Renderer(renderer) - * → Designer 编辑(designer) - */ -import { describe, expect, it } from "vitest" -import { createDocument, createTableElement } from "@report/core" -import { createEstimateMeasurer, createPassthroughFontResolver, layoutDocument } from "@report/layout" -import { renderHtml, renderSvg, createPdfRenderer } from "@report/renderer" -import { EditorSession, createTextElement } from "@report/designer" - -const measurer = createEstimateMeasurer() -const fontResolver = createPassthroughFontResolver() - -describe("端到端冒烟(§17)", () => { - it("完整链路:建文档 → 布局 → HTML/SVG → Designer 编辑", async () => { - // 1. Core:创建文档 + 明细表 - const doc = createDocument({ name: "销售单" }) - doc.datasets = { sales: { id: "sales" } } - const detail = doc.sections.find((s) => s.kind === "detail")! - detail.children.push( - createTableElement("tbl", { x: 0, y: 0, width: 180, height: 20 }, "sales", [ - { id: "c1", width: 90, header: "商品", binding: { field: "name" } }, - { id: "c2", width: 90, header: "金额", binding: { field: "amount" }, align: "right" }, - ]), - ) - const header = doc.sections.find((s) => s.kind === "page-header")! - header.children.push({ - id: "title", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - props: { text: "销售单" }, - }) - - const rows = [ - { name: "苹果", amount: 100 }, - { name: "香蕉", amount: 200 }, - { name: "橙子", amount: 300 }, - ] - - // 2. Layout:数据注入 + 布局 - const layout = await layoutDocument( - doc, - { data: { sales: rows }, parameters: { } }, - { textMeasurer: measurer, fontResolver }, - ) - expect(layout.pageCount).toBeGreaterThanOrEqual(1) - expect(layout.diagnostics.filter((d) => d.severity === "error")).toHaveLength(0) - - // 3. Renderer:HTML + SVG 渲染,页数一致 - const html = renderHtml(layout) - const svg = renderSvg(layout) - expect(html.pageCount).toBe(layout.pageCount) - expect(svg.pageCount).toBe(layout.pageCount) - expect(html.content).toContain("销售单") - expect(html.content).toContain("苹果") - expect(svg.content).toContain("苹果") - - // PDF 缺后端 → 诊断而非抛异常 - const pdf = createPdfRenderer().render(layout) - expect(pdf.target).toBe("pdf") - expect(pdf.diagnostics.length).toBeGreaterThan(0) - - // 4. Designer:编辑(移动 + 撤销) - const editor = new EditorSession(doc) - editor.select("title") - const before = editor.getDocument().sections - .find((s) => s.kind === "page-header")!.children[0]!.frame - editor.moveElements({ title: { x: 20, y: 0, width: 100, height: 8 } }) - const afterMove = editor.getDocument().sections - .find((s) => s.kind === "page-header")!.children[0]!.frame - expect(afterMove.x).toBe(20) - editor.undo() - const afterUndo = editor.getDocument().sections - .find((s) => s.kind === "page-header")!.children[0]!.frame - expect(afterUndo.x).toBe(before.x) - - // 新增元素 - const beforeCount = editor.getDocument().sections - .find((s) => s.kind === "detail")!.children.length - editor.addElement(detail.id, createTextElement({ x: 0, y: 0, width: 30, height: 8 }, "备注")) - const afterAdd = editor.getDocument().sections - .find((s) => s.kind === "detail")!.children.length - expect(afterAdd).toBe(beforeCount + 1) - }) -}) diff --git a/code/one-designer/packages/report-designer/tsconfig.json b/code/one-designer/packages/report-designer/tsconfig.json deleted file mode 100644 index 23cc1372..00000000 --- a/code/one-designer/packages/report-designer/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src", - "types": ["node"] - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist", "tests"] -} diff --git a/code/one-designer/packages/report-designer/tsconfig.test.json b/code/one-designer/packages/report-designer/tsconfig.test.json deleted file mode 100644 index 6cefc694..00000000 --- a/code/one-designer/packages/report-designer/tsconfig.test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "noEmit": true, - "types": ["node", "vitest/globals"] - }, - "include": ["src/**/*.ts", "tests/**/*.ts", "*.config.ts"] -} diff --git a/code/one-designer/packages/report-designer/tsup.config.ts b/code/one-designer/packages/report-designer/tsup.config.ts deleted file mode 100644 index be47bf93..00000000 --- a/code/one-designer/packages/report-designer/tsup.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "tsup" - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["esm", "cjs"], - dts: true, - sourcemap: true, - clean: true, - treeshake: true, - target: "es2022", -}) diff --git a/code/one-designer/packages/report-expression/README.md b/code/one-designer/packages/report-expression/README.md deleted file mode 100644 index c602289d..00000000 --- a/code/one-designer/packages/report-expression/README.md +++ /dev/null @@ -1,186 +0,0 @@ -# @report/expression - -受限表达式的词法、语法、AST 与求值器。**不执行任意 JavaScript。** - -> 对应设计文档 §4.2、§10。 - -## 定位 - -表达式系统使用**受限语法和 AST**,禁止通过 `eval` 或 `new Function` 执行任意 JavaScript(§4.2)。 - -本包只依赖 `@report/core` 的类型,不依赖 DOM、不依赖任何求值框架。 - -## 安装与使用 - -```ts -import { evaluateExpression, compile, evaluateCompiled, ExpressionCache } from "@report/expression" - -// 一次性求值 -const { value, diagnostics } = evaluateExpression("row.price * row.quantity", { - scope: { row: { price: 3, quantity: 4 } }, -}) -// value === 12 - -// 预编译(明细表每行求值一次时使用,避免重复解析) -const compiled = compile("if(row.amount > 0, '有', '无')") -evaluateCompiled(compiled, { scope: { row: { amount: 5 } } }) // "有" -``` - -## 安全边界 - -这是本包最重要的设计约束。安全通过**五层**保证: - -1. **AST 即全部** — 求值器只处理 `ast.ts` 中定义的 9 种节点,没有其它可执行形式。 -2. **作用域白名单** — 根标识符只认识 `row` / `params` / `group` / `page` / `index` / `rownumber` / `dataset`。 - `window`、`globalThis`、`process`、`document` 一律解析为 `undefined`。 -3. **原型链防护** — 属性访问拒绝 `__proto__`、`constructor`、`prototype`, - 因此 `row.constructor.constructor` 拿不到 `Function`。 -4. **函数白名单** — 解析期即拒绝未登记的函数调用,非法表达式在任何求值之前就失败。 -5. **异常兜底** — 求值过程中的任何异常都转成诊断,不向上抛(§13)。 - -```ts -parse("eval('1+1')") // null,报"不允许调用函数" -parse("row.constructor") // 求值为 undefined -parse("row.__proto__") // 求值为 undefined -parse("`${row.amount}`") // null,模板字符串不受支持 -parse("(x) => x") // null,箭头函数不受支持 -parse("row.amount = 1") // null,赋值不受支持 -parse("row.name.toUpperCase()") // null,成员方法调用不受支持 -``` - -字符串与数组**不提供任何方法**,只能读 `length` 与下标。 - -## 语法 - -``` -conditional ?: -logical-or || -logical-and && -nullish ?? -equality == != === !== -relational > >= < <= -additive + - -multiplicative * / % -unary - + ! -postfix . [] () -primary 字面量 / 标识符 / ( expr ) -``` - -字段访问是表达式求值的核心用法: - -``` -row.amount 字段 -params.customerName 参数 -row.price * row.quantity 运算 -if(row.amount > 0, "有", "无") 条件 -format(row.date, "YYYY-MM-DD") 格式化 -``` - -## 内置函数 - -| 分类 | 函数 | -| --- | --- | -| 逻辑 | `if` `and` `or` `not` `isnull` `coalesce` | -| 字符串 | `concat` `len` `upper` `lower` `trim` `substr` `replace` | -| 数学 | `round` `floor` `ceil` `abs` `min` `max` | -| 转换 | `number` `string` `date` | -| 格式化 | `format` | - -`if` 是**惰性求值**:只求值命中的分支,未命中分支的错误不会影响结果。 - -`format` 同时支持日期与数字模式: - -```ts -format(row.date, "YYYY-MM-DD") // 2024-03-05 -format(1234567.891, "#,##0.00") // 1,234,567.89 -format(0.1234, "0.0%") // 12.3% -``` - -`replace` 只做**字面量替换**,不接受正则,避免 ReDoS 与转义歧义: - -```ts -replace("a.b.c", ".", "-") // "a-b-c" -replace("abc", ".", "X") // "abc"('.' 只匹配字面点) -``` - -`date` 返回 ISO **字符串**而非 `Date` 对象,保证表达式结果始终是可序列化的纯数据(§3.5)。 - -## 空值语义 - -报表场景下空单元格很常见,因此约定: - -- `null` / `undefined` 参与算术视为 **0**(避免整列求和变空)。 -- 与字符串相加按拼接处理,`null` 视为空串。 -- 除数为 0 返回 `null` 并产生诊断,**不产生 `Infinity`**。 -- 字段缺失返回 `undefined` 并产生 `data.dataset-missing` 诊断。 - -## 错误处理 - -单个字段错误不应导致整个文档无结果(§10)。所有 API 都返回结果对象而非抛异常: - -```ts -const { value, diagnostics } = evaluateExpression("1 +", { - scope, - elementId: "el-1", - path: "/sections/1/children/0/binding/expression", -}) -// value === null -// diagnostics[0].code === "expression.parse-error" -// diagnostics[0].elementId === "el-1" -``` - -## 值绑定 - -`binding.ts` 把文档模型里的 `ValueBinding { field, expression, format }` 解析成最终值。 -`field` 是 `expression` 的语法糖(`fieldToExpression("amount")` → `"row.amount"`), -两条路径行为完全一致。 - -```ts -import { resolveBinding, ExpressionCache } from "@report/expression" - -const cache = new ExpressionCache() -resolveBinding( - { field: "amount", format: "#,##0.00" }, - { scope: { row: { amount: 1234.5 } } }, - cache, -) -// { value: 1234.5, text: "1,234.50", diagnostics: [] } -``` - -## 目录结构 - -``` -src/ -├── tokenizer.ts 词法分析(最长匹配运算符、中文标识符) -├── ast.ts AST 节点定义与遍历工具 -├── parser.ts 递归下降解析器 + 优先级爬升 -├── scope.ts 求值作用域与安全属性访问 -├── builtins.ts 内置函数(纯函数) -├── evaluator.ts 受限求值器 -├── binding.ts ValueBinding 求值与格式化 -└── index.ts 公共出口 -``` - -## 开发 - -```bash -pnpm build # tsup 打包 -pnpm test # vitest -pnpm typecheck # tsc --noEmit -``` - -## 当前测试覆盖 - -`tests/expression.test.ts` 共 **83** 个用例,其中 20 个专门验证安全边界: - -- 禁止任意代码执行:`eval`、`Function`、`require`、`import()`、宿主 API -- 原型链逃逸:`constructor`、`__proto__`、`prototype` 及其组合 -- 不支持的语法:模板字符串、箭头函数、赋值、`new`、`this`、注释 -- 作用域白名单与 `extra` 自定义根 -- 运算语义、空值处理、内置函数、格式化 -- 错误诊断与编译缓存 - -## 尚未实现 - -- 聚合函数(`sum` / `avg` / `count`),需要配合分组的上下文聚合(阶段 3)。 -- 自定义函数注册接口(当前白名单为编译期常量)。 diff --git a/code/one-designer/packages/report-expression/package.json b/code/one-designer/packages/report-expression/package.json deleted file mode 100644 index 57860528..00000000 --- a/code/one-designer/packages/report-expression/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@report/expression", - "version": "0.1.0", - "description": "受限表达式的词法、语法、AST 与求值器", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" - } - }, - "files": ["dist"], - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit -p tsconfig.test.json" - }, - "dependencies": { - "@report/core": "workspace:*" - }, - "devDependencies": { - "tsup": "^8.3.5", - "typescript": "^5.7.2", - "vitest": "^2.1.8" - } -} diff --git a/code/one-designer/packages/report-expression/src/ast.ts b/code/one-designer/packages/report-expression/src/ast.ts deleted file mode 100644 index ddda406b..00000000 --- a/code/one-designer/packages/report-expression/src/ast.ts +++ /dev/null @@ -1,228 +0,0 @@ -/** - * 表达式 AST(对应设计文档 §10)。 - * - * 只有这一组节点类型可以被求值器执行,杜绝了运行任意代码的可能。 - */ - -export type NodeType = - | "Literal" - | "Identifier" - | "Member" - | "Index" - | "Call" - | "Unary" - | "Binary" - | "Logical" - | "Conditional" - -/** 源码位置,用于诊断定位。 */ -export interface SourceSpan { - start: number - end: number -} - -interface BaseNode { - type: NodeType - span: SourceSpan -} - -/** 字面量:数字 / 字符串 / 布尔 / null。 */ -export interface LiteralNode extends BaseNode { - type: "Literal" - value: string | number | boolean | null -} - -/** 标识符:作用域根,如 row、params、page。 */ -export interface IdentifierNode extends BaseNode { - type: "Identifier" - name: string -} - -/** 成员访问:a.b。 */ -export interface MemberNode extends BaseNode { - type: "Member" - object: ExpressionNode - property: string -} - -/** 下标访问:a[0]。 */ -export interface IndexNode extends BaseNode { - type: "Index" - object: ExpressionNode - index: ExpressionNode -} - -/** 函数调用:f(a, b)。 */ -export interface CallNode extends BaseNode { - type: "Call" - callee: string - args: ExpressionNode[] -} - -/** 一元运算:-a、!a。 */ -export interface UnaryNode extends BaseNode { - type: "Unary" - operator: "-" | "+" | "!" - argument: ExpressionNode -} - -/** 二元运算:a + b。 */ -export interface BinaryNode extends BaseNode { - type: "Binary" - operator: "+" | "-" | "*" | "/" | "%" | "==" | "!=" | "===" | "!==" | ">" | ">=" | "<" | "<=" - left: ExpressionNode - right: ExpressionNode -} - -/** 逻辑运算:a && b、a || b、a ?? b。 */ -export interface LogicalNode extends BaseNode { - type: "Logical" - operator: "&&" | "||" | "??" - left: ExpressionNode - right: ExpressionNode -} - -/** 三元条件:cond ? a : b。 */ -export interface ConditionalNode extends BaseNode { - type: "Conditional" - test: ExpressionNode - consequent: ExpressionNode - alternate: ExpressionNode -} - -export type ExpressionNode = - | LiteralNode - | IdentifierNode - | MemberNode - | IndexNode - | CallNode - | UnaryNode - | BinaryNode - | LogicalNode - | ConditionalNode - -/** 解析错误。 */ -export interface ParseError { - message: string - span: SourceSpan -} - -/** 解析结果。 */ -export interface ParseResult { - ast: ExpressionNode | null - error: ParseError | null -} - -/** 遍历 AST 的所有子节点,供分析与校验使用。 */ -export function walkNode( - node: ExpressionNode, - visit: (child: ExpressionNode) => void, -): void { - switch (node.type) { - case "Literal": - case "Identifier": - return - case "Member": - visit(node.object) - return - case "Index": - visit(node.object) - visit(node.index) - return - case "Call": - for (const arg of node.args) visit(arg) - return - case "Unary": - visit(node.argument) - return - case "Binary": - case "Logical": - visit(node.left) - visit(node.right) - return - case "Conditional": - visit(node.test) - visit(node.consequent) - visit(node.alternate) - return - } -} - -/** - * 收集表达式中引用的作用域根标识符。 - * - * 例如 `row.amount + params.tax` 会返回 ["row", "params"]。 - * 供宿主在绑定前校验作用域是否可用。 - */ -export function collectRootIdentifiers(node: ExpressionNode): Set { - const roots = new Set() - const visitRoot = (current: ExpressionNode, isRoot: boolean): void => { - if (current.type === "Identifier") { - if (isRoot) roots.add(current.name) - return - } - switch (current.type) { - case "Member": - visitRoot(current.object, isRoot) - return - case "Index": - visitRoot(current.object, isRoot) - visitRoot(current.index, false) - return - case "Call": - for (const arg of current.args) visitRoot(arg, false) - return - case "Unary": - visitRoot(current.argument, false) - return - case "Binary": - case "Logical": - visitRoot(current.left, false) - visitRoot(current.right, false) - return - case "Conditional": - visitRoot(current.test, false) - visitRoot(current.consequent, false) - visitRoot(current.alternate, false) - return - case "Literal": - return - } - } - visitRoot(node, true) - return roots -} - -/** 收集表达式调用的所有函数名。 */ -export function collectFunctionNames(node: ExpressionNode): Set { - const names = new Set() - const visit = (current: ExpressionNode): void => { - if (current.type === "Call") names.add(current.callee) - walkNode(current, visit) - } - visit(node) - return names -} - -/** 把 AST 重新打印为表达式源码,便于诊断信息展示。 */ -export function printNode(node: ExpressionNode): string { - switch (node.type) { - case "Literal": - return typeof node.value === "string" ? JSON.stringify(node.value) : String(node.value) - case "Identifier": - return node.name - case "Member": - return `${printNode(node.object)}.${node.property}` - case "Index": - return `${printNode(node.object)}[${printNode(node.index)}]` - case "Call": - return `${node.callee}(${node.args.map(printNode).join(", ")})` - case "Unary": - return `${node.operator}${printNode(node.argument)}` - case "Binary": - case "Logical": - return `(${printNode(node.left)} ${node.operator} ${printNode(node.right)})` - case "Conditional": - return `(${printNode(node.test)} ? ${printNode(node.consequent)} : ${printNode(node.alternate)})` - } -} diff --git a/code/one-designer/packages/report-expression/src/binding.ts b/code/one-designer/packages/report-expression/src/binding.ts deleted file mode 100644 index ce5a26ae..00000000 --- a/code/one-designer/packages/report-expression/src/binding.ts +++ /dev/null @@ -1,167 +0,0 @@ -/** - * 值绑定求值(对应设计文档 §6.2 的 ValueBinding 与 §10)。 - * - * 把文档里的 ValueBinding { field, expression, format } 解析成最终值。 - * 这是 report-layout 消费绑定的统一入口,保证字段与表达式两条路径 - * 行为一致(都走受限求值器,字段只是 expression 的语法糖)。 - */ -import type { Diagnostic } from "@report/core" -import type { ValueBinding } from "@report/core" -import { DIAGNOSTIC_CODES } from "@report/core" -import { compile, evaluateCompiled, type CompiledExpression } from "./evaluator.js" -import type { EvalScope } from "./scope.js" - -/** 绑定求值选项。 */ -export interface ResolveBindingOptions { - scope: EvalScope - elementId?: string - path?: string -} - -/** 绑定求值结果。 */ -export interface ResolveBindingResult { - value: unknown - /** 格式化后的展示文本。 */ - text: string - diagnostics: Diagnostic[] -} - -/** - * 编译缓存。 - * - * 同一表达式在明细表里会对每一行求值一次,缓存解析结果避免重复解析。 - * 使用 Map 而非模块级单例,由调用方决定生命周期。 - */ -export class ExpressionCache { - private readonly cache = new Map() - - get(source: string): CompiledExpression { - const existing = this.cache.get(source) - if (existing) return existing - const compiled = compile(source) - this.cache.set(source, compiled) - return compiled - } - - clear(): void { - this.cache.clear() - } - - get size(): number { - return this.cache.size - } -} - -/** - * 把 field 路径转为表达式源码。 - * - * field 形如 "amount" 或 "customer.name",统一求值为 row.。 - */ -export function fieldToExpression(field: string): string { - return `row.${field}` -} - -/** - * 解析一个值绑定。 - * - * 优先级:expression > field。两者都缺省时返回空值。 - * format 只影响 text,不影响 value,便于 Renderer 自行决定呈现方式。 - */ -export function resolveBinding( - binding: ValueBinding | undefined, - options: ResolveBindingOptions, - cache?: ExpressionCache, -): ResolveBindingResult { - if (!binding) { - return { value: null, text: "", diagnostics: [] } - } - - const diagnostics: Diagnostic[] = [] - let value: unknown = null - - if (binding.expression) { - const compiled = cache ? cache.get(binding.expression) : compile(binding.expression) - const result = evaluateCompiled(compiled, options) - value = result.value - diagnostics.push(...result.diagnostics) - } else if (binding.field) { - const source = fieldToExpression(binding.field) - const compiled = cache ? cache.get(source) : compile(source) - const result = evaluateCompiled(compiled, options) - value = result.value - diagnostics.push(...result.diagnostics) - - // 字段缺失通常意味着数据源与设计不一致,值得单独提示 - if (value === undefined) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.DATA_DATASET_MISSING, - message: `字段 "${binding.field}" 在当前数据行中不存在`, - ...(options.elementId !== undefined ? { elementId: options.elementId } :{}), - ...(options.path !== undefined ? { path: options.path } :{}), - }) - } - } - - const text = formatValue(value, binding.format, options, cache) - diagnostics.push(...text.diagnostics) - - return { value, text: text.text, diagnostics } -} - -interface FormatResult { - text: string - diagnostics: Diagnostic[] -} - -/** - * 格式化值。 - * - * 缺省行为:null / undefined 渲染为空串,其余走 String()。 - * 指定 format 时复用表达式的 format() 内置函数,保证与表达式内 - * format() 的行为完全一致。 - */ -export function formatValue( - value: unknown, - format: string | undefined, - options: ResolveBindingOptions, - cache?: ExpressionCache, -): FormatResult { - if (value === null || value === undefined) return { text: "", diagnostics: [] } - - if (!format) { - return { text: defaultStringify(value), diagnostics: [] } - } - - // 复用 format() 内置函数,避免两套格式化逻辑产生分歧 - const source = `format(row.__value, ${JSON.stringify(format)})` - const compiled = cache ? cache.get(source) : compile(source) - const result = evaluateCompiled(compiled, { - ...options, - scope: { - ...options.scope, - row: { ...(options.scope.row ?? {}), __value: value }, - }, - }) - - return { - text: result.value === null ? "" : defaultStringify(result.value), - diagnostics: result.diagnostics, - } -} - -function defaultStringify(value: unknown): string { - if (value === null || value === undefined) return "" - if (typeof value === "string") return value - if (typeof value === "number") return Number.isFinite(value) ? String(value) : "" - if (typeof value === "boolean") return value ? "true" : "false" - if (value instanceof Date) return value.toISOString() - // 对象与数组不做隐式展开,避免把内部结构写进报表 - return "" -} - -/** 判断绑定是否为空(无 field 也无 expression)。 */ -export function isBindingEmpty(binding: ValueBinding | undefined): boolean { - if (!binding) return true - return !binding.field && !binding.expression -} diff --git a/code/one-designer/packages/report-expression/src/builtins.ts b/code/one-designer/packages/report-expression/src/builtins.ts deleted file mode 100644 index 062db3e3..00000000 --- a/code/one-designer/packages/report-expression/src/builtins.ts +++ /dev/null @@ -1,355 +0,0 @@ -/** - * 内置函数(对应设计文档 §10 与 §4.2)。 - * - * V1 至少支持: - * 字段:row.amount - * 参数:params.customerName - * 简单运算:row.price * row.quantity - * 条件:if(row.amount > 0, "有", "无") - * 格式化:format(row.date, "YYYY-MM-DD") - * - * 所有函数都是纯函数,除参数外不接触任何外部状态。 - */ - -/** 函数实现签名。 */ -export type BuiltinFunction = (args: unknown[]) => unknown - -function toNumber(value: unknown): number { - if (typeof value === "number") return value - if (typeof value === "boolean") return value ? 1 : 0 - if (typeof value === "string") { - const trimmed = value.trim() - if (trimmed === "") return 0 - const parsed = Number(trimmed) - return Number.isNaN(parsed) ? Number.NaN : parsed - } - if (value === null || value === undefined) return 0 - return Number.NaN -} - -function toString(value: unknown): string { - if (value === null || value === undefined) return "" - if (typeof value === "string") return value - if (typeof value === "number" || typeof value === "boolean") return String(value) - // 对象不做隐式序列化,避免把内部结构意外写进报表 - return "" -} - -/** 把 Date 或可解析的日期值规范化为 Date。 */ -function toDate(value: unknown): Date | null { - if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value - if (typeof value === "number") { - const d = new Date(value) - return Number.isNaN(d.getTime()) ? null : d - } - if (typeof value === "string" && value.trim() !== "") { - // 优先接受 ISO;再尝试 YYYY-MM-DD / YYYY/MM/DD - const iso = new Date(value) - if (!Number.isNaN(iso.getTime())) return iso - } - return null -} - -function pad(value: number, length = 2): string { - return String(Math.abs(value)).padStart(length, "0") -} - -/** - * 按模式格式化日期。 - * - * 支持 YYYY MM DD HH mm ss SSS,以及常见的 M D H m s 简写。 - * 小时使用 HH(24 小时制),避免 AM/PM 带来的歧义。 - */ -function formatDate(date: Date, pattern: string): string { - const tokens: Record = { - YYYY: String(date.getFullYear()), - MM: pad(date.getMonth() + 1), - DD: pad(date.getDate()), - HH: pad(date.getHours()), - mm: pad(date.getMinutes()), - ss: pad(date.getSeconds()), - SSS: String(date.getMilliseconds()).padStart(3, "0"), - M: String(date.getMonth() + 1), - D: String(date.getDate()), - H: String(date.getHours()), - } - // 长 token 优先,防止 MM 被 M 抢先匹配 - return pattern.replace(/YYYY|SSS|MM|DD|HH|mm|ss|M|D|H/g, (match) => tokens[match] ?? match) -} - -/** - * 按模式格式化数字。 - * - * 支持 #,##0.00 这类千分位与小位数模式,以及 0%、0.0% 百分比。 - */ -function formatNumber(value: number, pattern: string): string { - if (!Number.isFinite(value)) return "" - - // 百分比模式 - if (pattern.includes("%")) { - const decimals = (pattern.split(".")[1] ?? "").replace("%", "").length - return `${(value * 100).toFixed(decimals)}%` - } - - const decimalPart = pattern.split(".")[1] ?? "" - const decimals = decimalPart.replace(/[^0#]/g, "").length - const useGrouping = pattern.includes(",") - - let text = value.toFixed(decimals) - if (useGrouping) { - const negative = text.startsWith("-") - if (negative) text = text.slice(1) - const [intPart = "", fracPart] = text.split(".") - const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",") - text = fracPart !== undefined ? `${grouped}.${fracPart}` : grouped - if (negative) text = `-${text}` - } - return text -} - -/** 内置函数表。必须与 parser 的白名单保持一致。 */ -export const BUILTINS: Record = { - /** 条件:if(cond, a, b)。惰性由求值器保证。 */ - if: (args) => (args[0] ? args[1] : args[2]), - - /** 逻辑与:全部为真才为真。 */ - and: (args) => args.every((a) => Boolean(a)), - - /** 逻辑或:任一为真即为真。 */ - or: (args) => args.some((a) => Boolean(a)), - - /** 逻辑非。 */ - not: (args) => !args[0], - - /** 字符串拼接,null/undefined 视为空串。 */ - concat: (args) => args.map(toString).join(""), - - /** - * 格式化:format(value, pattern)。 - * - * 值是日期时按日期模式格式化,是数字时按数字模式格式化。 - */ - format: (args) => { - const value = args[0] - const pattern = toString(args[1]) - if (!pattern) return toString(value) - - const date = toDate(value) - // 含日期 token 的模式走日期格式化;纯数字模式走数字格式化 - if (date && /Y|M|D|H|m|s/.test(pattern)) { - return formatDate(date, pattern) - } - if (typeof value === "number" || (typeof value === "string" && value.trim() !== "" && !Number.isNaN(Number(value)))) { - return formatNumber(toNumber(value), pattern) - } - return toString(value) - }, - - round: (args) => { - const value = toNumber(args[0]) - const digits = args.length > 1 ? toNumber(args[1]) : 0 - if (!Number.isFinite(value)) return null - const factor = 10 ** digits - return Math.round(value * factor) / factor - }, - - floor: (args) => { - const value = toNumber(args[0]) - return Number.isFinite(value) ? Math.floor(value) : null - }, - - ceil: (args) => { - const value = toNumber(args[0]) - return Number.isFinite(value) ? Math.ceil(value) : null - }, - - abs: (args) => { - const value = toNumber(args[0]) - return Number.isFinite(value) ? Math.abs(value) : null - }, - - /** - * 最小值。 - * - * 同时支持两种调用形态: - * - 标量比较:min(3, 1, 2) → 1 - * - 数组聚合:min(group.amounts) → 数组中的最小值 - * 单参数且为数组时按聚合处理,否则按逐参数比较。 - */ - min: (args) => { - const nums = collectNumbers(args) - return nums.length > 0 ? Math.min(...nums) : null - }, - - /** 最大值。调用形态同 min。 */ - max: (args) => { - const nums = collectNumbers(args) - return nums.length > 0 ? Math.max(...nums) : null - }, - - len: (args) => { - const value = args[0] - if (typeof value === "string") return value.length - if (Array.isArray(value)) return value.length - if (value === null || value === undefined) return 0 - return toString(value).length - }, - - upper: (args) => toString(args[0]).toUpperCase(), - lower: (args) => toString(args[0]).toLowerCase(), - trim: (args) => toString(args[0]).trim(), - - /** 截取子串:substr(text, start, length?)。start 从 0 开始。 */ - substr: (args) => { - const text = toString(args[0]) - const start = Math.max(0, Math.trunc(toNumber(args[1]))) - if (args.length < 3) return text.slice(start) - const length = Math.max(0, Math.trunc(toNumber(args[2]))) - return text.slice(start, start + length) - }, - - /** - * 替换:replace(text, search, replacement)。 - * - * 只做字面量替换,不接受正则,避免 ReDoS 与转义歧义。 - */ - replace: (args) => { - const text = toString(args[0]) - const search = toString(args[1]) - const replacement = toString(args[2]) - if (search === "") return text - return text.split(search).join(replacement) - }, - - isnull: (args) => args[0] === null || args[0] === undefined || args[0] === "", - - /** 返回第一个非空的参数。 */ - coalesce: (args) => { - for (const arg of args) { - if (arg !== null && arg !== undefined && arg !== "") return arg - } - return null - }, - - /** 转数字,失败返回 null 而不是 NaN,便于报表侧用 coalesce 兜底。 */ - number: (args) => { - const value = toNumber(args[0]) - return Number.isFinite(value) ? value : null - }, - - string: (args) => toString(args[0]), - - /** - * 构造日期:date(value)。 - * - * 返回 ISO 字符串而非 Date 对象,保证表达式结果始终是可序列化的纯数据。 - */ - date: (args) => { - const date = toDate(args[0]) - return date ? date.toISOString() : null - }, - - // ------------------------------------------------------------------------- - // 聚合函数 - // - // 聚合的语义约定(与分组配合使用): - // - 参数是数组时,直接对数组元素聚合,如 sum(group.rows.amount) 不成立, - // 应写 sum(group.amounts)。 - // - 参数是标量时,视为"单元素聚合",等价于对该值本身取聚合。 - // - 空数组/无有效值:sum 返回 0,avg/min/max 返回 null(避免除零与伪值), - // count 返回 0。 - // 这样设计的原因是:报表里合计为 0 与"没有数据"是两种不同语义, - // 前者应显示 0,后者应显示空白。 - // ------------------------------------------------------------------------- - - /** 求和。非数字元素被忽略。 */ - sum: (args) => { - const list = toAggregateList(args[0]) - let total = 0 - for (const item of list) { - const n = toNumber(item) - if (Number.isFinite(n)) total += n - } - return total - }, - - /** - * 平均值。无有效值时返回 null。 - * - * 空值(null/undefined)与空字符串会被完全忽略,不参与分子也不参与分母。 - * 这一点与 sum 不同:sum 把 null 视为 0 是正确的(合计里空值就是没贡献), - * 但 avg 若把 null 当 0 计入分母,会把平均值稀释成偏小的错误数字。 - */ - avg: (args) => { - const list = toAggregateList(args[0]) - let total = 0 - let count = 0 - for (const item of list) { - if (item === null || item === undefined) continue - if (typeof item === "string" && item.trim() === "") continue - const n = toNumber(item) - if (Number.isFinite(n)) { - total += n - count += 1 - } - } - return count > 0 ? total / count : null - }, - - /** 计数。无参数时统计元素个数;有参数时统计非空值个数。 */ - count: (args) => { - if (args.length === 0) return 0 - const list = toAggregateList(args[0]) - // 标量参数(非数组)视为 1 个元素 - if (!Array.isArray(args[0])) { - const value = args[0] - return value === null || value === undefined ? 0 : 1 - } - // 单参数形式 count(list):统计非空元素 - if (args.length === 1) { - let n = 0 - for (const item of list) { - if (item !== null && item !== undefined) n += 1 - } - return n - } - return list.length - }, -} - -/** - * 把聚合参数规范化为数组。 - * - * 数组原样返回;标量包装成单元素数组;null/undefined 返回空数组。 - */ -function toAggregateList(value: unknown): unknown[] { - if (Array.isArray(value)) return value - if (value === null || value === undefined) return [] - return [value] -} - -/** - * 从实参列表收集有限数字,兼容两种调用形态: - * - 多参数:min(3, 1, 2) —— 逐个转换 - * - 单参数数组:min(group.amounts) —— 展开数组转换 - */ -function collectNumbers(args: unknown[]): number[] { - const out: number[] = [] - // 单参数且为数组时按聚合处理 - const source = args.length === 1 ? toAggregateList(args[0]) : args - for (const item of source) { - const n = toNumber(item) - if (Number.isFinite(n)) out.push(n) - } - return out -} - -/** 判断函数名是否为内置函数。 */ -export function isBuiltinFunction(name: string): boolean { - return Object.prototype.hasOwnProperty.call(BUILTINS, name) -} - -/** 全部内置函数名。 */ -export function builtinFunctionNames(): string[] { - return Object.keys(BUILTINS).sort() -} diff --git a/code/one-designer/packages/report-expression/src/evaluator.ts b/code/one-designer/packages/report-expression/src/evaluator.ts deleted file mode 100644 index 5820c002..00000000 --- a/code/one-designer/packages/report-expression/src/evaluator.ts +++ /dev/null @@ -1,373 +0,0 @@ -/** - * 受限求值器(对应设计文档 §10、§4.2)。 - * - * 明确禁止通过 eval 或 new Function 执行任意 JavaScript。 - * - * 本文件是"受限"这一约束的落地点,安全边界如下: - * 1. 只处理 ast.ts 中定义的节点类型,没有其它可执行形式。 - * 2. 作用域根只能命中 scope.ts 的白名单,拿不到 window / globalThis / process。 - * 3. 属性访问拒绝 __proto__ / constructor / prototype,阻断原型链逃逸。 - * 4. 函数调用只查 builtins 表,且 parser 已在解析期做过白名单过滤。 - * 5. 求值过程中任何异常都被捕获并转成诊断,不会向上抛。 - */ -import type { Diagnostic } from "@report/core" -import { DIAGNOSTIC_CODES } from "@report/core" -import type { ExpressionNode } from "./ast.js" -import { printNode } from "./ast.js" -import { BUILTINS } from "./builtins.js" -import { parse } from "./parser.js" -import { resolveRoot, safeGet, type EvalScope } from "./scope.js" - -/** 求值选项。 */ -export interface EvalOptions { - /** 作用域。 */ - scope: EvalScope - /** 出错的元素 ID,用于诊断定位。 */ - elementId?: string - /** 字段路径,用于诊断定位。 */ - path?: string - /** - * 表达式执行的时间上限(毫秒)。 - * - * 由于语法受限、无循环结构,表达式天然会终止;该选项仅作为 - * 宿主对异常输入的最后一道保护,默认不启用。 - */ - timeoutMs?: number -} - -/** 求值结果。 */ -export interface EvalResult { - value: unknown - diagnostics: Diagnostic[] -} - -/** - * 求值已解析的 AST。 - * - * 不使用 eval / new Function,纯粹按节点类型递归求值。 - */ -export function evaluateAst(node: ExpressionNode, options: EvalOptions): EvalResult { - const diagnostics: Diagnostic[] = [] - - const context = { - scope: options.scope, - ...(options.elementId !== undefined ? { elementId: options.elementId } :{}), - ...(options.path !== undefined ? { path: options.path } :{}), - report(message: string, span?: { start: number; end: number }): void { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.EXPRESSION_EVAL_ERROR, - message, - ...(options.elementId !== undefined ? { elementId: options.elementId } :{}), - ...(options.path !== undefined ? { path: options.path } :{}), - }) - void span - }, - } - - const value = evalNode(node, context) - return { value, diagnostics } -} - -/** 内部求值上下文。 */ -interface EvalContext { - scope: EvalScope - elementId?: string - path?: string - report(message: string, span?: { start: number; end: number }): void -} - -function evalNode(node: ExpressionNode, ctx: EvalContext): unknown { - switch (node.type) { - case "Literal": - return node.value - - case "Identifier": - return resolveRoot(ctx.scope, node.name) - - case "Member": { - const object = evalNode(node.object, ctx) - return safeGet(object, node.property) - } - - case "Index": { - const object = evalNode(node.object, ctx) - const index = evalNode(node.index, ctx) - return safeGet(object, String(index)) - } - - case "Unary": { - const value = evalNode(node.argument, ctx) - switch (node.operator) { - case "-": { - const n = toNumberStrict(value) - return n === null ? null : -n - } - case "+": { - const n = toNumberStrict(value) - return n === null ? 0 : n - } - case "!": - return !toBoolean(value) - } - return null - } - - case "Binary": - return evalBinary(node, ctx) - - case "Logical": { - const left = evalNode(node.left, ctx) - switch (node.operator) { - case "&&": - // 短路:左值为假就不再求值右侧,避免无谓的错误诊断 - return toBoolean(left) ? evalNode(node.right, ctx) : left - case "||": - return toBoolean(left) ? left : evalNode(node.right, ctx) - case "??": - return left === null || left === undefined ? evalNode(node.right, ctx) : left - } - return null - } - - case "Conditional": - return toBoolean(evalNode(node.test, ctx)) - ? evalNode(node.consequent, ctx) - : evalNode(node.alternate, ctx) - - case "Call": - return evalCall(node, ctx) - } -} - -function evalBinary( - node: Extract, - ctx: EvalContext, -): unknown { - const left = evalNode(node.left, ctx) - const right = evalNode(node.right, ctx) - - switch (node.operator) { - case "+": { - // 一方是字符串则做拼接,否则做加法;null/undefined 视为 0 - if (typeof left === "string" || typeof right === "string") { - return toText(left) + toText(right) - } - // null / undefined 视为 0,与 toNumberStrict("") === 0 保持一致, - // 避免报表里出现空单元格导致整列求和变空。 - const a = left === null || left === undefined ? 0 : toNumberStrict(left) - const b = right === null || right === undefined ? 0 : toNumberStrict(right) - if (a === null || b === null) return null - return a + b - } - - case "-": - case "*": - case "/": - case "%": { - // 减法/乘法中 null 同样视为 0;除法与取模的除数仍按 0 处理并报诊断 - const a = left === null || left === undefined ? 0 : toNumberStrict(left) - const b = right === null || right === undefined ? 0 : toNumberStrict(right) - if (a === null || b === null) return null - if ((node.operator === "/" || node.operator === "%") && b === 0) { - // 除零返回 null 并给出诊断,避免产生 Infinity 污染报表 - ctx.report("除数为 0,结果按空值处理", node.span) - return null - } - switch (node.operator) { - case "-": return a - b - case "*": return a * b - case "/": return a / b - default: return a % b - } - } - - case "==": - case "===": - return looseEquals(left, right, node.operator === "===") - - case "!=": - case "!==": - return !looseEquals(left, right, node.operator === "!==") - - case ">": - case ">=": - case "<": - case "<=": - return compare(left, right, node.operator) - } -} - -function evalCall( - node: Extract, - ctx: EvalContext, -): unknown { - const fn = BUILTINS[node.callee] - if (!fn) { - // 正常情况下 parser 已拦截,这里作为纵深防御 - ctx.report(`不允许调用函数 "${node.callee}"`, node.span) - return null - } - - // if 惰性求值:只求值命中的分支,避免未选中分支的错误影响结果 - if (node.callee === "if") { - const test = evalNode(node.args[0]!, ctx) - return toBoolean(test) - ? node.args[1] - ? evalNode(node.args[1], ctx) - : null - : node.args[2] - ? evalNode(node.args[2], ctx) - : null - } - - const args = node.args.map((arg) => evalNode(arg, ctx)) - try { - return fn(args) - } catch (cause) { - ctx.report(`函数 ${node.callee} 执行失败:${(cause as Error).message}`, node.span) - return null - } -} - -function toBoolean(value: unknown): boolean { - if (value === null || value === undefined) return false - if (typeof value === "boolean") return value - if (typeof value === "number") return value !== 0 && !Number.isNaN(value) - if (typeof value === "string") return value.length > 0 - if (Array.isArray(value)) return value.length > 0 - return true -} - -function toText(value: unknown): string { - if (value === null || value === undefined) return "" - if (typeof value === "string") return value - if (typeof value === "number" || typeof value === "boolean") return String(value) - return "" -} - -/** 严格转数字,失败返回 null(而不是 NaN)。 */ -function toNumberStrict(value: unknown): number | null { - if (typeof value === "number") return Number.isNaN(value) ? null : value - if (typeof value === "boolean") return value ? 1 : 0 - if (typeof value === "string") { - const trimmed = value.trim() - if (trimmed === "") return 0 - const parsed = Number(trimmed) - return Number.isNaN(parsed) ? null : parsed - } - if (value === null || value === undefined) return null - return null -} - -function looseEquals(a: unknown, b: unknown, strict: boolean): boolean { - if (a === b) return true - if (a === null || a === undefined) return b === null || b === undefined - if (b === null || b === undefined) return false - if (strict) return false - - // 宽松比较:数值优先,其次字符串 - const na = toNumberStrict(a) - const nb = toNumberStrict(b) - if (na !== null && nb !== null) return na === nb - return toText(a) === toText(b) -} - -function compare(a: unknown, b: unknown, operator: string): boolean { - // 两边都能转数字时按数值比较,否则按字符串比较(支持日期串) - const na = toNumberStrict(a) - const nb = toNumberStrict(b) - const bothNumeric = na !== null && nb !== null - - let result: number - if (bothNumeric) { - result = na - nb - } else { - const sa = toText(a) - const sb = toText(b) - result = sa < sb ? -1 : sa > sb ? 1 : 0 - } - - switch (operator) { - case ">": return result > 0 - case ">=": return result >= 0 - case "<": return result < 0 - default: return result <= 0 - } -} - -/** - * 一步到位:解析并求值表达式字符串。 - * - * 单个字段出错不应导致整个文档无结果(§10),因此这里总是返回结果对象, - * 错误体现在 diagnostics 中。 - */ -export function evaluateExpression(source: string, options: EvalOptions): EvalResult { - const { ast, error } = parse(source) - if (!ast || error) { - return { - value: null, - diagnostics: [ - { - severity: "warning", - code: DIAGNOSTIC_CODES.EXPRESSION_PARSE_ERROR, - message: `表达式解析失败:${error?.message ?? "未知错误"}(${source})`, - ...(options.elementId !== undefined ? { elementId: options.elementId } :{}), - ...(options.path !== undefined ? { path: options.path } :{}), - }, - ], - } - } - return evaluateAst(ast, options) -} - -/** - * 预编译表达式。 - * - * Designer 里同一表达式会被反复求值(每一行一次),预编译避免重复解析。 - */ -export function compile(source: string): CompiledExpression { - const { ast, error } = parse(source) - return { - source, - ast, - error: error ? error.message : null, - } -} - -/** 已编译表达式。 */ -export interface CompiledExpression { - source: string - ast: ExpressionNode | null - error: string | null -} - -/** 求值已编译表达式。 */ -export function evaluateCompiled( - compiled: CompiledExpression, - options: EvalOptions, -): EvalResult { - if (!compiled.ast) { - return { - value: null, - diagnostics: [ - { - severity: "warning", - code: DIAGNOSTIC_CODES.EXPRESSION_PARSE_ERROR, - message: `表达式解析失败:${compiled.error ?? "未知错误"}(${compiled.source})`, - ...(options.elementId !== undefined ? { elementId: options.elementId } :{}), - ...(options.path !== undefined ? { path: options.path } :{}), - }, - ], - } - } - return evaluateAst(compiled.ast, options) -} - -/** 便捷函数:只关心值,忽略诊断。 */ -export function evaluateValue(source: string, scope: EvalScope): unknown { - return evaluateExpression(source, { scope }).value -} - -/** 打印 AST 回源码,便于诊断展示。 */ -export { printNode } diff --git a/code/one-designer/packages/report-expression/src/index.ts b/code/one-designer/packages/report-expression/src/index.ts deleted file mode 100644 index 47d9127d..00000000 --- a/code/one-designer/packages/report-expression/src/index.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @report/expression 公共入口(对应设计文档 §4.2、§10)。 - * - * 表达式系统使用受限语法和 AST,不执行任意 JavaScript。 - * 本包只依赖 @report/core 的类型,不依赖 DOM 或任何求值框架。 - */ - -// 词法 -export type { Token, TokenType, TokenizeError, TokenizeResult } from "./tokenizer.js" -export { tokenize, KEYWORDS } from "./tokenizer.js" - -// AST -export type { - ExpressionNode, - NodeType, - SourceSpan, - LiteralNode, - IdentifierNode, - MemberNode, - IndexNode, - CallNode, - UnaryNode, - BinaryNode, - LogicalNode, - ConditionalNode, - ParseError, - ParseResult, -} from "./ast.js" -export { - walkNode, - collectRootIdentifiers, - collectFunctionNames, - printNode, -} from "./ast.js" - -// 语法 -export { parse, isValidExpression, allowedFunctionNames } from "./parser.js" - -// 作用域 -export type { EvalScope, ScopeRoot } from "./scope.js" -export { SCOPE_ROOTS, resolveRoot, safeGet } from "./scope.js" - -// 内置函数 -export type { BuiltinFunction } from "./builtins.js" -export { BUILTINS, isBuiltinFunction, builtinFunctionNames } from "./builtins.js" - -// 求值 -export type { - EvalOptions, - EvalResult, - CompiledExpression, -} from "./evaluator.js" -export { - evaluateAst, - evaluateExpression, - evaluateCompiled, - evaluateValue, - compile, -} from "./evaluator.js" - -// 绑定 -export type { - ResolveBindingOptions, - ResolveBindingResult, -} from "./binding.js" -export { - ExpressionCache, - resolveBinding, - formatValue, - fieldToExpression, - isBindingEmpty, -} from "./binding.js" diff --git a/code/one-designer/packages/report-expression/src/parser.ts b/code/one-designer/packages/report-expression/src/parser.ts deleted file mode 100644 index 80e8b339..00000000 --- a/code/one-designer/packages/report-expression/src/parser.ts +++ /dev/null @@ -1,396 +0,0 @@ -/** - * 表达式解析器(对应设计文档 §10)。 - * - * 手写递归下降解析器,优先级由低到高: - * - * conditional ?: - * logical-or || - * logical-and && - * nullish ?? - * equality == != === !== - * relational > >= < <= - * additive + - - * multiplicative * / % - * unary - + ! - * postfix . [] () - * primary 字面量 / 标识符 / ( expr ) - * - * 不使用 eval / new Function,也不生成可执行 JS 字符串。 - */ -import type { ExpressionNode, ParseError, ParseResult, SourceSpan } from "./ast.js" -import { tokenize, type Token } from "./tokenizer.js" - -/** 二元运算符优先级表。 */ -const BINARY_PRECEDENCE: Record = { - "||": 1, - "&&": 2, - "??": 3, - "==": 4, - "!=": 4, - "===": 4, - "!==": 4, - ">": 5, - ">=": 5, - "<": 5, - "<=": 5, - "+": 6, - "-": 6, - "*": 7, - "/": 7, - "%": 7, -} - -class Parser { - private readonly tokens: Token[] - private index = 0 - - constructor(tokens: Token[]) { - this.tokens = tokens - } - - private peek(): Token { - return this.tokens[this.index]! - } - - private next(): Token { - const token = this.tokens[this.index]! - if (token.type !== "eof") this.index += 1 - return token - } - - private span(from: Token, to: Token): SourceSpan { - return { start: from.start, end: to.end } - } - - /** 解析完整表达式,要求消费掉所有 token。 */ - parseExpression(): ParseResult { - try { - const expr = this.parseConditional() - const rest = this.peek() - if (rest.type !== "eof") { - return { - ast: null, - error: { - message: `表达式末尾存在多余内容 "${rest.value}"`, - span: { start: rest.start, end: rest.end }, - }, - } - } - return { ast: expr, error: null } - } catch (cause) { - if (cause instanceof ParseFailure) { - return { ast: null, error: { message: cause.message, span: cause.span } } - } - throw cause - } - } - - private fail(message: string, span: SourceSpan): never { - throw new ParseFailure(message, span) - } - - private parseConditional(): ExpressionNode { - const test = this.parseBinary(0) - const token = this.peek() - if (token.type === "operator" && token.value === "?") { - this.next() - const consequent = this.parseConditional() - const colon = this.peek() - if (!(colon.type === "punctuation" && colon.value === ":")) { - this.fail('三元表达式缺少 ":"', { start: colon.start, end: colon.end }) - } - this.next() - const alternate = this.parseConditional() - return { - type: "Conditional", - test, - consequent, - alternate, - span: this.span(token, colon), - } - } - return test - } - - /** 优先级爬升法解析二元与逻辑运算。 */ - private parseBinary(minPrecedence: number): ExpressionNode { - let left = this.parseUnary() - - for (;;) { - const token = this.peek() - if (token.type !== "operator") break - const precedence = BINARY_PRECEDENCE[token.value] - if (precedence === undefined || precedence < minPrecedence) break - - this.next() - // 左结合:右侧要求更高优先级 - const right = this.parseBinary(precedence + 1) - - if (token.value === "&&" || token.value === "||" || token.value === "??") { - left = { - type: "Logical", - operator: token.value, - left, - right, - span: { start: left.span.start, end: right.span.end }, - } - } else { - left = { - type: "Binary", - operator: token.value as never, - left, - right, - span: { start: left.span.start, end: right.span.end }, - } - } - } - - return left - } - - private parseUnary(): ExpressionNode { - const token = this.peek() - if (token.type === "operator" && (token.value === "-" || token.value === "+" || token.value === "!")) { - this.next() - const argument = this.parseUnary() - return { - type: "Unary", - operator: token.value as "-" | "+" | "!", - argument, - span: { start: token.start, end: argument.span.end }, - } - } - return this.parsePostfix() - } - - /** 后缀:成员访问、下标、函数调用。 */ - private parsePostfix(): ExpressionNode { - let node = this.parsePrimary() - - for (;;) { - const token = this.peek() - - if (token.type === "punctuation" && token.value === ".") { - this.next() - const prop = this.peek() - if (prop.type !== "identifier") { - this.fail("成员访问的右侧必须是标识符", { start: prop.start, end: prop.end }) - } - this.next() - node = { - type: "Member", - object: node, - property: prop.value, - span: { start: node.span.start, end: prop.end }, - } - continue - } - - if (token.type === "punctuation" && token.value === "[") { - this.next() - const index = this.parseConditional() - const close = this.peek() - if (!(close.type === "punctuation" && close.value === "]")) { - this.fail('下标访问缺少 "]"', { start: close.start, end: close.end }) - } - this.next() - node = { - type: "Index", - object: node, - index, - span: { start: node.span.start, end: close.end }, - } - continue - } - - // 调用只允许直接调用具名函数:foo(...),不支持 obj.method(...) - if (token.type === "punctuation" && token.value === "(" && node.type === "Identifier") { - this.next() - const args: ExpressionNode[] = [] - if (!(this.peek().type === "punctuation" && this.peek().value === ")")) { - for (;;) { - args.push(this.parseConditional()) - const sep = this.peek() - if (sep.type === "punctuation" && sep.value === ",") { - this.next() - continue - } - break - } - } - const close = this.peek() - if (!(close.type === "punctuation" && close.value === ")")) { - this.fail('函数调用缺少 ")"', { start: close.start, end: close.end }) - } - this.next() - - // 非白名单函数在解析期就拒绝,避免运行期才暴露 - if (!isAllowedFunctionName(node.name)) { - this.fail(`不允许调用函数 "${node.name}"`, node.span) - } - - node = { - type: "Call", - callee: node.name, - args, - span: { start: node.span.start, end: close.end }, - } - continue - } - - break - } - - return node - } - - private parsePrimary(): ExpressionNode { - const token = this.peek() - - switch (token.type) { - case "number": - this.next() - return { - type: "Literal", - value: token.numberValue!, - span: { start: token.start, end: token.end }, - } - - case "string": - this.next() - return { - type: "Literal", - value: token.stringValue!, - span: { start: token.start, end: token.end }, - } - - case "boolean": - this.next() - return { - type: "Literal", - value: token.value === "true", - span: { start: token.start, end: token.end }, - } - - case "null": - this.next() - return { - type: "Literal", - value: null, - span: { start: token.start, end: token.end }, - } - - case "identifier": - this.next() - if (token.value === "undefined") { - return { - type: "Literal", - value: null, - span: { start: token.start, end: token.end }, - } - } - return { - type: "Identifier", - name: token.value, - span: { start: token.start, end: token.end }, - } - - case "punctuation": - if (token.value === "(") { - this.next() - const inner = this.parseConditional() - const close = this.peek() - if (!(close.type === "punctuation" && close.value === ")")) { - this.fail('括号未闭合', { start: close.start, end: close.end }) - } - this.next() - return inner - } - break - - case "eof": - this.fail("表达式意外结束", { start: token.start, end: token.end }) - break - } - - this.fail(`意外的 token "${token.value}"`, { start: token.start, end: token.end }) - } -} - -class ParseFailure extends Error { - readonly span: SourceSpan - constructor(message: string, span: SourceSpan) { - super(message) - this.name = "ParseFailure" - this.span = span - } -} - -/** - * 允许调用的函数白名单。 - * - * 与 builtins 的实现保持同步;解析期即拒绝未登记函数, - * 使非法表达式在任何求值之前就失败。 - */ -const ALLOWED_FUNCTIONS = new Set([ - "if", - "and", - "or", - "not", - "concat", - "format", - "round", - "floor", - "ceil", - "abs", - "min", - "max", - "len", - "upper", - "lower", - "trim", - "substr", - "replace", - "isnull", - "coalesce", - "number", - "string", - "date", - // 聚合函数(与分组配合使用) - "sum", - "avg", - "count", -]) - -function isAllowedFunctionName(name: string): boolean { - return ALLOWED_FUNCTIONS.has(name) -} - -/** 列出全部受支持的函数名。 */ -export function allowedFunctionNames(): string[] { - return [...ALLOWED_FUNCTIONS].sort() -} - -/** - * 解析表达式为 AST。 - * - * 词法或语法错误时返回 error,不抛异常。 - */ -export function parse(source: string): ParseResult { - const { tokens, error } = tokenize(source) - if (error) { - return { - ast: null, - error: { message: error.message, span: { start: error.start, end: error.end } }, - } - } - if (tokens.length === 1 && tokens[0]!.type === "eof") { - return { ast: null, error: { message: "表达式为空", span: { start: 0, end: 0 } } } - } - return new Parser(tokens).parseExpression() -} - -/** 判断表达式是否可解析。 */ -export function isValidExpression(source: string): boolean { - return parse(source).ast !== null -} diff --git a/code/one-designer/packages/report-expression/src/scope.ts b/code/one-designer/packages/report-expression/src/scope.ts deleted file mode 100644 index 124c4aec..00000000 --- a/code/one-designer/packages/report-expression/src/scope.ts +++ /dev/null @@ -1,101 +0,0 @@ -/** - * 表达式求值作用域(对应设计文档 §10)。 - * - * 作用域根由宿主注入,表达式只能访问这里显式提供的值。 - * 未提供的根名会解析为 undefined 并产生诊断,而不是去查全局对象, - * 因此 `window`、`globalThis`、`process` 这类标识符天然拿不到任何东西。 - */ - -/** 求值作用域。 */ -export interface EvalScope { - /** 当前行数据,对应表达式里的 row。 */ - row?: Record - /** 报表参数,对应 params。 */ - params?: Record - /** 分组值,对应 group。 */ - group?: Record - /** 页面信息,对应 page。 */ - page?: Record - /** 当前行索引(从 0 开始),对应 index。 */ - index?: number - /** 当前行序号(从 1 开始),对应 rownumber。 */ - rowNumber?: number - /** 数据集聚合,对应 dataset。 */ - dataset?: Record - /** 自定义根,供宿主扩展。 */ - extra?: Record -} - -/** 允许作为表达式根名的标识符。 */ -export const SCOPE_ROOTS = [ - "row", - "params", - "group", - "page", - "index", - "rownumber", - "dataset", -] as const - -export type ScopeRoot = (typeof SCOPE_ROOTS)[number] - -/** - * 取作用域根的值。 - * - * 明确只认识白名单根名,其余一律返回 undefined。 - * 这是"受限求值"的第一道闸门。 - */ -export function resolveRoot(scope: EvalScope, name: string): unknown { - switch (name) { - case "row": - return scope.row - case "params": - return scope.params - case "group": - return scope.group - case "page": - return scope.page - case "index": - return scope.index - case "rownumber": - return scope.rowNumber - case "dataset": - return scope.dataset - default: - // 宿主自定义根只允许命中 extra 中真实存在的键 - if (scope.extra && Object.prototype.hasOwnProperty.call(scope.extra, name)) { - return scope.extra[name] - } - return undefined - } -} - -/** - * 安全地读取对象属性。 - * - * 拒绝原型链上的危险键,避免 `row.constructor` / `row.__proto__` - * 这类写法拿到构造函数进而逃逸。 - */ -const FORBIDDEN_KEYS = new Set(["__proto__", "constructor", "prototype"]) - -export function safeGet(target: unknown, key: string): unknown { - if (FORBIDDEN_KEYS.has(key)) return undefined - if (target === null || target === undefined) return undefined - if (typeof target !== "object" && typeof target !== "string") return undefined - - if (typeof target === "string") { - // 字符串只允许按索引取字符,不允许方法调用 - if (key === "length") return target.length - return undefined - } - if (Array.isArray(target)) { - if (key === "length") return target.length - const index = Number(key) - if (Number.isInteger(index) && index >= 0 && index < target.length) { - return target[index] - } - return undefined - } - if (!Object.prototype.hasOwnProperty.call(target, key)) return undefined - return (target as Record)[key] -} diff --git a/code/one-designer/packages/report-expression/src/tokenizer.ts b/code/one-designer/packages/report-expression/src/tokenizer.ts deleted file mode 100644 index f5fd942c..00000000 --- a/code/one-designer/packages/report-expression/src/tokenizer.ts +++ /dev/null @@ -1,292 +0,0 @@ -/** - * 表达式词法单元(对应设计文档 §10)。 - * - * 表达式系统使用受限语法和 AST,不执行任意 JavaScript。 - * 词法层只产出可枚举的 token 类型,任何超出语法范围的字符都直接报错, - * 而不是"忽略后继续",从而杜绝绕过语法检查的可能。 - */ - -export type TokenType = - | "number" - | "string" - | "boolean" - | "null" - | "identifier" - | "operator" - | "punctuation" - | "eof" - -export interface Token { - type: TokenType - /** 原始字面量文本。 */ - value: string - /** 数字 token 的解析结果。 */ - numberValue?: number - /** 字符串 token 的解析结果(已处理转义)。 */ - stringValue?: string - /** 在源串中的起始偏移。 */ - start: number - /** 在源串中的结束偏移(不含)。 */ - end: number - /** 从 0 开始的行号,用于诊断定位。 */ - line: number - /** 从 0 开始的列号。 */ - column: number -} - -/** 词法错误。 */ -export interface TokenizeError { - message: string - start: number - end: number - line: number - column: number -} - -/** 词法分析结果。 */ -export interface TokenizeResult { - tokens: Token[] - error: TokenizeError | null -} - -/** 运算符,按长度降序排列以保证最长匹配(如 >= 优先于 >)。 */ -const OPERATORS = [ - "===", - "!==", - "==", - "!=", - ">=", - "<=", - "&&", - "||", - "??", - "?", - "+", - "-", - "*", - "/", - "%", - ">", - "<", - "!", -] as const - -const PUNCTUATION = ["(", ")", ",", ".", "[", "]", ":"] as const - -/** 保留字:不可作为标识符使用。 */ -export const KEYWORDS = new Set(["true", "false", "null", "undefined", "if", "and", "or", "not"]) - -function isDigit(ch: string): boolean { - return ch >= "0" && ch <= "9" -} - -function isIdentStart(ch: string): boolean { - return ( - (ch >= "a" && ch <= "z") || - (ch >= "A" && ch <= "Z") || - ch === "_" || - ch === "$" || - // 允许中文标识符,便于 params.客户名称 这类写法 - ch.charCodeAt(0) > 0x7f - ) -} - -function isIdentPart(ch: string): boolean { - return isIdentStart(ch) || isDigit(ch) -} - -function isSpace(ch: string): boolean { - return ch === " " || ch === "\t" || ch === "\r" || ch === "\n" -} - -/** - * 词法分析。 - * - * 遇到非法字符立即返回错误,不产出"尽力而为"的 token 流。 - */ -export function tokenize(source: string): TokenizeResult { - const tokens: Token[] = [] - let i = 0 - let line = 0 - let lineStart = 0 - - const position = (index: number): { line: number; column: number } => ({ - line, - column: index - lineStart, - }) - - const fail = (message: string, start: number, end: number): TokenizeResult => { - const pos = position(start) - return { - tokens: [], - error: { message, start, end, line: pos.line, column: pos.column }, - } - } - - while (i < source.length) { - const ch = source[i]! - - if (isSpace(ch)) { - if (ch === "\n") { - line += 1 - lineStart = i + 1 - } - i += 1 - continue - } - - const start = i - const pos = position(start) - - // 数字:123、1.5、.5 不支持(必须写 0.5),避免与成员访问歧义 - if (isDigit(ch)) { - let j = i - while (j < source.length && isDigit(source[j]!)) j += 1 - if (source[j] === ".") { - j += 1 - if (!isDigit(source[j] ?? "")) { - return fail("小数点后必须有数字", start, j) - } - while (j < source.length && isDigit(source[j]!)) j += 1 - } - // 科学计数法 - if (source[j] === "e" || source[j] === "E") { - let k = j + 1 - if (source[k] === "+" || source[k] === "-") k += 1 - if (isDigit(source[k] ?? "")) { - while (k < source.length && isDigit(source[k]!)) k += 1 - j = k - } - } - const raw = source.slice(i, j) - tokens.push({ - type: "number", - value: raw, - numberValue: Number(raw), - start, - end: j, - line: pos.line, - column: pos.column, - }) - i = j - continue - } - - // 字符串:单引号或双引号 - if (ch === '"' || ch === "'") { - const quote = ch - let j = i + 1 - let out = "" - let closed = false - while (j < source.length) { - const c = source[j]! - if (c === "\\") { - const next = source[j + 1] - if (next === undefined) return fail("字符串以转义符结尾", start, j + 1) - switch (next) { - case "n": out += "\n"; break - case "t": out += "\t"; break - case "r": out += "\r"; break - case "\\": out += "\\"; break - case '"': out += '"'; break - case "'": out += "'"; break - default: - // 未知转义一律原样保留反斜杠,避免静默吞掉字符 - out += next - break - } - j += 2 - continue - } - if (c === quote) { - closed = true - j += 1 - break - } - if (c === "\n") { - return fail("字符串字面量不能跨行", start, j) - } - out += c - j += 1 - } - if (!closed) return fail("字符串字面量未闭合", start, source.length) - tokens.push({ - type: "string", - value: source.slice(start, j), - stringValue: out, - start, - end: j, - line: pos.line, - column: pos.column, - }) - i = j - continue - } - - // 标识符 / 关键字 - if (isIdentStart(ch)) { - let j = i - while (j < source.length && isIdentPart(source[j]!)) j += 1 - const raw = source.slice(i, j) - let type: TokenType = "identifier" - if (raw === "true" || raw === "false") type = "boolean" - else if (raw === "null") type = "null" - tokens.push({ - type, - value: raw, - start, - end: j, - line: pos.line, - column: pos.column, - }) - i = j - continue - } - - // 运算符:最长匹配 - const operator = OPERATORS.find((op) => source.startsWith(op, i)) - if (operator) { - const j = i + operator.length - tokens.push({ - type: "operator", - value: operator, - start, - end: j, - line: pos.line, - column: pos.column, - }) - i = j - continue - } - - // 标点 - const punct = PUNCTUATION.find((p) => source.startsWith(p, i)) - if (punct) { - const j = i + punct.length - tokens.push({ - type: "punctuation", - value: punct, - start, - end: j, - line: pos.line, - column: pos.column, - }) - i = j - continue - } - - return fail(`无法识别的字符 "${ch}"`, start, start + 1) - } - - const endPos = position(source.length) - tokens.push({ - type: "eof", - value: "", - start: source.length, - end: source.length, - line: endPos.line, - column: endPos.column, - }) - - return { tokens, error: null } -} diff --git a/code/one-designer/packages/report-expression/tests/aggregate.test.ts b/code/one-designer/packages/report-expression/tests/aggregate.test.ts deleted file mode 100644 index e3ad88a5..00000000 --- a/code/one-designer/packages/report-expression/tests/aggregate.test.ts +++ /dev/null @@ -1,180 +0,0 @@ -/** - * 聚合函数测试(对应设计文档 §16 阶段 3 的"跨页合计"能力基础)。 - * - * 语义约定: - * - 空数组:sum → 0,avg/min/max → null,count → 0 - * - "合计为 0" 与 "没有数据" 是两种不同语义,前者显示 0,后者显示空白 - */ -import { describe, expect, it } from "vitest" -import { evaluateValue } from "../src/evaluator.js" -import type { EvalScope } from "../src/scope.js" - -const scope: EvalScope = { - row: { - amounts: [10, 20, 30], - prices: [1.5, 2.5], - mixed: [1, "abc", 3, null], - empty: [], - names: ["甲", "乙", "丙"], - }, - params: {}, -} - -describe("sum", () => { - it("数组求和", () => { - expect(evaluateValue("sum(row.amounts)", scope)).toBe(60) - }) - - it("空数组返回 0(合计为零应显示 0)", () => { - expect(evaluateValue("sum(row.empty)", scope)).toBe(0) - }) - - it("忽略非数字元素", () => { - expect(evaluateValue("sum(row.mixed)", scope)).toBe(4) - }) - - it("标量视为单元素", () => { - expect(evaluateValue("sum(5)", scope)).toBe(5) - }) - - it("null 返回 0", () => { - expect(evaluateValue("sum(row.nothing)", scope)).toBe(0) - }) - - it("小数求和", () => { - expect(evaluateValue("sum(row.prices)", scope)).toBe(4) - }) - - it("可与其他运算组合", () => { - expect(evaluateValue("sum(row.amounts) * 2", scope)).toBe(120) - }) -}) - -describe("avg", () => { - it("平均值为数字", () => { - expect(evaluateValue("avg(row.amounts)", scope)).toBe(20) - }) - - it("空数组返回 null(无数据应显示空白)", () => { - expect(evaluateValue("avg(row.empty)", scope)).toBeNull() - }) - - it("忽略非数字元素后再平均", () => { - // 1 和 3 是有效数字,'abc' 与 null 被忽略 - expect(evaluateValue("avg(row.mixed)", scope)).toBe(2) - }) - - it("小数的平均值", () => { - expect(evaluateValue("avg(row.prices)", scope)).toBe(2) - }) -}) - -describe("count", () => { - it("统计元素个数", () => { - expect(evaluateValue("count(row.amounts)", scope)).toBe(3) - }) - - it("空数组返回 0", () => { - expect(evaluateValue("count(row.empty)", scope)).toBe(0) - }) - - it("统计非空元素个数", () => { - // mixed = [1, 'abc', 3, null],null 不计入 - expect(evaluateValue("count(row.mixed)", scope)).toBe(3) - }) - - it("无参数返回 0", () => { - expect(evaluateValue("count()", scope)).toBe(0) - }) - - it("标量计为 1", () => { - expect(evaluateValue("count(5)", scope)).toBe(1) - }) - - it("null 计为 0", () => { - expect(evaluateValue("count(row.nothing)", scope)).toBe(0) - }) -}) - -describe("min / max 双形态", () => { - it("多参数形态(标量比较)", () => { - expect(evaluateValue("min(3, 1, 2)", scope)).toBe(1) - expect(evaluateValue("max(3, 1, 2)", scope)).toBe(3) - }) - - it("单参数数组形态(聚合)", () => { - expect(evaluateValue("min(row.amounts)", scope)).toBe(10) - expect(evaluateValue("max(row.amounts)", scope)).toBe(30) - }) - - it("空数组返回 null", () => { - expect(evaluateValue("min(row.empty)", scope)).toBeNull() - expect(evaluateValue("max(row.empty)", scope)).toBeNull() - }) - - it("忽略非数字", () => { - expect(evaluateValue("max(row.mixed)", scope)).toBe(3) - }) - - it("单元素数组与标量结果一致", () => { - expect(evaluateValue("min(5)", scope)).toBe(5) - expect(evaluateValue("min(row.prices)", scope)).toBe(1.5) - }) -}) - -describe("聚合与分组作用域协作", () => { - it("可通过 group 作用域聚合", () => { - const groupScope: EvalScope = { - row: { name: "甲" }, - group: { - key: "华北", - amounts: [100, 200, 300], - count: 3, - }, - params: {}, - } - expect(evaluateValue("sum(group.amounts)", groupScope)).toBe(600) - expect(evaluateValue("avg(group.amounts)", groupScope)).toBe(200) - expect(evaluateValue("group.count", groupScope)).toBe(3) - }) - - it("可通过 dataset 作用域做全表合计", () => { - const datasetScope: EvalScope = { - row: {}, - dataset: { amounts: [1, 2, 3, 4], count: 4 }, - params: {}, - } - expect(evaluateValue("sum(dataset.amounts)", datasetScope)).toBe(10) - }) - - it("聚合结果可被格式化", () => { - const groupScope: EvalScope = { - row: {}, - group: { amounts: [1234.5, 2.25] }, - params: {}, - } - expect(evaluateValue("format(sum(group.amounts), '#,##0.00')", groupScope)).toBe("1,236.75") - }) - - it("空组不产生 NaN", () => { - const groupScope: EvalScope = { row: {}, group: { amounts: [] }, params: {} } - const sum = evaluateValue("sum(group.amounts)", groupScope) - expect(sum).toBe(0) - expect(Number.isNaN(sum as number)).toBe(false) - }) -}) - -describe("聚合函数仍在安全白名单内", () => { - it("sum/avg/count 可调用", () => { - expect(evaluateValue("sum(1)", scope)).toBe(1) - expect(evaluateValue("avg(1)", scope)).toBe(1) - expect(evaluateValue("count(1)", scope)).toBe(1) - }) - - it("未登记的聚合名仍被拒绝", () => { - // median 等未实现,应在解析期就被拒绝 - const scope2: EvalScope = { row: {} } - const result = evaluateValue("median(row.x)", scope2) - expect(result).toBeNull() - }) -}) diff --git a/code/one-designer/packages/report-expression/tests/expression.test.ts b/code/one-designer/packages/report-expression/tests/expression.test.ts deleted file mode 100644 index 0490eb80..00000000 --- a/code/one-designer/packages/report-expression/tests/expression.test.ts +++ /dev/null @@ -1,456 +0,0 @@ -/** - * 表达式安全性测试(对应 §4.2、§10、§14 的"表达式安全性测试")。 - * - * 这是本包最重要的测试:受限求值器必须无法执行任意 JavaScript, - * 也无法通过原型链或作用域外标识符逃逸。 - */ -import { describe, expect, it } from "vitest" -import { parse } from "../src/parser.js" -import { evaluateExpression, evaluateValue, compile, evaluateCompiled } from "../src/evaluator.js" -import { tokenize } from "../src/tokenizer.js" -import type { EvalScope } from "../src/scope.js" - -const scope: EvalScope = { - row: { amount: 100, price: 3, quantity: 4, name: "张三", empty: null }, - params: { tax: 0.1, customerName: "李四" }, - index: 0, - rowNumber: 1, -} - -describe("禁止任意代码执行(§4.2)", () => { - it("不允许调用未登记的函数", () => { - const result = parse("eval('1+1')") - expect(result.ast).toBeNull() - expect(result.error?.message).toContain("不允许调用函数") - }) - - it("eval 在解析期即被拒绝", () => { - expect(parse("eval(\"alert(1)\")").ast).toBeNull() - }) - - it("Function 构造器不可用", () => { - expect(parse("Function('return 1')()").ast).toBeNull() - }) - - it("setTimeout 等宿主 API 不可用", () => { - expect(parse("setTimeout('x', 1)").ast).toBeNull() - }) - - it("require / import 不可用", () => { - expect(parse("require('fs')").ast).toBeNull() - expect(parse("import('fs')").ast).toBeNull() - }) - - it("无法通过 constructor 逃逸", () => { - const value = evaluateValue("row.constructor", scope) - expect(value).toBeUndefined() - }) - - it("无法通过 __proto__ 逃逸", () => { - expect(evaluateValue("row.__proto__", scope)).toBeUndefined() - expect(evaluateValue("row['__proto__']", scope)).toBeUndefined() - }) - - it("无法通过 prototype 逃逸", () => { - expect(evaluateValue("row.prototype", scope)).toBeUndefined() - }) - - it("constructor.constructor 组合逃逸失败", () => { - expect(evaluateValue("row.constructor.constructor", scope)).toBeUndefined() - }) - - it("全局对象标识符解析为 undefined", () => { - for (const name of ["window", "globalThis", "process", "document", "global"]) { - expect(evaluateValue(name, scope)).toBeUndefined() - } - }) - - it("模板字符串语法不被支持", () => { - expect(parse("`${row.amount}`").ast).toBeNull() - }) - - it("箭头函数语法不被支持", () => { - expect(parse("(x) => x").ast).toBeNull() - }) - - it("赋值表达式不被支持", () => { - expect(parse("row.amount = 1").ast).toBeNull() - }) - - it("不支持语句分隔与多表达式", () => { - expect(parse("1; 2").ast).toBeNull() - }) - - it("不支持注释语法", () => { - expect(parse("1 // comment").ast).toBeNull() - }) - - it("不允许成员方法调用", () => { - // row.name.toUpperCase() 中 callee 不是简单标识符,解析失败 - expect(parse("row.name.toUpperCase()").ast).toBeNull() - }) - - it("字符串不提供任何方法", () => { - // "张三" 是两个字符 - expect(evaluateValue("row.name.length", scope)).toBe(2) - expect(evaluateValue("row.name.toUpperCase", scope)).toBeUndefined() - }) - - it("数组不提供任何方法", () => { - const s: EvalScope = { row: { list: [1, 2, 3] } } - expect(evaluateValue("row.list.length", s)).toBe(3) - expect(evaluateValue("row.list.map", s)).toBeUndefined() - }) - - it("new 关键字不被支持", () => { - expect(parse("new Date()").ast).toBeNull() - }) - - it("不支持 this", () => { - expect(evaluateValue("this", scope)).toBeUndefined() - }) -}) - -describe("作用域白名单", () => { - it("只认识约定的根名", () => { - expect(evaluateValue("row.amount", scope)).toBe(100) - expect(evaluateValue("params.tax", scope)).toBe(0.1) - expect(evaluateValue("index", scope)).toBe(0) - expect(evaluateValue("rownumber", scope)).toBe(1) - }) - - it("未知根名返回 undefined", () => { - expect(evaluateValue("nonexistent.field", scope)).toBeUndefined() - }) - - it("extra 中的自定义根可访问", () => { - const s: EvalScope = { extra: { custom: { x: 7 } } } - expect(evaluateValue("custom.x", s)).toBe(7) - }) - - it("extra 的 Object.prototype 属性不可访问", () => { - expect(evaluateValue("toString", { extra: {} })).toBeUndefined() - }) -}) - -describe("tokenizer", () => { - it("识别数字", () => { - const { tokens } = tokenize("1 + 2.5 + 1e3") - const nums = tokens.filter((t) => t.type === "number").map((t) => t.numberValue) - expect(nums).toEqual([1, 2.5, 1000]) - }) - - it("拒绝小数点后无数字", () => { - expect(tokenize("1.").error?.message).toContain("小数点后必须有数字") - }) - - it("识别字符串与转义", () => { - const { tokens } = tokenize("'a\\nb'") - expect(tokens[0]?.stringValue).toBe("a\nb") - }) - - it("拒绝未闭合字符串", () => { - expect(tokenize("'abc").error?.message).toContain("未闭合") - }) - - it("拒绝跨行字符串", () => { - expect(tokenize("'a\nb'").error?.message).toContain("不能跨行") - }) - - it("识别中文标识符", () => { - const { tokens } = tokenize("row.客户名称") - expect(tokens.some((t) => t.value === "客户名称")).toBe(true) - }) - - it("运算符最长匹配", () => { - const { tokens } = tokenize("a >= b") - expect(tokens.some((t) => t.value === ">=")).toBe(true) - }) - - it("拒绝非法字符", () => { - expect(tokenize("a # b").error?.message).toContain("无法识别的字符") - }) - - it("记录行列位置", () => { - const { tokens } = tokenize("a +\n b") - const b = tokens.find((t) => t.value === "b") - expect(b?.line).toBe(1) - expect(b?.column).toBe(2) - }) -}) - -describe("parser 结构与错误", () => { - it("拒绝空表达式", () => { - expect(parse("").error?.message).toContain("表达式为空") - expect(parse(" ").error?.message).toContain("表达式为空") - }) - - it("括号必须闭合", () => { - expect(parse("(1 + 2").error?.message).toContain("未闭合") - }) - - it("三元必须有冒号", () => { - expect(parse("1 ? 2").error?.message).toContain('缺少 ":"') - }) - - it("拒绝多余内容", () => { - expect(parse("1 2").error?.message).toContain("多余内容") - }) - - it("运算符优先级正确", () => { - expect(evaluateValue("1 + 2 * 3", scope)).toBe(7) - expect(evaluateValue("(1 + 2) * 3", scope)).toBe(9) - }) - - it("比较与逻辑优先级正确", () => { - expect(evaluateValue("1 + 1 == 2 && 3 > 1", scope)).toBe(true) - }) - - it("成员访问右侧必须是标识符", () => { - expect(parse("row.1").error?.message).toContain("必须是标识符") - }) - - it("下标必须闭合", () => { - expect(parse("row[0").error?.message).toContain('缺少 "]"') - }) -}) - -describe("运算语义", () => { - it("算术运算", () => { - expect(evaluateValue("row.price * row.quantity", scope)).toBe(12) - expect(evaluateValue("10 / 4", scope)).toBe(2.5) - expect(evaluateValue("10 % 3", scope)).toBe(1) - }) - - it("字符串拼接", () => { - expect(evaluateValue("'a' + 'b'", scope)).toBe("ab") - expect(evaluateValue("row.name + '先生'", scope)).toBe("张三先生") - }) - - it("数字与字符串相加按拼接处理", () => { - expect(evaluateValue("1 + '2'", scope)).toBe("12") - }) - - it("除零返回 null 并产生诊断", () => { - const result = evaluateExpression("1 / 0", { scope }) - expect(result.value).toBeNull() - expect(result.diagnostics.some((d) => d.message.includes("除数为 0"))).toBe(true) - }) - - it("null 参与算术视为 0", () => { - expect(evaluateValue("row.empty + 1", scope)).toBe(1) - }) - - it("空值不产生 NaN", () => { - const result = evaluateExpression("row.empty * 2", { scope }) - expect(Number.isNaN(result.value as number)).toBe(false) - }) - - it("一元运算", () => { - expect(evaluateValue("-5", scope)).toBe(-5) - expect(evaluateValue("!true", scope)).toBe(false) - expect(evaluateValue("!row.empty", scope)).toBe(true) - }) - - it("比较运算", () => { - expect(evaluateValue("2 > 1", scope)).toBe(true) - expect(evaluateValue("'a' < 'b'", scope)).toBe(true) - expect(evaluateValue("2 >= 2", scope)).toBe(true) - }) - - it("相等比较", () => { - expect(evaluateValue("1 == 1", scope)).toBe(true) - expect(evaluateValue("1 == '1'", scope)).toBe(true) - expect(evaluateValue("1 === '1'", scope)).toBe(false) - expect(evaluateValue("null == null", scope)).toBe(true) - }) - - it("逻辑运算短路", () => { - // 右侧会触发除零诊断;短路后不应产生该诊断 - const result = evaluateExpression("false && (1 / 0)", { scope }) - expect(result.diagnostics).toEqual([]) - }) - - it("?? 只在空值时取右侧", () => { - expect(evaluateValue("row.empty ?? 'fallback'", scope)).toBe("fallback") - expect(evaluateValue("row.amount ?? 0", scope)).toBe(100) - }) - - it("三元条件", () => { - expect(evaluateValue("row.amount > 0 ? '有' : '无'", scope)).toBe("有") - expect(evaluateValue("row.amount < 0 ? '有' : '无'", scope)).toBe("无") - }) - - it("嵌套成员访问", () => { - const s: EvalScope = { row: { a: { b: { c: 42 } } } } - expect(evaluateValue("row.a.b.c", s)).toBe(42) - }) - - it("下标访问数组", () => { - const s: EvalScope = { row: { list: [10, 20] } } - expect(evaluateValue("row.list[1]", s)).toBe(20) - expect(evaluateValue("row.list[9]", s)).toBeUndefined() - }) - - it("越界下标返回 undefined 而非报错", () => { - const result = evaluateExpression("row.list[9]", { scope: { row: { list: [1] } } }) - expect(result.diagnostics.filter((d) => d.severity === "error")).toEqual([]) - }) -}) - -describe("内置函数", () => { - it("if 惰性求值,不执行未命中分支", () => { - const result = evaluateExpression("if(true, 1, 1 / 0)", { scope }) - expect(result.value).toBe(1) - expect(result.diagnostics).toEqual([]) - }) - - it("if 命中 else 分支", () => { - expect(evaluateValue("if(false, 'a', 'b')", scope)).toBe("b") - }) - - it("and / or / not", () => { - expect(evaluateValue("and(true, true)", scope)).toBe(true) - expect(evaluateValue("and(true, false)", scope)).toBe(false) - expect(evaluateValue("or(false, true)", scope)).toBe(true) - expect(evaluateValue("not(false)", scope)).toBe(true) - }) - - it("concat", () => { - expect(evaluateValue("concat('a', 'b', 'c')", scope)).toBe("abc") - expect(evaluateValue("concat(row.empty, 'x')", scope)).toBe("x") - }) - - it("round / floor / ceil / abs", () => { - expect(evaluateValue("round(1.234, 2)", scope)).toBe(1.23) - expect(evaluateValue("round(1.5)", scope)).toBe(2) - expect(evaluateValue("floor(1.9)", scope)).toBe(1) - expect(evaluateValue("ceil(1.1)", scope)).toBe(2) - expect(evaluateValue("abs(-3)", scope)).toBe(3) - }) - - it("min / max 忽略非数字", () => { - expect(evaluateValue("min(3, 1, 2)", scope)).toBe(1) - expect(evaluateValue("max(3, 1, 2)", scope)).toBe(3) - expect(evaluateValue("min('a', 5)", scope)).toBe(5) - }) - - it("len / upper / lower / trim", () => { - expect(evaluateValue("len('abc')", scope)).toBe(3) - expect(evaluateValue("upper('ab')", scope)).toBe("AB") - expect(evaluateValue("lower('AB')", scope)).toBe("ab") - expect(evaluateValue("trim(' a ')", scope)).toBe("a") - }) - - it("substr", () => { - expect(evaluateValue("substr('abcdef', 2)", scope)).toBe("cdef") - expect(evaluateValue("substr('abcdef', 2, 3)", scope)).toBe("cde") - }) - - it("replace 只做字面量替换", () => { - expect(evaluateValue("replace('a.b.c', '.', '-')", scope)).toBe("a-b-c") - }) - - it("replace 不接受正则元字符作为模式", () => { - // 正则语义下 '.' 应匹配任意字符,这里必须只匹配字面点 - expect(evaluateValue("replace('abc', '.', 'X')", scope)).toBe("abc") - }) - - it("isnull / coalesce", () => { - expect(evaluateValue("isnull(row.empty)", scope)).toBe(true) - expect(evaluateValue("isnull(row.amount)", scope)).toBe(false) - expect(evaluateValue("coalesce(row.empty, '', 'x')", scope)).toBe("x") - expect(evaluateValue("coalesce(row.amount, 0)", scope)).toBe(100) - }) - - it("number 转失败返回 null 而非 NaN", () => { - expect(evaluateValue("number('12')", scope)).toBe(12) - expect(evaluateValue("number('abc')", scope)).toBeNull() - }) - - it("string 对象不隐式序列化", () => { - expect(evaluateValue("string(row)", scope)).toBe("") - }) - - it("format 日期", () => { - expect(evaluateValue("format('2024-03-05T08:09:10Z', 'YYYY-MM-DD')", scope)).toBe("2024-03-05") - }) - - it("format 数字千分位", () => { - expect(evaluateValue("format(1234567.891, '#,##0.00')", scope)).toBe("1,234,567.89") - }) - - it("format 百分比", () => { - expect(evaluateValue("format(0.1234, '0.0%')", scope)).toBe("12.3%") - }) - - it("format 负数千分位", () => { - expect(evaluateValue("format(-1234.5, '#,##0.00')", scope)).toBe("-1,234.50") - }) - - it("date 返回可序列化的 ISO 字符串", () => { - const value = evaluateValue("date('2024-03-05T08:09:10Z')", scope) - expect(typeof value).toBe("string") - expect(value).toBe("2024-03-05T08:09:10.000Z") - }) - - it("表达式结果永远是纯数据(不含 Date 对象)", () => { - const value = evaluateValue("date('2024-01-01')", scope) - expect(value instanceof Date).toBe(false) - }) -}) - -describe("错误处理(§10 单个字段错误不影响整体)", () => { - it("解析失败返回诊断而非抛异常", () => { - const result = evaluateExpression("1 +", { scope }) - expect(result.value).toBeNull() - expect(result.diagnostics).toHaveLength(1) - expect(result.diagnostics[0]?.code).toBe("expression.parse-error") - }) - - it("诊断携带元素 ID 与路径", () => { - const result = evaluateExpression("1 +", { - scope, - elementId: "el-1", - path: "/sections/1/children/0/binding/expression", - }) - expect(result.diagnostics[0]?.elementId).toBe("el-1") - expect(result.diagnostics[0]?.path).toBe("/sections/1/children/0/binding/expression") - }) - - it("函数内部异常被捕获", () => { - const result = evaluateExpression("round('abc')", { scope }) - expect(result.diagnostics.filter((d) => d.severity === "error")).toEqual([]) - }) - - it("诊断不包含原始表达式外的敏感内容", () => { - const result = evaluateExpression("nosuchfn(1)", { scope }) - expect(result.diagnostics[0]?.message).toBeTruthy() - }) -}) - -describe("编译与缓存", () => { - it("compile 返回可复用的 AST", () => { - const c = compile("row.amount + 1") - expect(c.ast).not.toBeNull() - expect(c.error).toBeNull() - }) - - it("compile 记录解析错误", () => { - const c = compile("1 +") - expect(c.ast).toBeNull() - expect(c.error).toBeTruthy() - }) - - it("evaluateCompiled 复用 AST", () => { - const c = compile("row.amount * 2") - expect(evaluateCompiled(c, { scope }).value).toBe(200) - expect(evaluateCompiled(c, { scope: { row: { amount: 5 } } }).value).toBe(10) - }) - - it("evaluateCompiled 对坏表达式返回诊断", () => { - const result = evaluateCompiled(compile("1 +"), { scope }) - expect(result.value).toBeNull() - expect(result.diagnostics).toHaveLength(1) - }) -}) diff --git a/code/one-designer/packages/report-expression/tsconfig.json b/code/one-designer/packages/report-expression/tsconfig.json deleted file mode 100644 index ae429f46..00000000 --- a/code/one-designer/packages/report-expression/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src" - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist", "tests"] -} diff --git a/code/one-designer/packages/report-expression/tsconfig.test.json b/code/one-designer/packages/report-expression/tsconfig.test.json deleted file mode 100644 index 6cefc694..00000000 --- a/code/one-designer/packages/report-expression/tsconfig.test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "noEmit": true, - "types": ["node", "vitest/globals"] - }, - "include": ["src/**/*.ts", "tests/**/*.ts", "*.config.ts"] -} diff --git a/code/one-designer/packages/report-expression/tsup.config.ts b/code/one-designer/packages/report-expression/tsup.config.ts deleted file mode 100644 index be47bf93..00000000 --- a/code/one-designer/packages/report-expression/tsup.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "tsup" - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["esm", "cjs"], - dts: true, - sourcemap: true, - clean: true, - treeshake: true, - target: "es2022", -}) diff --git a/code/one-designer/packages/report-expression/vitest.config.ts b/code/one-designer/packages/report-expression/vitest.config.ts deleted file mode 100644 index 0af27743..00000000 --- a/code/one-designer/packages/report-expression/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "vitest/config" - -export default defineConfig({ - test: { - include: ["tests/**/*.test.ts"], - environment: "node", - }, -}) diff --git a/code/one-designer/packages/report-layout/README.md b/code/one-designer/packages/report-layout/README.md deleted file mode 100644 index 061a818d..00000000 --- a/code/one-designer/packages/report-layout/README.md +++ /dev/null @@ -1,192 +0,0 @@ -# @report/layout - -元素测量、文本换行、动态高度、明细表展开与分页,产出所有 Renderer 共用的 `LayoutDocument`。 - -> 对应设计文档 §4.3、§9、§3.3。 - -## 定位 - -Layout 负责**尺寸计算、文本测量、换行、表格展开、动态高度、分页**; -Renderer 只负责把 `LayoutDocument` 画成 HTML / SVG / PDF,**绝不重新计算分页**(§3.3)。 - -Layout 通过 `TextMeasurer`、`FontResolver` 接口获得环境能力,**不直接依赖 DOM**(§4.3)。 -因此同一套分页逻辑可以在浏览器、Node 和服务端复用。 - -## 安装与使用 - -```ts -import { createDocument } from "@report/core" -import { layoutDocument, createEstimateMeasurer, createPassthroughFontResolver } from "@report/layout" - -const doc = createDocument({ name: "销售单" }) - -const result = await layoutDocument( - doc, - { data: { ds1: rows }, parameters: { year: 2024 } }, - { - textMeasurer: createEstimateMeasurer(), - fontResolver: createPassthroughFontResolver(), - }, -) - -console.log(result.pageCount) -for (const page of result.pages) { - for (const node of page.nodes) { - console.log(node.id, node.type, node.frame) - } -} -``` - -### Node 侧使用真实字体度量 - -`@report/layout/fonts` 依赖 `node:fs`,因此单独入口,避免浏览器打包被迫引入 Node 内置模块。 - -```ts -import { FontLibrary, createFontMeasurer, findSystemFontSources } from "@report/layout/fonts" -import { layoutDocument } from "@report/layout" - -const library = new FontLibrary() -library.loadAll(findSystemFontSources()) - -const measurer = createFontMeasurer({ - library, - fallbackFamilies: ["SimSun", "SimHei", "Microsoft YaHei"], -}) - -const result = await layoutDocument(doc, context, { - textMeasurer: measurer, - fontResolver: measurer.resolver, -}) -``` - -## 核心概念 - -### LayoutDocument 是唯一的分页真相 - -```ts -interface LayoutDocument { - pages: LayoutPage[] - diagnostics: LayoutDiagnostic[] - pageCount: number -} - -interface LayoutPage { - width: number // mm - height: number // mm - pageNumber: number // 从 1 开始 - nodes: LayoutNode[] - sections: LayoutPageSection[] -} -``` - -所有节点使用**绝对坐标**(mm,原点在页面左上角),Renderer 不需要再做任何层级累加。 - -### 单位约定 - -文档内部统一 mm(§7)。`units.ts` 集中提供换算: - -| 函数 | 说明 | -| --- | --- | -| `mmToPx` / `pxToMm` | 与 Designer 显示层换算(1in = 96px) | -| `mmToPt` / `ptToMm` | 与 PDF 输出边界换算(1in = 72pt) | -| `fontSizeToMm` | 字号 pt → 几何 mm,测量时使用 | - -### 文本换行 - -- 西文按**词**断行,不拆开单词(超长词强制断开并标记 `brokeWords`)。 -- 中文按**字**断行,无需空格分词。 -- 支持**避头点**(`,。)】` 不出现在行首)与**避尾点**(`(【` 不出现在行尾)。 -- 显式换行符保留为硬换行。 - -换行结果完全由注入的 `TextMeasurer` 决定,因此与具体字体环境解耦。 - -### 动态高度 - -`text` 元素内容高于 `frame.height` 时,布局阶段会**自动增高**(§3.3)。 -这是表格 `rowHeightMode: "auto"` 的基础。 - -### 中英混排与字体回退 - -拉丁字体通常不含汉字。度量器按**字符**查找覆盖它的字体: - -``` -"中" 在 Arial 中 → glyphId 0(.notdef)→ 回退到 SimHei → 1.0em -"A" 在 Arial 中 → glyphId 36 → 直接用 Arial → 0.667em -``` - -**关键正确性细节**:字体缺失字符时返回 `.notdef` 字形,而它**本身带有 advance 宽度**。 -若直接返回该宽度,缺字会被静默当成正常字符排版。本实现对此显式返回 `null`, -由调用方按回退字体或兜底宽度处理,并在 `TextMetrics.fallback` 中标记。 - -### 分页 - -- 页眉 / 页脚每页重复,其高度先从可用高度扣除。 -- 明细表产出「表头块 + 每行一个块」的序列,因此**行与行之间可跨页断开,单行不会被拆散**。 -- `repeatHeaderOnEachPage` 控制表头是否每页重复。 -- 页眉 + 页脚高度达到或超过内容区时返回**明确错误诊断**而不是静默产出重叠页面。 -- 单个内容块高于整页时产生 `layout.page-overflow` 警告并让其独占一页(允许溢出)。 - -### 页脚页码占位符 - -页脚文本中的 `{pageNumber}` 与 `{pageCount}` 会在分页完成后替换为实际值, -用于「第 X 页 / 共 Y 页」。 - -## 目录结构 - -``` -src/ -├── units.ts 单位换算 -├── measurer.ts TextMeasurer / FontResolver 接口 + 估算度量器 -├── font-parser.ts TTF/OTF/TTC 字节解析(无文件系统依赖) -├── load-font.ts 字体加载与 FontLibrary(Node) -├── font-measurer.ts 基于真实字体度量的 TextMeasurer -├── system-fonts.ts 系统字体探测 -├── text-wrap.ts 分段、换行、避头尾、动态高度 -├── layout-document.ts LayoutDocument 模型 -├── measure.ts 样式解析、绑定求值、元素测量 -├── table.ts 明细表展开为分页块 -├── paginate.ts 分页引擎 -├── engine.ts Layout Engine 主入口 -├── index.ts 主入口(纯逻辑,无 node:fs) -└── fonts.ts 字体入口(Node) -``` - -## 字体解析说明 - -`font-parser.ts` 自行解析字体二进制,**不依赖 canvas 等原生模块**: - -| 表 | 用途 | -| --- | --- | -| `head` | unitsPerEm(度量归一化基准) | -| `hhea` | numberOfHMetrics、ascender、descender、lineGap | -| `hmtx` | 每个字形的 advanceWidth | -| `cmap` | 字符 → 字形映射(format 4 与 format 12) | -| `maxp` | numGlyphs | -| `name` | 字体族名(用于匹配与诊断) | - -同时支持 `.ttf` / `.otf` 与 `.ttc` 字体集合(按 `fontIndex` 取字体)。 - -## 开发 - -```bash -pnpm build # tsup 打包 -pnpm test # vitest -pnpm typecheck # tsc --noEmit -``` - -## 当前测试覆盖 - -| 测试文件 | 用例数 | 覆盖内容 | -| --- | --- | --- | -| `font.test.ts` | 29 | TTF/TTC 解析、真实字宽、中英回退、缺字检测 | -| `text-wrap.test.ts` | 30 | 分词、按词/按字换行、避头尾、动态高度 | -| `pagination.test.ts` | 28 | 页面几何、单页/多页、页眉页脚重复、Y 分层 | - -合计 **87** 个用例。字体相关用例在缺少系统字体的环境中自动跳过。 - -## 尚未实现 - -- 表达式驱动的分组(`group-header` / `group-footer`)与跨页合计。 -- 容器内嵌套表格的多级拆分。 -- 表格列自动宽度(当前按声明宽度 + 等比压缩)。 -- PDF 输出(属 `report-renderer`,阶段 4)。 diff --git a/code/one-designer/packages/report-layout/package.json b/code/one-designer/packages/report-layout/package.json deleted file mode 100644 index 0730df61..00000000 --- a/code/one-designer/packages/report-layout/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@report/layout", - "version": "0.1.0", - "description": "元素测量、文本换行、动态高度与分页,产出统一的 LayoutDocument", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" - }, - "./fonts": { - "types": "./dist/fonts.d.ts", - "import": "./dist/fonts.js", - "require": "./dist/fonts.cjs" - } - }, - "files": ["dist"], - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit -p tsconfig.test.json" - }, - "dependencies": { - "@report/core": "workspace:*", - "@report/expression": "workspace:*" - }, - "devDependencies": { - "tsup": "^8.3.5", - "typescript": "^5.7.2", - "vitest": "^2.1.8" - } -} diff --git a/code/one-designer/packages/report-layout/src/context.ts b/code/one-designer/packages/report-layout/src/context.ts deleted file mode 100644 index 69046c23..00000000 --- a/code/one-designer/packages/report-layout/src/context.ts +++ /dev/null @@ -1,142 +0,0 @@ -/** - * 运行时数据与布局选项(对应设计文档 §8、§9)。 - * - * 报表文档只保存数据源定义,不保存连接、Token 和本次查询结果。 - * 运行时数据统一通过 RenderContext 注入,数据获取通过 DataProvider 注入。 - */ -import type { - DataProvider, - DatasetDefinition, - Diagnostic, - ReportDocument, - RenderContext, -} from "@report/core" -import { DIAGNOSTIC_CODES } from "@report/core" -import type { FontResolver, TextMeasurer } from "./measurer.js" - -// RenderContext 与 DataProvider 定义在 core(§8),这里只做转发, -// 保证 Designer 与 Layout 使用的是同一份契约。 -export type { RenderContext, DataProvider } - -/** - * 布局选项(§9)。 - * - * textMeasurer / fontResolver 在文档里是必填的。这里放宽为可选是为了支持 - * "无字体环境仍能产出结构正确的 LayoutDocument"(如无字体的 CI): - * 缺省时回退到估算度量器,并产生一条明确诊断。 - * 生产环境应当注入真实度量器,否则分页结果与真实排版存在偏差。 - */ -export interface LayoutOptions { - /** 数据提供器。当 RenderContext.data 缺少某数据集时,用它按需取数。 */ - dataProvider?: DataProvider - /** 文本度量器。缺省时回退到估算度量器并产生诊断。 */ - textMeasurer?: TextMeasurer - /** 字体解析器。缺省时使用直通实现。 */ - fontResolver?: FontResolver - /** - * 文本溢出的容差(mm)。默认 0.01。 - */ - overflowTolerance?: number -} - -/** 创建空的渲染上下文。 */ -export function createRenderContext( - partial: Partial = {}, -): RenderContext { - return { - data: partial.data ?? {}, - parameters: partial.parameters ?? {}, - ...(partial.locale !== undefined ? { locale: partial.locale } :{}), - ...(partial.timezone !== undefined ? { timezone: partial.timezone } :{}), - } -} - -/** - * 解析数据集数据。 - * - * 优先使用 RenderContext 中已注入的数据;缺失时才调用 DataProvider。 - * 两者都没有时返回空数组并产生诊断,而不是抛异常—— - * 数据缺失不应阻止报表渲染(§13)。 - */ -export async function resolveDataset( - dataset: DatasetDefinition, - context: RenderContext, - dataProvider: DataProvider | undefined, - diagnostics: Diagnostic[], -): Promise>> { - const injected = context.data[dataset.id] - if (injected) return injected - - if (dataProvider) { - try { - return await dataProvider.getDataset(dataset, context) - } catch (cause) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.DATA_DATASET_MISSING, - message: `数据集 "${dataset.id}" 取数失败:${(cause as Error).message}`, - }) - return [] - } - } - - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.DATA_DATASET_MISSING, - message: `数据集 "${dataset.id}" 没有可用数据:RenderContext 未注入,且未提供 DataProvider`, - }) - return [] -} - -/** 预先解析文档中所有需要的数据集。 */ -export async function resolveAllDatasets( - document: ReportDocument, - context: RenderContext, - dataProvider: DataProvider | undefined, - diagnostics: Diagnostic[], -): Promise>>> { - const result = new Map>>() - const needed = collectRequiredDatasetIds(document) - - for (const datasetId of needed) { - const dataset = document.datasets[datasetId] - if (!dataset) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.REF_DANGLING_DATASET, - message: `文档引用了不存在的数据集 "${datasetId}"`, - }) - result.set(datasetId, []) - continue - } - result.set(datasetId, await resolveDataset(dataset, context, dataProvider, diagnostics)) - } - return result -} - -/** 收集文档中实际会被用到的数据集 ID(区域与明细表)。 */ -export function collectRequiredDatasetIds(document: ReportDocument): Set { - const ids = new Set() - - const walk = (elements: readonly import("@report/core").ReportElement[]): void => { - for (const element of elements) { - if (element.type === "table") { - const datasetId = (element as { datasetId?: string }).datasetId - if (datasetId) ids.add(datasetId) - const columns = (element as { - columns?: { children?: import("@report/core").ReportElement[] }[] - }).columns - for (const column of columns ?? []) { - if (column.children?.length) walk(column.children) - } - } - if (element.children?.length) walk(element.children) - } - } - - for (const section of document.sections) { - if (section.datasetId) ids.add(section.datasetId) - walk(section.children) - } - return ids -} diff --git a/code/one-designer/packages/report-layout/src/engine.ts b/code/one-designer/packages/report-layout/src/engine.ts deleted file mode 100644 index 34e87b20..00000000 --- a/code/one-designer/packages/report-layout/src/engine.ts +++ /dev/null @@ -1,405 +0,0 @@ -/** - * Layout Engine 主入口(对应设计文档 §9)。 - * - * LayoutEngine.layout(document, context, options) → LayoutDocument - * - * 完整流程: - * 1. 解析运行时数据(RenderContext / DataProvider) - * 2. 逐区域测量(样式解析、绑定求值、文本换行、动态高度) - * 3. 分页(页眉页脚重复、明细表按行拆分) - * 4. 产出统一的 LayoutDocument + 诊断 - * - * 关键约束:本流程不依赖 DOM,也不重新访问网络—— - * 数据来自注入,字体能力来自 TextMeasurer。 - */ -import type { - Diagnostic, - ReportDocument, - ReportSection, -} from "@report/core" -import { DIAGNOSTIC_CODES, isGroupSectionKind, isV1SectionKind } from "@report/core" -import type { EvalScope } from "@report/expression" -import type { FontResolver, TextMeasurer } from "./measurer.js" -import { - createEstimateMeasurer, - createPassthroughFontResolver, -} from "./measurer.js" -import type { RenderContext, LayoutOptions } from "./context.js" -import { - collectRequiredDatasetIds, - resolveAllDatasets, -} from "./context.js" -import type { MeasuredElement } from "./measure.js" -import { - createMeasureContext, - contentHeight, - measureSection, -} from "./measure.js" -import type { LayoutBlock, MeasuredSection } from "./paginate.js" -import { - computePageGeometry, - paginate, - toLayoutNode, - toMeasuredSection, -} from "./paginate.js" -import { buildTableBlocks } from "./table.js" -import type { GroupLevelSpec } from "./group.js" -import { buildGroupBlocks, collectGroupLevels, computeGroups } from "./group.js" -import type { LayoutDocument, LayoutNode } from "./layout-document.js" - -/** - * Layout Engine 契约(§9)。 - * - * 定义在本包而非 core:分页是 layout 的职责,core 不依赖具体布局实现。 - */ -export interface LayoutEngine { - layout( - document: ReportDocument, - context: RenderContext, - options?: LayoutOptions, - ): Promise -} - -/** Layout Engine 实现。 */ -export class DefaultLayoutEngine implements LayoutEngine { - async layout( - document: ReportDocument, - context: RenderContext, - options?: LayoutOptions, - ): Promise { - return layoutDocument(document, context, options) - } -} - -/** 创建 Layout Engine。 */ -export function createLayoutEngine(): LayoutEngine { - return new DefaultLayoutEngine() -} - -/** - * 执行一次完整布局。 - * - * options 省略时使用估算度量器,并产生字体回退诊断—— - * 这保证在没有任何字体能力的环境(如无字体的 CI)里仍能产出结构正确的 - * LayoutDocument,只是文本宽度为估算值。 - */ -export async function layoutDocument( - document: ReportDocument, - context: RenderContext = { data: {}, parameters: {} }, - options?: LayoutOptions, -): Promise { - const diagnostics: Diagnostic[] = [] - - const measurer: TextMeasurer = options?.textMeasurer ?? createEstimateMeasurer() - const fontResolver: FontResolver = options?.fontResolver ?? createPassthroughFontResolver() - - if (!options?.textMeasurer) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.LAYOUT_TEXT_OVERFLOW, - message: - "未提供 TextMeasurer,已回退到估算度量器;文本宽度为估算值," + - "分页结果可能与真实排版存在偏差", - }) - } - - // 1. 解析数据 - const datasets = await resolveAllDatasets( - document, - context, - options?.dataProvider, - diagnostics, - ) - const dataContext: RenderContext = { ...context, data: context.data } - - // 2. 测量各区域 - const geometry = computePageGeometry(document) - const ctx = createMeasureContext({ - document, - renderContext: dataContext, - measurer, - fontResolver, - }) - if (options?.overflowTolerance !== undefined) { - ctx.overflowTolerance = options.overflowTolerance - } - - const measuredSections: MeasuredSection[] = [] - - // 分组级别定义(group-header / group-footer) - const groupLevels = collectGroupLevels(document.sections, diagnostics) - - for (let i = 0; i < document.sections.length; i += 1) { - const section = document.sections[i]! - const path = `/sections/${i}` - const options_ = section.options ?? {} - - // 分组区域由明细区的分组流程消费,不单独成块 - if (isGroupSectionKind(section.kind)) { - continue - } - - if (!isV1SectionKind(section.kind)) { - diagnostics.push({ - severity: "info", - code: DIAGNOSTIC_CODES.ELEMENT_UNKNOWN_TYPE, - message: `区域 "${section.kind}" 不在 V1 渲染范围内,已跳过`, - path: `${path}/kind`, - }) - continue - } - - // 明细表需要按数据集展开成多行,走单独的块构建流程 - if (section.kind === "detail") { - const built = buildDetailSection( - section, - i, - document, - ctx, - datasets, - geometry.contentWidth, - path, - diagnostics, - groupLevels, - ) - measuredSections.push(built) - continue - } - - const scope: EvalScope = { - params: context.parameters, - page: { pageNumber: 1, pageCount: 1 }, - } - const elements = measureSection(section, geometry.contentWidth, ctx, scope, path) - for (const element of elements) diagnostics.push(...element.diagnostics) - - measuredSections.push( - toMeasuredSection({ - sectionId: section.id, - kind: section.kind, - elements, - // 页眉页脚每页重复 - repeatOnEachPage: options_.repeatOnEachPage ?? true, - allowSplit: options_.allowSplit ?? false, - }), - ) - } - - // 3. 分页 - const result = paginate(measuredSections, geometry, { - document, - diagnostics, - allowSplit: true, - }) - - // 4. 回填总页数,便于页脚渲染"第 X 页 / 共 Y 页" - annotatePageCount(result) - - return result -} - -/** 在每页上记录页码信息,供页脚使用。 */ -function annotatePageCount(document: LayoutDocument): void { - for (const page of document.pages) { - for (const node of page.nodes) { - annotateNode(node, page.pageNumber, document.pageCount) - } - } -} - -function annotateNode( - node: import("./layout-document.js").LayoutNode, - pageNumber: number, - pageCount: number, -): void { - if (node.content?.kind === "text") { - // 页脚里常见的 {pageNumber} / {pageCount} 占位符在此替换 - const content = node.content - if (content.lines.some((line) => line.includes("{pageNumber}") || line.includes("{pageCount}"))) { - content.lines = content.lines.map((line) => - line - .replace(/\{pageNumber\}/g, String(pageNumber)) - .replace(/\{pageCount\}/g, String(pageCount)), - ) - content.text = content.lines.join("\n") - } - } - for (const child of node.children ?? []) { - annotateNode(child, pageNumber, pageCount) - } -} - -/** - * 构建明细区域。 - * - * 明细表按数据集展开成表头块 + 每行一个块,从而支持跨页拆分; - * 非表格元素作为普通块处理。 - */ -function buildDetailSection( - section: ReportSection, - sectionIndex: number, - document: ReportDocument, - ctx: ReturnType, - datasets: Map>>, - contentWidth: number, - path: string, - diagnostics: Diagnostic[], - groupLevels: readonly GroupLevelSpec[] = [], -): MeasuredSection { - const tableBlocks: LayoutBlock[] = [] - const staticElements: MeasuredElement[] = [] - let staticHeight = 0 - - for (let i = 0; i < section.children.length; i += 1) { - const element = section.children[i]! - const elementPath = `${path}/children/${i}` - - if (element.type === "table") { - const blocks = buildTableBlocks({ - element, - ctx, - datasets, - parentWidth: contentWidth, - path: elementPath, - diagnostics, - }) - tableBlocks.push(...blocks) - continue - } - - // 非表格元素:在明细区顶部依次排布 - const measured = measureSection( - { ...section, children: [element] }, - contentWidth, - ctx, - { params: {}, page: {} }, - path, - ) - for (const m of measured) { - // 累加垂直偏移,避免多个静态元素重叠 - m.frame.y += staticHeight - staticHeight += m.frame.height - staticElements.push(m) - diagnostics.push(...m.diagnostics) - } - } - - // 静态元素作为首个块,表格块依次跟随 - const blocks: LayoutBlock[] = [] - if (staticElements.length > 0) { - const height = contentHeight(staticElements) - blocks.push({ - height, - render: (top) => staticElements.map((element) => toNode(element, top)), - }) - } - - // 有分组定义时,详细行按组包裹:组头 → 行 → 组脚 - if (groupLevels.length > 0 && tableBlocks.length > 0) { - const groupSource = resolveGroupSource(section, groupLevels) - if (!groupSource) { - blocks.push(...tableBlocks) - } else { - const rows = datasets.get(groupSource.datasetId) ?? [] - if (rows.length === 0) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.DATA_DATASET_MISSING, - message: `分组所依据的数据集 "${groupSource.datasetId}" 没有数据,分组区域将不输出`, - path: `${path}/children/${groupSource.tableIndex}`, - }) - blocks.push(...tableBlocks) - } else { - const tree = computeGroups(rows, groupLevels, diagnostics) - // 表头 / 空数据占位块与数据行块分开: - // 行块带 rowIndex,按行身份选取,不依赖数组下标(避免混入非行块导致错位)。 - // 表头判定用 kind === "header":表头始终存在, - // 只是可能不重复(repeatOnEachPage 为 false)。 - const headerBlocks = tableBlocks.filter((b) => b.kind === "header") - const nonRowBlocks = tableBlocks.filter( - (b) => b.kind !== "header" && b.rowIndex === undefined, - ) - const rowBlocks = tableBlocks.filter((b) => b.rowIndex !== undefined) - - // 表头在最前,空数据占位紧随其后 - if (headerBlocks.length > 0) blocks.push(headerBlocks[0]!) - blocks.push(...nonRowBlocks) - - if (rowBlocks.length === 0) { - // 表格没有产出任何行块(例如无 columns),保持原样输出 - blocks.push(...headerBlocks.slice(1)) - } else { - const grouped = buildGroupBlocks({ - groups: tree.groups, - levels: groupLevels, - ctx, - parentWidth: contentWidth, - sectionPath: path, - diagnostics, - allRows: rows, - // 按数据行索引区间选取块,而不是按下标切片 - buildDetailBlocks: (start, end) => - rowBlocks.filter( - (b) => b.rowIndex !== undefined && b.rowIndex >= start && b.rowIndex < end, - ), - }) - blocks.push(...grouped) - } - } - } - } else { - blocks.push(...tableBlocks) - } - - if (blocks.length === 0) { - return toMeasuredSection({ - sectionId: section.id, - kind: section.kind, - elements: [], - repeatOnEachPage: false, - allowSplit: true, - }) - } - - return { - sectionId: section.id, - kind: section.kind, - elements: staticElements, - height: blocks.reduce((sum, block) => sum + block.height, 0), - repeatOnEachPage: false, - allowSplit: true, - blocks, - } -} - -function toNode(element: MeasuredElement, top: number): LayoutNode { - // 复用 paginate 的转换逻辑,保持坐标处理一致 - return toLayoutNode(element, top) -} - -/** - * 找出分组所依据的数据集。 - * - * 规则:取明细区中第一个带 datasetId 的表格元素。 - * 分组表达式在**该数据集的行**上求值,因此必须先确定数据源。 - * 找不到可用的表格时返回 null,调用方回退为不分组输出。 - */ -function resolveGroupSource( - section: ReportSection, - groupLevels: readonly GroupLevelSpec[], -): { datasetId: string; tableIndex: number } | null { - if (groupLevels.length === 0) return null - - // 区域自身声明了数据集时优先使用 - if (section.datasetId) { - return { datasetId: section.datasetId, tableIndex: -1 } - } - - for (let i = 0; i < section.children.length; i += 1) { - const element = section.children[i]! - if (element.type !== "table") continue - const datasetId = (element as { datasetId?: string }).datasetId - if (datasetId) return { datasetId, tableIndex: i } - } - return null -} diff --git a/code/one-designer/packages/report-layout/src/font-measurer.ts b/code/one-designer/packages/report-layout/src/font-measurer.ts deleted file mode 100644 index 5d832517..00000000 --- a/code/one-designer/packages/report-layout/src/font-measurer.ts +++ /dev/null @@ -1,147 +0,0 @@ -/** - * 基于真实字体度量的文本度量器(对应设计文档 §9)。 - * - * 与 estimate 版度量器的区别:宽度来自字体文件的 advance 表, - * 因此中英混排、比例字体的换行结果与真实排版一致。 - * - * 中英混排策略:按字符逐个查找覆盖它的字体。 - * 拉丁字体通常不含汉字,需要回退到 CJK 字体——这正是 - * "中文字体、长文本"测试(§14)关注的核心场景。 - */ -import type { ResolvedStyle } from "@report/core" -import type { TextMeasurer, TextMetrics, FontResolver, ResolvedFont } from "./measurer.js" -import type { FontLibrary } from "./load-font.js" -import type { ParsedFont } from "./font-parser.js" -import { ptToMm } from "./units.js" - -/** 字体回退事件,供诊断使用。 */ -export interface FontFallbackEvent { - requested: string - resolved: string - codePoint: number - char: string -} - -/** 度量选项。 */ -export interface FontMeasurerOptions { - library: FontLibrary - /** - * 回退字体族列表,按优先级排列。 - * - * 当首选字体不覆盖某字符时按此顺序查找。 - */ - fallbackFamilies?: readonly string[] - /** 当字符在所有字体中都缺失时使用的兜底宽度(em)。默认 0.5。 */ - missingGlyphWidth?: number - /** 回退事件回调,用于收集诊断。 */ - onFallback?: (event: FontFallbackEvent) => void -} - -/** - * 创建基于字体库的度量器。 - * - * 度量单位为 mm,与文档模型保持一致(§7)。 - */ -export function createFontMeasurer(options: FontMeasurerOptions): TextMeasurer & { - resolver: FontResolver -} { - const { library } = options - const fallbackFamilies = options.fallbackFamilies ?? [] - const missingGlyphWidth = options.missingGlyphWidth ?? 0.5 - - const resolveFont = (fontFamily: string): { font: ParsedFont | undefined; family: string; fallback: boolean } => { - const hit = library.resolveStack(fontFamily) - if (hit) return { font: hit.font, family: hit.family, fallback: false } - - // 首选未命中,按回退列表找 - for (const name of fallbackFamilies) { - const font = library.get(name) - if (font) return { font, family: name, fallback: true } - } - // 再退一步:任意可用字体 - const first = library.families()[0] - if (first) { - const font = library.get(first) - if (font) return { font, family: first, fallback: true } - } - return { font: undefined, family: fontFamily, fallback: true } - } - - /** 计算单个字符的宽度(em)。缺失时返回 null。 */ - const charAdvance = ( - codePoint: number, - ch: string, - primary: ParsedFont | undefined, - preferredFamily: string, - ): { advance: number; font: ParsedFont | undefined } | null => { - if (primary?.hasGlyph(codePoint)) { - const adv = primary.charAdvance(codePoint) - if (adv !== null) return { advance: adv, font: primary } - } - - // 主字体不覆盖,查找可回退的字体 - const fallback = library.findForCodePoint(codePoint, fallbackFamilies) - if (fallback) { - const adv = fallback.charAdvance(codePoint) - if (adv !== null) { - options.onFallback?.({ - requested: preferredFamily, - resolved: fallback.metrics.familyName, - codePoint, - char: ch, - }) - return { advance: adv, font: fallback } - } - } - return null - } - - const measurer: TextMeasurer & { resolver: FontResolver } = { - resolver: { - resolve(fontFamily: string): ResolvedFont { - const { family, fallback } = resolveFont(fontFamily) - return { requested: fontFamily, resolved: family, fallback } - }, - }, - - measure(text: string, style: ResolvedStyle): TextMetrics { - const emMm = ptToMm(style.fontSize) - const { font, family, fallback: fontFallback } = resolveFont(style.fontFamily) - - let totalEm = 0 - let usedFallback = fontFallback - let missing = 0 - - for (const ch of text) { - const codePoint = ch.codePointAt(0)! - const hit = charAdvance(codePoint, ch, font, family) - if (hit) { - totalEm += hit.advance - if (hit.font && hit.font !== font) usedFallback = true - } else { - // 所有字体都不覆盖:按兜底宽度计入并标记,避免静默低估宽度 - totalEm += missingGlyphWidth - missing += 1 - usedFallback = true - } - } - - // 字重加粗会导致宽度增加;这里给出保守的 2% 补偿 - if (style.fontWeight === "bold" || (typeof style.fontWeight === "number" && style.fontWeight >= 600)) { - totalEm *= 1.02 - } - - const height = emMm * style.lineHeight - return { - width: totalEm * emMm, - height, - ascent: emMm * 0.8, - descent: emMm * 0.2, - fontFamily: family, - fallback: usedFallback || missing > 0, - } - }, - } - - return measurer -} diff --git a/code/one-designer/packages/report-layout/src/font-parser.ts b/code/one-designer/packages/report-layout/src/font-parser.ts deleted file mode 100644 index 86465e81..00000000 --- a/code/one-designer/packages/report-layout/src/font-parser.ts +++ /dev/null @@ -1,233 +0,0 @@ -/** - * TrueType / OpenType 字体度量解析(对应设计文档 §9)。 - * - * 目的:让 Node / 服务端也具备真实文本度量能力,而不必依赖 canvas 等 - * 原生模块。只解析度量所需的表,不涉及字形轮廓渲染。 - * - * 解析的表: - * - head:unitsPerEm、indexToLocFormat(本实现不需要 loca,但用于确认字体有效) - * - hhea:numberOfHMetrics、ascender、descender、lineGap - * - hmtx:每个字形的 advanceWidth - * - cmap:字符 → 字形映射(优先 format 4,其次 format 12) - * - maxp:numGlyphs - * - name:字体族名(用于 FontResolver 匹配与诊断) - * - * 本模块不依赖 DOM,也不依赖任何原生扩展。 - */ - -/** 解析错误。 */ -export class FontParseError extends Error { - constructor(message: string) { - super(message) - this.name = "FontParseError" - } -} - -/** 字体表目录项。 */ -interface TableRecord { - offset: number - length: number -} - -/** cmap 子表。 */ -interface CmapSubtable { - format: number - offset: number -} - -/** 已解析的字体度量。 */ -export interface FontMetrics { - /** 字体族名,如 "Arial"、"SimHei"。 */ - familyName: string - /** 全名,如 "SimHei Regular"。 */ - fullName: string - /** em 单位数,典型 1000 或 2048。 */ - unitsPerEm: number - /** 字形总数。 */ - numGlyphs: number - /** 整数度量的字形数。 */ - numberOfHMetrics: number - /** 上升部(em 单位)。 */ - ascender: number - /** 下降部(em 单位,通常为负)。 */ - descender: number - /** 行间距(em 单位)。 */ - lineGap: number - /** 源文件路径(若从文件加载)。 */ - source?: string -} - -/** 可查询度量与字形映射的字体对象。 */ -export class ParsedFont { - readonly metrics: FontMetrics - private readonly buffer: Buffer - private readonly base: number - private readonly tables: Map - private readonly cmapFormat4: number - private readonly cmapFormat12: number - - /** 字形宽度缓存:gid → advance(em 单位)。 */ - private readonly advanceCache = new Map() - /** 字符宽度缓存:码点 → advance(em 单位)。 */ - private readonly charCache = new Map() - - constructor(buffer: Buffer, base: number, metrics: FontMetrics, tables: Map) { - this.buffer = buffer - this.base = base - this.metrics = metrics - this.tables = tables - - const cmap = tables.get("cmap") - if (!cmap) throw new FontParseError("字体缺少 cmap 表") - const subtableCount = buffer.readUInt16BE(cmap.offset + 2) - let format4 = -1 - let format12 = -1 - for (let i = 0; i < subtableCount; i += 1) { - const record = cmap.offset + 4 + i * 8 - const platformId = buffer.readUInt16BE(record) - const encodingId = buffer.readUInt16BE(record + 2) - const subtableOffset = cmap.offset + buffer.readUInt32BE(record + 4) - const format = buffer.readUInt16BE(subtableOffset) - - // 优先 Unicode 平台(0)与 Windows BMP(3,1);format 12 覆盖增补平面 - if (format === 12 && (platformId === 0 || platformId === 3)) { - if (format12 < 0) format12 = subtableOffset - } else if (format === 4 && (platformId === 0 || (platformId === 3 && encodingId === 1))) { - if (format4 < 0) format4 = subtableOffset - } - } - if (format4 < 0 && format12 < 0) { - throw new FontParseError("字体缺少受支持的 cmap 子表(format 4 / 12)") - } - this.cmapFormat4 = format4 - this.cmapFormat12 = format12 - } - - /** 查询码点对应的字形 ID;0 表示 .notdef(未覆盖)。 */ - glyphId(codePoint: number): number { - // 增补平面优先用 format 12 - if (codePoint > 0xffff && this.cmapFormat12 >= 0) { - return this.lookupFormat12(codePoint) - } - if (this.cmapFormat4 >= 0) { - const gid = this.lookupFormat4(codePoint) - if (gid !== 0) return gid - } - if (this.cmapFormat12 >= 0) return this.lookupFormat12(codePoint) - return 0 - } - - /** 判断字体是否覆盖某码点。 */ - hasGlyph(codePoint: number): boolean { - if (codePoint === 0x20) return true - return this.glyphId(codePoint) !== 0 - } - - /** 字形 advance 宽度(em 单位)。 */ - advanceOfGlyph(glyphId: number): number { - const cached = this.advanceCache.get(glyphId) - if (cached !== undefined) return cached - - const hmtx = this.tables.get("hmtx") - if (!hmtx) throw new FontParseError("字体缺少 hmtx 表") - - // 超出 numberOfHMetrics 的字形复用最后一个 advance - const index = Math.min(glyphId, this.metrics.numberOfHMetrics - 1) - const offset = hmtx.offset + index * 4 - if (offset + 2 > this.buffer.length) { - this.advanceCache.set(glyphId, 0) - return 0 - } - const advance = this.buffer.readUInt16BE(offset) / this.metrics.unitsPerEm - this.advanceCache.set(glyphId, advance) - return advance - } - - /** - * 字符宽度(em 单位)。 - * - * 未覆盖的字符返回 null,由调用方决定回退策略—— - * 这一点很关键:.notdef 字形本身带有 advance 宽度, - * 若直接返回该宽度会把"缺字"静默当成正常字符渲染。 - */ - charAdvance(codePoint: number): number | null { - const cached = this.charCache.get(codePoint) - if (cached !== undefined) return cached - - const gid = this.glyphId(codePoint) - if (gid === 0 && codePoint !== 0x20 && codePoint !== 0) return null - - const advance = this.advanceOfGlyph(gid) - this.charCache.set(codePoint, advance) - return advance - } - - private lookupFormat4(codePoint: number): number { - if (codePoint > 0xffff) return 0 - const t = this.cmapFormat4 - const segCountX2 = this.buffer.readUInt16BE(t + 6) - const segCount = segCountX2 / 2 - - const endOffset = t + 14 - const startOffset = endOffset + segCountX2 + 2 - const deltaOffset = startOffset + segCountX2 - const rangeOffsetBase = deltaOffset + segCountX2 - - // 二分查找覆盖该码点的段 - let lo = 0 - let hi = segCount - 1 - let segment = -1 - while (lo <= hi) { - const mid = (lo + hi) >> 1 - const end = this.buffer.readUInt16BE(endOffset + mid * 2) - if (codePoint <= end) { - segment = mid - hi = mid - 1 - } else { - lo = mid + 1 - } - } - if (segment < 0) return 0 - - const start = this.buffer.readUInt16BE(startOffset + segment * 2) - if (codePoint < start) return 0 - - const delta = this.buffer.readInt16BE(deltaOffset + segment * 2) - const rangeOffset = this.buffer.readUInt16BE(rangeOffsetBase + segment * 2) - - if (rangeOffset === 0) { - return (codePoint + delta) & 0xffff - } - - const glyphIndexOffset = rangeOffsetBase + segment * 2 + rangeOffset + (codePoint - start) * 2 - if (glyphIndexOffset + 2 > this.buffer.length) return 0 - const glyph = this.buffer.readUInt16BE(glyphIndexOffset) - if (glyph === 0) return 0 - return (glyph + delta) & 0xffff - } - - private lookupFormat12(codePoint: number): number { - const t = this.cmapFormat12 - if (t < 0) return 0 - const nGroups = this.buffer.readUInt32BE(t + 12) - - // 二分查找码点所属分组 - let lo = 0 - let hi = nGroups - 1 - while (lo <= hi) { - const mid = (lo + hi) >> 1 - const group = t + 16 + mid * 12 - const startChar = this.buffer.readUInt32BE(group) - const endChar = this.buffer.readUInt32BE(group + 4) - if (codePoint < startChar) { - hi = mid - 1 - } else if (codePoint > endChar) { - lo = mid + 1 - } else { - const startGlyph = this.buffer.readUInt32BE(group + 8) - return startGlyph + (codePoint - startChar) - } - } - return 0 - } -} diff --git a/code/one-designer/packages/report-layout/src/fonts.ts b/code/one-designer/packages/report-layout/src/fonts.ts deleted file mode 100644 index 48c043e2..00000000 --- a/code/one-designer/packages/report-layout/src/fonts.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @report/layout/fonts —— Node / Electron 侧真实字体度量入口。 - * - * 与主入口分离的原因:这里依赖 node:fs,浏览器打包不应被迫引入 - * Node 内置模块。浏览器侧应由宿主提供 Canvas 版 TextMeasurer。 - * - * 典型用法: - * - * const library = new FontLibrary() - * library.load({ family: "Arial", path: "C:/Windows/Fonts/arial.ttf" }) - * library.load({ family: "SimHei", path: "C:/Windows/Fonts/simhei.ttf" }) - * const measurer = createFontMeasurer({ - * library, - * fallbackFamilies: ["SimHei"], - * }) - * await layoutDocument(doc, ctx, { textMeasurer: measurer, fontResolver: measurer.resolver }) - */ - -// 字体解析 -export type { FontMetrics } from "./font-parser.js" -export { ParsedFont, FontParseError } from "./font-parser.js" - -// 字体加载与库 -export type { FontSource } from "./load-font.js" -export { - FontLibrary, - loadFontFile, - parseFontBuffer, -} from "./load-font.js" - -// 基于真实字体的度量器 -export type { FontMeasurerOptions, FontFallbackEvent } from "./font-measurer.js" -export { createFontMeasurer } from "./font-measurer.js" - -// 常见字体探测辅助 -export { defaultFontSources, findSystemFontSources } from "./system-fonts.js" diff --git a/code/one-designer/packages/report-layout/src/group.ts b/code/one-designer/packages/report-layout/src/group.ts deleted file mode 100644 index faed5874..00000000 --- a/code/one-designer/packages/report-layout/src/group.ts +++ /dev/null @@ -1,367 +0,0 @@ -/** - * 分组展开(对应设计文档 §6.1、§16 阶段 3)。 - * - * 分组语义: - * - 数据集行按 groupExpression 求值,**相邻行值相同**即属于同一组。 - * 这与 SQL 的 ORDER BY + GROUP BY 语义一致:分组不改变行顺序, - * 只按当前顺序切分。因此宿主应先按分组键排序再传入。 - * - 支持多级分组:groupLevel 小的为外层组,嵌套关系为 - * 外层组头 → 内层组头 → 详细行 → 内层组脚 → 外层组脚。 - * - 组脚可聚合该组的行(sum/avg/count),通过 group 作用域访问。 - * - * 跨页处理: - * - 组头默认与组内首行保持在一起(keepTogether),避免组头孤立在页尾。 - * - 组脚同理,不与最后一行分离。 - * - 组的聚合值在**组结束时**才可知,因此组脚块的渲染是延迟求值的。 - */ -import type { Diagnostic, ReportSection } from "@report/core" -import { DIAGNOSTIC_CODES } from "@report/core" -import type { EvalScope } from "@report/expression" -import { compile, evaluateCompiled } from "@report/expression" -import type { LayoutBlock } from "./paginate.js" -import { toLayoutNode } from "./paginate.js" -import type { LayoutNode } from "./layout-document.js" -import type { MeasureContext, MeasuredElement } from "./measure.js" -import { measureElement } from "./measure.js" - -/** 一个分组实例。 */ -export interface GroupInstance { - /** 分组键值。 */ - key: unknown - /** 分组级别(从 1 开始)。 */ - level: number - /** 该组包含的行索引区间 [start, end)。 */ - start: number - end: number - /** 该组对应的行(浅引用)。 */ - rows: ReadonlyArray> - /** 是否是该级别的第一个组。 */ - isFirst: boolean - /** 是否是该级别的最后一个组。 */ - isLast: boolean -} - -/** 分组计算结果。 */ -export interface GroupTree { - /** 按顺序排列的分组实例,按 level 从小到大、再按出现顺序。 */ - groups: GroupInstance[] - /** 分组过程中产生的诊断。 */ - diagnostics: Diagnostic[] -} - -/** 单级分组的描述。 */ -export interface GroupLevelSpec { - level: number - expression: string - headerSection?: ReportSection - footerSection?: ReportSection -} - -/** - * 计算分组树。 - * - * 只做"按相邻行切分",不排序——排序是宿主的职责, - * 因为 core/layout 不应假设数据来源是否可排序。 - */ -export function computeGroups( - rows: ReadonlyArray>, - levels: readonly GroupLevelSpec[], - diagnostics: Diagnostic[], -): GroupTree { - const groups: GroupInstance[] = [] - - if (levels.length === 0 || rows.length === 0) { - return { groups, diagnostics } - } - - // 外层到内层依次切分:每一层的分组区间是父区间的细分 - for (const spec of [...levels].sort((a, b) => a.level - b.level)) { - const compiled = compile(spec.expression) - if (!compiled.ast) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.EXPRESSION_PARSE_ERROR, - message: `分组表达式解析失败:${compiled.error ?? "未知错误"}(${spec.expression})`, - }) - continue - } - - const boundaries: { key: unknown; start: number }[] = [] - let previousKey: unknown = Symbol("init") - let hasPrevious = false - - for (let index = 0; index < rows.length; index += 1) { - const row = rows[index]! - const scope: EvalScope = { row, index, rowNumber: index + 1 } - const { value } = evaluateCompiled(compiled, { scope }) - - // 相邻值相同则并入上一组;首个行无条件开组 - if (!hasPrevious || !isSameGroupKey(previousKey, value)) { - boundaries.push({ key: value, start: index }) - previousKey = value - hasPrevious = true - } - } - - boundaries.forEach((boundary, i) => { - const next = boundaries[i + 1] - groups.push({ - key: boundary.key, - level: spec.level, - start: boundary.start, - end: next ? next.start : rows.length, - rows: rows.slice(boundary.start, next ? next.start : rows.length), - isFirst: i === 0, - isLast: i === boundaries.length - 1, - }) - }) - } - - // 排序:先按出现位置,再按 level,保证组头/组脚按嵌套顺序输出 - groups.sort((a, b) => (a.start - b.start) || (a.level - b.level)) - return { groups, diagnostics } -} - -/** 判断两个分组键是否属于同一组。 */ -export function isSameGroupKey(a: unknown, b: unknown): boolean { - if (a === b) return true - if (a === null || a === undefined) return b === null || b === undefined - if (b === null || b === undefined) return false - // 数字与字符串混合时按字符串比较,避免 1 与 "1" 被当成不同组 - return String(a) === String(b) -} - -/** - * 构建分组相关的分页块。 - * - * 输出顺序(多级分组时按嵌套展开): - * 每个组:组头块 → 子组头块 → 该组的详细行 → 子组脚块 → 组脚块 - * - * @param groupSections 参与分组的区域(group-header / group-footer) - * @param detailBlocks 详细行块工厂:给出行的索引区间,返回对应的块 - */ -export function buildGroupBlocks(options: { - groups: readonly GroupInstance[] - levels: readonly GroupLevelSpec[] - ctx: MeasureContext - parentWidth: number - sectionPath: string - diagnostics: Diagnostic[] - /** 生成某一行区间的详细块。 */ - buildDetailBlocks(start: number, end: number): LayoutBlock[] - /** 数据集全部行,用于 dataset 作用域聚合。 */ - allRows: ReadonlyArray> -}): LayoutBlock[] { - const { - groups, - levels, - ctx, - parentWidth, - sectionPath, - diagnostics, - buildDetailBlocks, - allRows, - } = options - - const blocks: LayoutBlock[] = [] - - // 顶层组(level 最小的那批)按 start 顺序遍历,逐组展开 - const topLevel = Math.min(...levels.map((l) => l.level)) - const topGroups = groups.filter((g) => g.level === topLevel) - - for (const group of topGroups) { - emitGroup(group, blocks) - } - - function emitGroup(group: GroupInstance, out: LayoutBlock[]): void { - const headerSpec = levels.find((l) => l.level === group.level && l.headerSection) - const footerSpec = levels.find((l) => l.level === group.level && l.footerSection) - - // 组头 - if (headerSpec?.headerSection) { - const block = buildGroupSectionBlock( - headerSpec.headerSection, - group, - ctx, - parentWidth, - `${sectionPath}/group-header/L${group.level}`, - diagnostics, - allRows, - "header", - ) - if (block) { - // 组头与组内首行不分离;组声明 pageBreakBefore 时每个组独占一页起始 - block.keepWithNext = true - if (headerSpec.headerSection.pageBreakBefore) { - block.pageBreakBefore = true - } - out.push(block) - } - } - - // 内层子组:找出完全落在本组区间内的下一级组 - const childLevel = levels - .map((l) => l.level) - .filter((l) => l > group.level) - .sort((a, b) => a - b)[0] - - if (childLevel !== undefined) { - const children = groups.filter( - (g) => g.level === childLevel && g.start >= group.start && g.end <= group.end, - ) - if (children.length > 0) { - for (const child of children) emitGroup(child, out) - } else { - // 无子组数据时仍输出详细行 - out.push(...buildDetailBlocks(group.start, group.end)) - } - } else { - out.push(...buildDetailBlocks(group.start, group.end)) - } - - // 组脚 - if (footerSpec?.footerSection) { - const block = buildGroupSectionBlock( - footerSpec.footerSection, - group, - ctx, - parentWidth, - `${sectionPath}/group-footer/L${group.level}`, - diagnostics, - allRows, - "footer", - ) - if (block) { - // 组脚与组内末行不分离,避免组脚被单独甩到下一页 - block.keepWithPrevious = true - out.push(block) - } - } - } - - return blocks -} - -/** - * 把一个分组区域转成分页块。 - * - * 组脚需要聚合整组数据,因此这里构造 group 作用域: - * - group.key:分组键 - * - group.rows:该组行数组 - * - group.count:行数 - * - 以及每一列的值数组,便于 sum(group.amounts) 这类写法 - */ -function buildGroupSectionBlock( - section: ReportSection, - group: GroupInstance, - ctx: MeasureContext, - parentWidth: number, - path: string, - diagnostics: Diagnostic[], - allRows: ReadonlyArray>, - role: "header" | "footer", -): LayoutBlock | null { - if (section.children.length === 0) return null - - // 构造聚合列:把每列的值收集成数组 - const columns: Record = {} - for (const row of group.rows) { - for (const [key, value] of Object.entries(row)) { - if (!columns[key]) columns[key] = [] - columns[key]!.push(value) - } - } - - const scope: EvalScope = { - row: group.rows[0] ?? {}, - group: { - key: group.key, - rows: group.rows, - count: group.rows.length, - ...columns, - }, - index: group.start, - rowNumber: group.start + 1, - params: ctx.renderContext.parameters, - dataset: { - rows: allRows, - count: allRows.length, - }, - } - - // 测量该区域的所有元素(此时 group 作用域已就绪,聚合表达式可求值) - const measured = section.children.map((element, i) => { - const m = measureElement(element, parentWidth, ctx, scope, `${path}/children/${i}`) - diagnostics.push(...m.diagnostics) - return m - }) - - let maxBottom = 0 - for (const m of measured) { - const bottom = m.frame.y + m.frame.height - if (bottom > maxBottom) maxBottom = bottom - } - const height = maxBottom - if (height <= 0) return null - - return { - height, - render: (top: number): LayoutNode[] => measured.map((m) => toNode(m, top)), - } -} - -/** 把已测量元素转换为布局节点(复用 paginate 的转换逻辑,保证坐标处理一致)。 */ -function toNode(element: MeasuredElement, top: number): LayoutNode { - return toLayoutNode(element, top) -} - -/** 收集文档中的分组级别定义。 */ -export function collectGroupLevels( - sections: readonly ReportSection[], - diagnostics: Diagnostic[], -): GroupLevelSpec[] { - const byLevel = new Map() - - for (const section of sections) { - if (section.kind !== "group-header" && section.kind !== "group-footer") continue - - if (!section.groupExpression) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.SCHEMA_REQUIRED_MISSING, - message: `区域 "${section.kind}" 缺少 groupExpression,已忽略`, - path: `/sections/${section.id}`, - }) - continue - } - - const level = section.groupLevel ?? 1 - const existing = byLevel.get(level) - if (existing) { - if (section.kind === "group-header") existing.headerSection = section - else existing.footerSection = section - // 同一级别的两处声明必须使用同一表达式,否则分组语义不明确 - if (existing.expression !== section.groupExpression) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.SCHEMA_INVALID, - message: - `分组级别 ${level} 的 group-header 与 group-footer 使用了不同的 ` + - `groupExpression("${existing.expression}" 与 "${section.groupExpression}"),` + - `已以前者为准`, - path: `/sections/${section.id}`, - }) - } - } else { - byLevel.set(level, { - level, - expression: section.groupExpression, - ...(section.kind === "group-header" - ? { headerSection: section } - : { footerSection: section }), - }) - } - } - - return [...byLevel.values()].sort((a, b) => a.level - b.level) -} diff --git a/code/one-designer/packages/report-layout/src/index.ts b/code/one-designer/packages/report-layout/src/index.ts deleted file mode 100644 index 8edbda9b..00000000 --- a/code/one-designer/packages/report-layout/src/index.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @report/layout 公共入口(对应设计文档 §4.3、§9)。 - * - * Layout 负责尺寸计算、文本测量、换行、表格展开、动态高度和分页, - * 产出所有 Renderer 共用的 LayoutDocument。 - * - * 本入口为纯逻辑部分,不接触文件系统。需要 Node 侧真实字体度量时, - * 从 "@report/layout/fonts" 导入。 - */ - -// 中间结果模型 -export type { - LayoutDocument, - LayoutPage, - LayoutPageSection, - LayoutNode, - LayoutNodeRole, - LayoutContent, - LayoutDiagnostic, - TextContent, - ImageContent, - LineContent, - RectContent, - TableContent, - TableRow, - TableCellContent, - TableColumnLayout, -} from "./layout-document.js" -export { - createLayoutDocument, - walkLayoutNodes, - countLayoutNodes, -} from "./layout-document.js" - -// 单位换算 -export { - MM_PER_INCH, - PX_PER_INCH, - PT_PER_INCH, - mmToPx, - pxToMm, - mmToPt, - ptToMm, - ptToPx, - pxToPt, - fontSizeToMm, -} from "./units.js" - -// 环境能力接口 -export type { - TextMeasurer, - TextMetrics, - FontResolver, - ResolvedFont, -} from "./measurer.js" -export { - createEstimateMeasurer, - createPassthroughFontResolver, - estimateCharWidth, -} from "./measurer.js" - -// 文本换行 -export type { WrapOptions, WrapResult } from "./text-wrap.js" -export { - wrapText, - segmentText, - measureTextHeight, - isTextOverflow, - isNoLineStart, - isNoLineEnd, -} from "./text-wrap.js" - -// 运行时上下文 -export type { RenderContext, LayoutOptions } from "./context.js" -export { - createRenderContext, - resolveDataset, - resolveAllDatasets, - collectRequiredDatasetIds, -} from "./context.js" - -// 测量 -export type { MeasuredElement, MeasureContext } from "./measure.js" -export { - createMeasureContext, - measureElement, - measureSection, - contentHeight, - measureInlineText, - resolveElementStyle, -} from "./measure.js" - -// 分页 -export type { - MeasuredSection, - LayoutBlock, - PaginationContext, - PageGeometry, -} from "./paginate.js" -export { - paginate, - computePageGeometry, - renderElements, - toLayoutNode, - toMeasuredSection, - isTextNode, - nodeStyle, -} from "./paginate.js" - -// 明细表展开 -export { - buildTableBlocks, - estimateTableRowsPerPage, - isExpandableTable, - declaredTableWidth, -} from "./table.js" - -// 分组 -export type { GroupInstance, GroupTree, GroupLevelSpec } from "./group.js" -export { - computeGroups, - isSameGroupKey, - buildGroupBlocks, - collectGroupLevels, -} from "./group.js" - -// 引擎 -export type { LayoutEngine } from "./engine.js" -export { - DefaultLayoutEngine, - createLayoutEngine, - layoutDocument, -} from "./engine.js" diff --git a/code/one-designer/packages/report-layout/src/layout-document.ts b/code/one-designer/packages/report-layout/src/layout-document.ts deleted file mode 100644 index 30a76a1e..00000000 --- a/code/one-designer/packages/report-layout/src/layout-document.ts +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Layout 中间结果模型(对应设计文档 §9)。 - * - * LayoutDocument 是所有 Renderer 共用的分页结果:Renderer 只消费它, - * 绝不重新计算分页(§3.3)。 - */ -import type { Diagnostic, Rect, ResolvedStyle } from "@report/core" - -/** 布局诊断。与统一 Diagnostic 同构,便于跨包传递。 */ -export type LayoutDiagnostic = Diagnostic - -/** 布局节点内容。按节点类型区分,Renderer 据此绘制。 */ -export interface TextContent { - kind: "text" - /** 已应用绑定的最终文本。 */ - text: string - /** 换行后的行,已由 Layout 计算完成。 */ - lines: string[] - /** 单行高度(mm)。 */ - lineHeight: number - /** 是否发生了溢出(内容高于 frame)。 */ - overflow: boolean -} - -export interface ImageContent { - kind: "image" - src: string - fit: "contain" | "cover" | "fill" | "none" - /** 原始像素尺寸(若已知)。 */ - naturalWidth?: number - naturalHeight?: number -} - -export interface LineContent { - kind: "line" - direction: "horizontal" | "vertical" - /** 线宽(mm)。 */ - thickness: number -} - -export interface RectContent { - kind: "rect" -} - -/** 明细表内容。 */ -export interface TableContent { - kind: "table" - /** 已展开的行,每行是按列切分后的单元格数据。 */ - rows: TableRow[] - columns: TableColumnLayout[] - /** 本页是否渲染表头。 */ - showHeader: boolean - headerHeight: number - rowHeight: number - showGrid: boolean -} - -export interface TableColumnLayout { - id: string - /** 相对表格左边界的偏移(mm)。 */ - x: number - width: number - align: "left" | "center" | "right" - header?: string -} - -export interface TableRow { - /** 数据集中的行索引(从 0 开始)。 */ - index: number - /** 序号(从 1 开始)。 */ - rowNumber: number - /** 每个单元格已求值的文本。 */ - cells: TableCellContent[] - /** 行高(mm)。 */ - height: number -} - -export interface TableCellContent { - columnId: string - text: string - value?: unknown -} - -/** 节点内容联合类型。 */ -export type LayoutContent = - | TextContent - | ImageContent - | LineContent - | RectContent - | TableContent - -/** 布局节点。 */ -export interface LayoutNode { - /** 对应 ReportElement.id。 */ - id: string - type: string - /** 绝对坐标(mm),原点在页面左上角。 */ - frame: Rect - style: ResolvedStyle - content?: LayoutContent - children?: LayoutNode[] - /** 节点种类,便于 Renderer 快速分派。 */ - role: LayoutNodeRole -} - -/** 节点角色。 */ -export type LayoutNodeRole = - | "element" - | "table-header" - | "table-row" - | "table-cell" - -/** 布局页。 */ -export interface LayoutPage { - /** 页宽(mm)。 */ - width: number - /** 页高(mm)。 */ - height: number - /** 页码(从 1 开始)。 */ - pageNumber: number - nodes: LayoutNode[] - /** 本页来源区域,便于调试与诊断。 */ - sections: LayoutPageSection[] -} - -/** 页面中某个区域的落位信息。 */ -export interface LayoutPageSection { - kind: string - sectionId: string - /** 该区域在本页占用的垂直范围(mm,绝对坐标)。 */ - top: number - bottom: number -} - -/** 布局文档。 */ -export interface LayoutDocument { - pages: LayoutPage[] - diagnostics: LayoutDiagnostic[] - /** 总页数,便于页脚渲染"第 X 页 / 共 Y 页"。 */ - pageCount: number -} - -/** 创建空布局文档。 */ -export function createLayoutDocument( - pages: LayoutPage[] = [], - diagnostics: LayoutDiagnostic[] = [], -): LayoutDocument { - return { pages, diagnostics, pageCount: pages.length } -} - -/** 遍历布局文档的所有节点(含嵌套)。 */ -export function walkLayoutNodes( - document: LayoutDocument, - visit: (node: LayoutNode, page: LayoutPage) => void, -): void { - const walk = (nodes: readonly LayoutNode[], page: LayoutPage): void => { - for (const node of nodes) { - visit(node, page) - if (node.children?.length) walk(node.children, page) - } - } - for (const page of document.pages) walk(page.nodes, page) -} - -/** 统计布局文档中的节点总数。 */ -export function countLayoutNodes(document: LayoutDocument): number { - let count = 0 - walkLayoutNodes(document, () => { - count += 1 - }) - return count -} diff --git a/code/one-designer/packages/report-layout/src/load-font.ts b/code/one-designer/packages/report-layout/src/load-font.ts deleted file mode 100644 index 44cd94a3..00000000 --- a/code/one-designer/packages/report-layout/src/load-font.ts +++ /dev/null @@ -1,253 +0,0 @@ -/** - * 字体加载与字体库(对应设计文档 §9 的 FontResolver)。 - * - * 负责从文件读取 TTF / OTF / TTC,并解析成可查询的 ParsedFont。 - * 与 font-parser.ts 的分工: - * - font-parser.ts:纯字节解析,不接触文件系统,可用于浏览器(配合宿主提供的 buffer)。 - * - load-font.ts:文件加载与字体族匹配,仅在 Node / Electron 主进程使用。 - */ -import { readFileSync, existsSync } from "node:fs" -import { basename, extname } from "node:path" -import { FontParseError, ParsedFont, type FontMetrics } from "./font-parser.js" - -interface TableRecord { - offset: number - length: number -} - -/** 判断 buffer 是否为 TrueType Collection(ttcf)。 */ -function isCollection(buffer: Buffer): boolean { - return ( - buffer.length >= 4 && - buffer[0] === 0x74 && // t - buffer[1] === 0x74 && // t - buffer[2] === 0x63 && // c - buffer[3] === 0x66 // f - ) -} - -/** 读取字体表目录。 */ -function readTables(buffer: Buffer, base: number): Map { - if (base + 12 > buffer.length) { - throw new FontParseError("字体数据不完整,无法读取表目录") - } - const numTables = buffer.readUInt16BE(base + 4) - const tables = new Map() - for (let i = 0; i < numTables; i += 1) { - const record = base + 12 + i * 16 - if (record + 16 > buffer.length) break - const tag = buffer.toString("ascii", record, record + 4) - tables.set(tag, { - offset: buffer.readUInt32BE(record + 8), - length: buffer.readUInt32BE(record + 12), - }) - } - return tables -} - -/** 从 name 表读取名称。 */ -function readName(buffer: Buffer, base: number, tables: Map, nameId: number): string { - const name = tables.get("name") - if (!name) return "" - const count = buffer.readUInt16BE(name.offset + 2) - const stringOffset = name.offset + buffer.readUInt16BE(name.offset + 4) - - for (let i = 0; i < count; i += 1) { - const record = name.offset + 6 + i * 12 - if (record + 12 > buffer.length) break - const platformId = buffer.readUInt16BE(record) - const currentNameId = buffer.readUInt16BE(record + 6) - if (currentNameId !== nameId) continue - - const length = buffer.readUInt16BE(record + 8) - const offset = buffer.readUInt16BE(record + 10) - const start = stringOffset + offset - if (start + length > buffer.length) continue - - if (platformId === 3 || platformId === 0) { - // UTF-16BE:Node 不支持该 encoding,按码元手工解码 - let out = "" - for (let k = 0; k + 1 < length; k += 2) { - out += String.fromCharCode(buffer.readUInt16BE(start + k)) - } - if (out) return out - } else if (platformId === 1) { - let out = "" - for (let k = 0; k < length; k += 1) out += String.fromCharCode(buffer[start + k]!) - if (out) return out - } - } - return "" -} - -/** 从 buffer 解析字体。 */ -export function parseFontBuffer( - buffer: Buffer, - options: { fontIndex?: number; source?: string } = {}, -): ParsedFont { - const { fontIndex = 0, source } = options - - let base = 0 - if (isCollection(buffer)) { - const numFonts = buffer.readUInt32BE(8) - if (fontIndex >= numFonts) { - throw new FontParseError( - `字体集合只有 ${numFonts} 个字体,请求索引 ${fontIndex} 越界`, - ) - } - base = buffer.readUInt32BE(12 + fontIndex * 4) - } - - const tables = readTables(buffer, base) - - const head = tables.get("head") - const hhea = tables.get("hhea") - const maxp = tables.get("maxp") - if (!head) throw new FontParseError("字体缺少 head 表") - if (!hhea) throw new FontParseError("字体缺少 hhea 表") - if (!maxp) throw new FontParseError("字体缺少 maxp 表") - - const unitsPerEm = buffer.readUInt16BE(head.offset + 18) - if (unitsPerEm === 0) throw new FontParseError("字体的 unitsPerEm 为 0,数据无效") - - const metrics: FontMetrics = { - familyName: readName(buffer, base, tables, 1), - fullName: readName(buffer, base, tables, 4), - unitsPerEm, - numGlyphs: buffer.readUInt16BE(maxp.offset + 4), - numberOfHMetrics: buffer.readUInt16BE(hhea.offset + 34), - ascender: buffer.readInt16BE(hhea.offset + 4), - descender: buffer.readInt16BE(hhea.offset + 6), - lineGap: buffer.readInt16BE(hhea.offset + 8), - ...(source !== undefined ? { source } :{}), - } - - if (!metrics.familyName) { - metrics.familyName = source ? basename(source, extname(source)) : "unknown" - } - - return new ParsedFont(buffer, base, metrics, tables) -} - -/** 从文件路径解析字体。 */ -export function loadFontFile( - path: string, - options: { fontIndex?: number } = {}, -): ParsedFont { - if (!existsSync(path)) { - throw new FontParseError(`字体文件不存在:${path}`) - } - const buffer = readFileSync(path) - return parseFontBuffer(buffer, { ...options, source: path }) -} - -/** 字体来源配置。 */ -export interface FontSource { - /** 字体族名(用于匹配 style.fontFamily)。 */ - family: string - /** 文件路径。 */ - path: string - /** TTC 内的索引。 */ - fontIndex?: number -} - -/** 字体库:按族名查找已加载字体。 */ -export class FontLibrary { - private readonly fonts = new Map() - private readonly byPath = new Map() - private readonly failures: { family: string; path: string; message: string }[] = [] - - /** 已成功加载的字体族(小写)。 */ - families(): string[] { - return [...this.fonts.keys()].sort() - } - - /** 加载失败的记录,用于诊断。 */ - loadFailures(): readonly { family: string; path: string; message: string }[] { - return this.failures - } - - /** 注册一个字体对象。 */ - register(family: string, font: ParsedFont): void { - this.fonts.set(family.toLowerCase(), font) - const source = font.metrics.source - if (source) this.byPath.set(source, font) - } - - /** 从文件加载并注册。加载失败时记录而不抛异常,保证宿主仍可继续。 */ - load(source: FontSource): boolean { - try { - const font = loadFontFile(source.path, { - ...(source.fontIndex !== undefined ? { fontIndex: source.fontIndex } :{}), - }) - this.register(source.family, font) - return true - } catch (cause) { - this.failures.push({ - family: source.family, - path: source.path, - message: (cause as Error).message, - }) - return false - } - } - - /** 批量加载。 */ - loadAll(sources: readonly FontSource[]): void { - for (const source of sources) this.load(source) - } - - /** 按族名精确查找(大小写不敏感)。 */ - get(family: string): ParsedFont | undefined { - return this.fonts.get(family.toLowerCase()) - } - - has(family: string): boolean { - return this.fonts.has(family.toLowerCase()) - } - - /** - * 解析字体族,支持 CSS 风格的字体栈。 - * - * 依次尝试栈中每个族名,命中即返回。全部未命中时返回 undefined。 - */ - resolveStack(fontFamily: string): { font: ParsedFont; family: string } | undefined { - const candidates = fontFamily - .split(",") - .map((name) => name.trim().replace(/^["']|["']$/g, "")) - .filter((name) => name.length > 0) - - for (const name of candidates) { - const font = this.get(name) - if (font) return { font, family: name } - } - return undefined - } - - /** - * 查找能覆盖指定字符的字体。 - * - * 这正是中英混排的关键:拉丁字体通常不含汉字, - * 需要按字符回退到 CJK 字体。 - */ - findForCodePoint(codePoint: number, preferred: readonly string[] = []): ParsedFont | undefined { - for (const name of preferred) { - const font = this.get(name) - if (font?.hasGlyph(codePoint)) return font - } - for (const font of this.fonts.values()) { - if (font.hasGlyph(codePoint)) return font - } - return undefined - } - - get size(): number { - return this.fonts.size - } - - clear(): void { - this.fonts.clear() - this.byPath.clear() - this.failures.length = 0 - } -} diff --git a/code/one-designer/packages/report-layout/src/measure.ts b/code/one-designer/packages/report-layout/src/measure.ts deleted file mode 100644 index 27500e07..00000000 --- a/code/one-designer/packages/report-layout/src/measure.ts +++ /dev/null @@ -1,251 +0,0 @@ -/** - * 元素测量(对应设计文档 §3.3、§4.3)。 - * - * 负责把 ReportElement 转成"已确定尺寸"的中间结构: - * 解析样式、求值绑定、计算动态高度。 - * - * 本文件只做测量,不做分页;分页由 paginate.ts 完成。 - * 这样"测量"与"分页"两项职责各自独立可测。 - */ -import type { - DataProvider, - Diagnostic, - Rect, - ReportDocument, - ReportElement, - ReportSection, - ResolvedStyle, - TableElement, -} from "@report/core" -import { - DIAGNOSTIC_CODES, - resolveStyleChain, - isTableElement, - measureTableWidth, -} from "@report/core" -import type { EvalScope } from "@report/expression" -import { ExpressionCache, resolveBinding } from "@report/expression" -import type { FontResolver, TextMeasurer, TextMetrics } from "./measurer.js" -import { wrapText } from "./text-wrap.js" -import type { RenderContext } from "./context.js" - -/** 已测量的元素。 */ -export interface MeasuredElement { - element: ReportElement - style: ResolvedStyle - /** 元素最终尺寸(mm)。动态高度会覆盖原始 frame.height。 */ - frame: Rect - /** 文本内容(text 类型)。 */ - text?: string - /** 换行结果(text 类型)。 */ - wrapped?: { lines: string[]; lineHeight: number; totalHeight: number } - /** 是否发生溢出。 */ - overflow: boolean - children: MeasuredElement[] - diagnostics: Diagnostic[] -} - -/** 测量上下文。 */ -export interface MeasureContext { - document: ReportDocument - renderContext: RenderContext - measurer: TextMeasurer - fontResolver: FontResolver - cache: ExpressionCache - /** 文本溢出的容差(mm),避免浮点误差导致误报。 */ - overflowTolerance: number - diagnostics: Diagnostic[] -} - -/** 创建测量上下文。 */ -export function createMeasureContext(options: { - document: ReportDocument - renderContext: RenderContext - measurer: TextMeasurer - fontResolver: FontResolver -}): MeasureContext { - return { - document: options.document, - renderContext: options.renderContext, - measurer: options.measurer, - fontResolver: options.fontResolver, - cache: new ExpressionCache(), - overflowTolerance: 0.01, - diagnostics: [], - } -} - -/** 解析元素的最终样式(styleId 继承链 + 元素级覆盖)。 */ -export function resolveElementStyle( - element: ReportElement, - document: ReportDocument, - diagnostics: Diagnostic[], -): ResolvedStyle { - const { style, cycle } = resolveStyleChain(element.styleId, document.styles) - if (cycle) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.REF_CYCLE_DETECTED, - message: `样式继承存在循环:${cycle.join(" → ")},已回退到默认样式`, - elementId: element.id, - }) - } - - // 元素级覆盖:style 字段直接覆盖已解析样式的同名字段 - if (!element.style) return style - const merged: ResolvedStyle = { ...style } - const override = element.style - if (typeof override.fontFamily === "string") merged.fontFamily = override.fontFamily - if (typeof override.fontSize === "number") merged.fontSize = override.fontSize - if (typeof override.color === "string") merged.color = override.color - if (typeof override.background === "string") merged.background = override.background - if (override.align === "left" || override.align === "center" || override.align === "right") { - merged.align = override.align - } - if ( - override.verticalAlign === "top" || - override.verticalAlign === "middle" || - override.verticalAlign === "bottom" - ) { - merged.verticalAlign = override.verticalAlign - } - if (typeof override.lineHeight === "number") merged.lineHeight = override.lineHeight - if (typeof override.fontWeight === "number" || typeof override.fontWeight === "string") { - merged.fontWeight = override.fontWeight as ResolvedStyle["fontWeight"] - } - return merged -} - -/** - * 测量单个元素。 - * - * text 元素会根据换行结果计算动态高度;其它类型沿用 frame 尺寸。 - */ -export function measureElement( - element: ReportElement, - parentWidth: number, - ctx: MeasureContext, - scope: EvalScope, - path: string, -): MeasuredElement { - const diagnostics: Diagnostic[] = [] - const style = resolveElementStyle(element, ctx.document, diagnostics) - - // 宽度以 frame 为准;若 frame 宽度为 0,则继承父容器宽度 - const width = element.frame.width > 0 ? element.frame.width : parentWidth - const frame: Rect = { ...element.frame, width } - - const measured: MeasuredElement = { - element, - style, - frame, - overflow: false, - children: [], - diagnostics, - } - - // 文本元素:求值绑定 + 换行 + 动态高度 - if (element.type === "text") { - const binding = element.binding - let text = "" - if (binding && (binding.field || binding.expression)) { - const resolved = resolveBinding(binding, { scope, elementId: element.id, path }, ctx.cache) - text = resolved.text - diagnostics.push(...resolved.diagnostics) - } else { - // 无绑定时取 props.text 作为静态文本 - const literal = element.props?.text - text = typeof literal === "string" ? literal : "" - } - - const innerWidth = Math.max(0, width - style.padding.left - style.padding.right) - const wrapped = wrapText(text, { maxWidth: innerWidth, style, measurer: ctx.measurer }) - - measured.text = text - measured.wrapped = { - lines: wrapped.lines, - lineHeight: wrapped.lineHeight, - totalHeight: wrapped.totalHeight, - } - - // 动态高度:内容高于 frame 时以内容为准(§3.3) - const originalHeight = element.frame.height - if (wrapped.totalHeight > originalHeight + ctx.overflowTolerance) { - measured.frame.height = wrapped.totalHeight + style.padding.top + style.padding.bottom - } else { - measured.overflow = false - } - } - - // 子元素递归测量 - if (element.children?.length) { - for (let i = 0; i < element.children.length; i += 1) { - const child = element.children[i]! - measured.children.push( - measureElement(child, frame.width, ctx, scope, `${path}/children/${i}`), - ) - } - } - - // 明细表的列布局在展开阶段处理,这里只记录总宽度是否超出 - if (isTableElement(element)) { - const tableWidth = measureTableWidth(element as TableElement) - if (tableWidth > width + ctx.overflowTolerance) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.LAYOUT_TEXT_OVERFLOW, - message: `明细表列宽合计 ${tableWidth.toFixed(2)}mm 超出表格宽度 ${width.toFixed(2)}mm`, - elementId: element.id, - path, - }) - } - } - - return measured -} - -/** 测量一个区域的所有顶层元素。 */ -export function measureSection( - section: ReportSection, - contentWidth: number, - ctx: MeasureContext, - scope: EvalScope, - path: string, -): MeasuredElement[] { - return section.children.map((element, index) => - measureElement(element, contentWidth, ctx, scope, `${path}/children/${index}`), - ) -} - -/** - * 计算一组已测量元素的内容高度(mm)。 - * - * 取所有子元素底边的最大值,再加区域内边距。 - * 这决定了页眉/页脚/明细区在分页时占用的垂直空间。 - */ -export function contentHeight(elements: readonly MeasuredElement[], padding = 0): number { - let maxBottom = 0 - for (const element of elements) { - const bottom = element.frame.y + element.frame.height - if (bottom > maxBottom) maxBottom = bottom - } - return maxBottom + padding -} - -/** 测量一段文本,供表格单元格等场景复用。 */ -export function measureInlineText( - text: string, - width: number, - style: ResolvedStyle, - measurer: TextMeasurer, -): TextMetrics { - const result = wrapText(text, { maxWidth: width, style, measurer }) - return { - width: Math.max(...result.widths, 0), - height: result.totalHeight, - ascent: result.lineHeight * 0.8, - descent: result.lineHeight * 0.2, - fontFamily: style.fontFamily, - fallback: false, - } -} diff --git a/code/one-designer/packages/report-layout/src/measurer.ts b/code/one-designer/packages/report-layout/src/measurer.ts deleted file mode 100644 index 51be5951..00000000 --- a/code/one-designer/packages/report-layout/src/measurer.ts +++ /dev/null @@ -1,125 +0,0 @@ -/** - * 环境能力接口(对应设计文档 §9)。 - * - * Layout 通过 TextMeasurer、FontResolver 等接口获得环境能力,不直接依赖 DOM。 - * 这样可以分别适配浏览器、Node 和服务端字体环境,同时让分页逻辑保持独立。 - */ -import type { ResolvedStyle } from "@report/core" - -/** 文本度量结果。 */ -export interface TextMetrics { - /** 文本宽度(mm)。 */ - width: number - /** 单行高度(mm),已含行距。 */ - height: number - /** 基线到顶部的距离(mm)。 */ - ascent: number - /** 基线到底部的距离(mm)。 */ - descent: number - /** 实际参与度量的字体(用于诊断缺失字体)。 */ - fontFamily: string - /** 是否发生了字体回退。 */ - fallback: boolean -} - -/** 已解析的字体信息。 */ -export interface ResolvedFont { - /** 请求的字体族名。 */ - requested: string - /** 实际使用的字体族名。 */ - resolved: string - /** 是否发生了回退。 */ - fallback: boolean -} - -/** - * 文本度量器。 - * - * 浏览器侧通常用 Canvas measureText 实现;Node 侧用 TTF 度量表实现。 - * 度量单位统一为 mm,与文档模型一致。 - */ -export interface TextMeasurer { - measure(text: string, style: ResolvedStyle): TextMetrics -} - -/** 字体解析器。 */ -export interface FontResolver { - resolve(fontFamily: string): ResolvedFont -} - -/** - * 缺省度量器:按字符类别估算宽度。 - * - * 仅在宿主未注入真实度量器时使用,会产生 layout.font-fallback 诊断。 - * 估算规则基于东亚字宽惯例: - * - 全角字符(CJK、全角标点)宽 1.0 em - * - 半角字符宽 0.5 em - * - ASCII 按窄/中等/宽分档,粗略接近常见无衬线字体 - */ -export function createEstimateMeasurer(): TextMeasurer { - return { - measure(text: string, style: ResolvedStyle): TextMetrics { - const emMm = (style.fontSize / 72) * 25.4 - let width = 0 - for (const ch of text) { - width += estimateCharWidth(ch) * emMm - } - const height = emMm * style.lineHeight - return { - width, - height, - ascent: emMm * 0.8, - descent: emMm * 0.2, - fontFamily: style.fontFamily, - fallback: true, - } - }, - } -} - -/** 单个字符的宽度(以 em 为单位)。 */ -export function estimateCharWidth(ch: string): number { - const code = ch.codePointAt(0) ?? 0 - - // 控制字符不占宽 - if (code === 0x09) return 0.5 - - // CJK 统一表意文字、全角标点、假名、谚文:全角 - if ( - (code >= 0x1100 && code <= 0x115f) || - (code >= 0x2e80 && code <= 0xa4cf) || - (code >= 0xac00 && code <= 0xd7a3) || - (code >= 0xf900 && code <= 0xfaff) || - (code >= 0xfe30 && code <= 0xfe6f) || - (code >= 0xff00 && code <= 0xff60) || - (code >= 0xffe0 && code <= 0xffe6) || - (code >= 0x20000 && code <= 0x3fffd) - ) { - return 1.0 - } - - // ASCII 分档 - if (code < 0x80) { - const ch2 = ch - // 窄字符 - if ("iljtfr.,:;'|!()[]`".includes(ch2)) return 0.28 - if ("I".includes(ch2)) return 0.3 - // 宽字符 - if ("MWmw@".includes(ch2)) return 0.88 - if ("ABCDEFGHKNOPQRSTUVXYZ".includes(ch2)) return 0.68 - if (ch2 >= "0" && ch2 <= "9") return 0.556 - return 0.5 - } - - // 其它非 ASCII 按半角估算 - return 0.5 -} - -/** 缺省字体解析器:总是回退。 */ -export function createPassthroughFontResolver(): FontResolver { - return { - resolve(fontFamily: string): ResolvedFont { - return { requested: fontFamily, resolved: fontFamily, fallback: false } - }, - } -} diff --git a/code/one-designer/packages/report-layout/src/paginate.ts b/code/one-designer/packages/report-layout/src/paginate.ts deleted file mode 100644 index 4c6e111f..00000000 --- a/code/one-designer/packages/report-layout/src/paginate.ts +++ /dev/null @@ -1,550 +0,0 @@ -/** - * 分页引擎(对应设计文档 §3.3、§9)。 - * - * 职责:把已测量的内容按页面内容区高度切分到多页,产出统一的 LayoutDocument。 - * - * 设计要点: - * - 分页只在这里做一次,所有 Renderer 消费同一份结果(§3.3)。 - * - 页眉/页脚每页重复;明细区独占中间的垂直空间。 - * - 页脚占用的高度必须先从可用高度中扣除,否则最后一页会溢出。 - * - 分页失败产生诊断而不是抛异常(§13)。 - */ -import type { - Diagnostic, - Rect, - ReportDocument, - ResolvedStyle, -} from "@report/core" -import { DIAGNOSTIC_CODES, resolvePageSize, resolveContentBox } from "@report/core" -import type { - LayoutDocument, - LayoutNode, - LayoutPage, - LayoutPageSection, - TextContent, -} from "./layout-document.js" -import type { MeasuredElement } from "./measure.js" -import { contentHeight } from "./measure.js" - -/** 分页上下文。 */ -export interface PaginationContext { - document: ReportDocument - diagnostics: Diagnostic[] - /** 允许元素跨页拆分(V1 暂不支持,保留接口)。 */ - allowSplit: boolean -} - -/** 页面几何信息。 */ -export interface PageGeometry { - width: number - height: number - contentX: number - contentY: number - contentWidth: number - contentHeight: number -} - -/** 计算页面几何。 */ -export function computePageGeometry(document: ReportDocument): PageGeometry { - const size = resolvePageSize(document.page) - const box = resolveContentBox(document.page) - return { - width: size.width, - height: size.height, - contentX: box.x, - contentY: box.y, - contentWidth: box.width, - contentHeight: box.height, - } -} - -/** 参与分页的已测量区域。 */ -export interface MeasuredSection { - sectionId: string - kind: string - elements: MeasuredElement[] - /** 内容高度(mm)。 */ - height: number - /** 是否每页重复。 */ - repeatOnEachPage: boolean - /** 是否允许跨页拆分。 */ - allowSplit: boolean - /** - * 可拆分的内容块(按行拆分的明细表等)。 - * 存在时优先按块分页,否则整块作为一个不可分单元。 - */ - blocks?: LayoutBlock[] -} - -/** 块种类。 */ -export type LayoutBlockKind = "content" | "header" | "spacer" - -/** 可独立分页的内容块。 */ -export interface LayoutBlock { - /** 块渲染函数:给出在页内的起始 Y,返回布局节点。 */ - render(top: number): LayoutNode[] - /** 块高度(mm)。 */ - height: number - /** - * 块种类。 - * - * "header" 表示这是表头块——它**始终渲染一次**, - * 是否在后续页面重复由 repeatOnEachPage 决定。 - * 这两个概念必须分开:早期实现用一个布尔同时表达两者, - * 导致把"不重复"误当成"不渲染",表头直接消失。 - */ - kind?: LayoutBlockKind - /** 是否在后续每一页重复渲染本块。仅对 header 块有意义。 */ - repeatOnEachPage?: boolean - /** - * 对应的数据行索引(从 0 开始)。 - * - * 明细表为每个数据行产出一个块,这里记录它来自哪一行。 - * 分组需要按**行身份**选取块,而不能依赖数组下标—— - * 因为块数组里还混有表头、空数据占位等非行块, - * 按下标切片会错位,导致行被丢弃或重复输出。 - */ - rowIndex?: number - /** - * 本块必须与**下一个**块保持在同页(组头与组内首行不分离)。 - * - * 分页引擎在填块时若发现本块后紧跟着放不下下一块, - * 会尝试把本块也挪到下一页,避免组头孤立在页尾。 - */ - keepWithNext?: boolean - /** - * 本块必须与**上一个**块保持在同页(组脚与组内末行不分离)。 - * - * 与 keepWithNext 成对出现,二者表达的是同一段不可分关系的两端。 - * 分页引擎据此保证组脚不会被单独甩到下一页。 - */ - keepWithPrevious?: boolean - /** - * 本块之前强制换页(组变更时每个分组独占一页起始)。 - * - * 当本块是某组的首个块且声明了 pageBreakBefore 时, - * 分页引擎会结束当前页并从新页开始输出本组。 - */ - pageBreakBefore?: boolean -} - -/** - * 分页主流程。 - * - * @param sections 已测量并按文档顺序排列的区域 - */ -export function paginate( - sections: readonly MeasuredSection[], - geometry: PageGeometry, - ctx: PaginationContext, -): LayoutDocument { - const pages: LayoutPage[] = [] - const diagnostics: Diagnostic[] = [...ctx.diagnostics] - - // 区分每页重复区域与主体区域 - const repeating = sections.filter((s) => s.repeatOnEachPage && s.kind !== "detail") - const body = sections.filter((s) => !(s.repeatOnEachPage && s.kind !== "detail")) - - const headerHeight = repeating - .filter((s) => s.kind === "page-header") - .reduce((sum, s) => sum + s.height, 0) - const footerHeight = repeating - .filter((s) => s.kind === "page-footer") - .reduce((sum, s) => sum + s.height, 0) - - // 每页可容纳的主体高度:内容区高度 - 页眉 - 页脚 - const bodyPerPage = geometry.contentHeight - headerHeight - footerHeight - - if (bodyPerPage <= 0) { - diagnostics.push({ - severity: "error", - code: DIAGNOSTIC_CODES.LAYOUT_PAGE_OVERFLOW, - message: - `页眉与页脚高度合计 ${(headerHeight + footerHeight).toFixed(2)}mm ` + - `已达到或超过页面内容区高度 ${geometry.contentHeight.toFixed(2)}mm,无法排版主体内容`, - path: "/sections", - }) - return { pages: [], diagnostics, pageCount: 0 } - } - - // 把主体区域摊平成有序的块序列 - const stream = flattenBlocks(body, ctx, diagnostics) - - if (stream.length === 0) { - // 没有任何主体内容,仍产出一页(只有页眉页脚) - pages.push(buildPage(1, repeating, [], geometry, undefined, 0, 0)) - return { pages, diagnostics, pageCount: pages.length } - } - - let cursor = 0 - let pageNumber = 1 - - // 已出现的表头块:翻页时需要在新页顶部重新插入,实现"每页重复表头"。 - // 之前的实现只在注释里提到这一点却没有真正补插,导致表头只出现在第一页。 - const activeHeaders: LayoutBlock[] = [] - let headerHeightTotal = 0 - - while (cursor < stream.length) { - let used = 0 - const pageBlocks: LayoutBlock[] = [] - let lastSection: { sectionId: string; kind: string } | undefined - - // 非首页时补插表头;首页由流中的首个表头块自然带入。 - // 补插的表头也要占用高度,否则本页主体会溢出 headerHeightTotal。 - if (pageNumber > 1 && activeHeaders.length > 0) { - pageBlocks.push(...activeHeaders) - used += headerHeightTotal - } - - while (cursor < stream.length) { - const item = stream[cursor]! - const blockHeight = item.block.height - - // 块比整页还高:无法容纳,记录诊断并单独占一页(允许溢出) - if (blockHeight > bodyPerPage) { - if (pageBlocks.length === 0) { - pageBlocks.push(item.block) - lastSection = { sectionId: item.sectionId, kind: item.sectionKind } - cursor += 1 - used = blockHeight - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.LAYOUT_PAGE_OVERFLOW, - message: - `内容块高度 ${blockHeight.toFixed(2)}mm 超过单页可排高度 ` + - `${bodyPerPage.toFixed(2)}mm,该块将溢出页面`, - elementId: item.blockId, - }) - } - break - } - - // 组变更强制换页:本块(非表头/非本页首块)声明了 pageBreakBefore 时, - // 结束当前页,从新页开始输出本组。 - if (item.block.pageBreakBefore && pageBlocks.length > 0 && !hasOnlyHeaders(pageBlocks)) { - break - } - - // 组头与首行不分离(keepWithNext):放入本块前,预判下一块是否放得下。 - // 若放不下且当前页已有普通内容,则本块不进本页,留给下一页一起输出。 - if (item.block.keepWithNext) { - const nextItem = stream[cursor + 1] - if (nextItem) { - const nextHeight = nextItem.block.height - if ( - nextHeight <= bodyPerPage && - used + blockHeight + nextHeight > bodyPerPage + 1e-6 && - !hasOnlyHeaders(pageBlocks) - ) { - break - } - } - } - - // 组脚与末行不分离(keepWithPrevious):本块放不下当前页时, - // 回退本页最后一个普通块,让组脚与它同页输出。 - if (item.block.keepWithPrevious) { - if (used + blockHeight > bodyPerPage + 1e-6) { - const rollback = popLastOrdinaryBlock(pageBlocks) - if (rollback) { - used -= rollback.height - cursor -= 1 - } - break - } - } - - if (used + blockHeight > bodyPerPage + 1e-6) break - - pageBlocks.push(item.block) - lastSection = { sectionId: item.sectionId, kind: item.sectionKind } - used += blockHeight - cursor += 1 - - // 表头块本身始终渲染一次;只有声明了 repeatOnEachPage 才在后续页面补插 - if (item.block.kind === "header") { - if (item.block.repeatOnEachPage !== false) { - if (!activeHeaders.includes(item.block)) { - activeHeaders.push(item.block) - headerHeightTotal += item.block.height - } - } - continue - } - } - - pages.push( - buildPage( - pageNumber, - repeating, - pageBlocks, - geometry, - lastSection, - headerHeight, - footerHeight, - ), - ) - pageNumber += 1 - - if (pageBlocks.length === 0) { - // 防御:避免死循环 - diagnostics.push({ - severity: "error", - code: DIAGNOSTIC_CODES.LAYOUT_PAGE_OVERFLOW, - message: "分页未能推进,已中止以避免死循环", - }) - break - } - } - - return { pages, diagnostics, pageCount: pages.length } -} - -/** - * 判断当前页是否只有表头(或空)。 - * - * keepWithNext / pageBreakBefore 的分页回退只在"页上已有普通内容"时才需要; - * 若当前页只有表头(或尚无任何块),把组头放进来是安全的——它不会孤立, - * 因为组头本就需要与后续内容同页,而本页还有空间。 - */ -function hasOnlyHeaders(blocks: readonly LayoutBlock[]): boolean { - return blocks.every((block) => block.kind === "header") -} - -/** - * 从当前页的块列表中弹出最后一个"普通块"(非表头),并返回它。 - * - * 用于 keepWithPrevious(组脚与末行不分离):组脚放不下当前页时, - * 把上一块一起挪到下一页,保证组脚与它绑定的内容同页。 - * 返回 null 表示没有可回退的普通块(例如页上只有表头)。 - */ -function popLastOrdinaryBlock(blocks: LayoutBlock[]): LayoutBlock | null { - for (let i = blocks.length - 1; i >= 0; i -= 1) { - const block = blocks[i]! - if (block.kind !== "header") { - return blocks.splice(i, 1)[0] ?? null - } - } - return null -} - -/** 展平后的流项。 */ -interface StreamItem { - block: LayoutBlock - sectionId: string - sectionKind: string - blockId: string -} - -/** - * 把主体区域展平成有序块序列。 - * - * 不可拆分的区域整体作为一个块;可拆分区域按其 blocks 展开。 - */ -function flattenBlocks( - sections: readonly MeasuredSection[], - ctx: PaginationContext, - diagnostics: Diagnostic[], -): StreamItem[] { - const stream: StreamItem[] = [] - - for (const section of sections) { - if (section.blocks && section.blocks.length > 0) { - for (let i = 0; i < section.blocks.length; i += 1) { - const block = section.blocks[i]! - stream.push({ - block, - sectionId: section.sectionId, - sectionKind: section.kind, - blockId: `${section.sectionId}#${i}`, - }) - } - continue - } - - // 整块不可分:用一个渲染函数统一产出该区域的所有节点 - const elements = section.elements - const height = section.height - if (height <= 0 && elements.length === 0) continue - - if (!section.allowSplit && height > 0) { - // 不可拆分区域,作为单块 - } else if (height <= 0) { - continue - } - - stream.push({ - block: { - height, - render: (top: number) => renderElements(elements, top), - }, - sectionId: section.sectionId, - sectionKind: section.kind, - blockId: section.sectionId, - }) - - if (!section.allowSplit) continue - } - - return stream -} - -/** - * 把已测量元素转成布局节点(绝对坐标)。 - * - * @param top 该块在本页的起始 Y(绝对 mm) - */ -export function renderElements(elements: readonly MeasuredElement[], top: number): LayoutNode[] { - return elements.map((element) => toLayoutNode(element, top)) -} - -/** 把单个已测量元素转为布局节点。 */ -export function toLayoutNode(element: MeasuredElement, offsetY: number): LayoutNode { - const frame: Rect = { - x: element.frame.x, - y: element.frame.y + offsetY, - width: element.frame.width, - height: element.frame.height, - } - - const node: LayoutNode = { - id: element.element.id, - type: element.element.type, - frame, - style: element.style, - role: "element", - } - - // 内容按类型产出,Renderer 只负责画,不再计算 - if (element.element.type === "text" && element.wrapped) { - const content: TextContent = { - kind: "text", - text: element.text ?? "", - lines: element.wrapped.lines, - lineHeight: element.wrapped.lineHeight, - overflow: false, - } - node.content = content - } else if (element.element.type === "rect") { - node.content = { kind: "rect" } - } else if (element.element.type === "line") { - const direction = - (element.element.props?.direction as "horizontal" | "vertical" | undefined) ?? "horizontal" - const thickness = - (element.element.props?.thickness as number | undefined) ?? Math.max(0.1, element.frame.height) - node.content = { kind: "line", direction, thickness } - } else if (element.element.type === "image") { - node.content = { - kind: "image", - src: (element.element.props?.src as string | undefined) ?? "", - fit: (element.element.props?.fit as "contain" | "cover" | "fill" | "none" | undefined) ?? "contain", - } - } - - if (element.children.length > 0) { - node.children = element.children.map((child) => toLayoutNode(child, offsetY)) - } - - return node -} - -/** 构建一页。 */ -function buildPage( - pageNumber: number, - repeating: readonly MeasuredSection[], - blocks: readonly LayoutBlock[], - geometry: PageGeometry, - lastSection: { sectionId: string; kind: string } | undefined, - headerHeight: number, - footerHeight: number, -): LayoutPage { - const nodes: LayoutNode[] = [] - const sections: LayoutPageSection[] = [] - - // 页眉 - let cursorY = geometry.contentY - for (const section of repeating.filter((s) => s.kind === "page-header")) { - const rendered = renderElements(section.elements, cursorY) - nodes.push(...rendered) - sections.push({ - kind: section.kind, - sectionId: section.sectionId, - top: cursorY, - bottom: cursorY + section.height, - }) - cursorY += section.height - } - - // 主体 - const bodyTop = cursorY - const bodyBottom = geometry.contentY + geometry.contentHeight - footerHeight - let bodyCursor = bodyTop - - for (const block of blocks) { - const rendered = block.render(bodyCursor) - nodes.push(...rendered) - bodyCursor += block.height - } - - if (lastSection && blocks.length > 0) { - sections.push({ - kind: lastSection.kind, - sectionId: lastSection.sectionId, - top: bodyTop, - bottom: Math.min(bodyCursor, bodyBottom), - }) - } - - // 页脚:贴着内容区底部 - const footerTop = geometry.contentY + geometry.contentHeight - footerHeight - let footerCursor = footerTop - for (const section of repeating.filter((s) => s.kind === "page-footer")) { - const rendered = renderElements(section.elements, footerCursor) - nodes.push(...rendered) - sections.push({ - kind: section.kind, - sectionId: section.sectionId, - top: footerCursor, - bottom: footerCursor + section.height, - }) - footerCursor += section.height - } - - return { - width: geometry.width, - height: geometry.height, - pageNumber, - nodes, - sections, - } -} - -/** 计算区域测量高度并包装成可分发结构。 */ -export function toMeasuredSection(options: { - sectionId: string - kind: string - elements: MeasuredElement[] - repeatOnEachPage: boolean - allowSplit: boolean - blocks?: LayoutBlock[] -}): MeasuredSection { - return { - sectionId: options.sectionId, - kind: options.kind, - elements: options.elements, - height: contentHeight(options.elements), - repeatOnEachPage: options.repeatOnEachPage, - allowSplit: options.allowSplit, - ...(options.blocks ? { blocks: options.blocks } :{}), - } -} - -/** 判断布局节点是否为文本。 */ -export function isTextNode(node: LayoutNode): node is LayoutNode & { content: TextContent } { - return node.content?.kind === "text" -} - -/** 取节点的已解析样式(类型收窄辅助)。 */ -export function nodeStyle(node: LayoutNode): ResolvedStyle { - return node.style -} diff --git a/code/one-designer/packages/report-layout/src/system-fonts.ts b/code/one-designer/packages/report-layout/src/system-fonts.ts deleted file mode 100644 index a11d656e..00000000 --- a/code/one-designer/packages/report-layout/src/system-fonts.ts +++ /dev/null @@ -1,122 +0,0 @@ -/** - * 系统字体探测(对应设计文档 §9 的字体环境适配)。 - * - * 目标:在 Node / Electron 环境中给出一份"开箱可用"的字体来源列表, - * 使宿主不必硬编码字体路径。探测不到时静默跳过,由宿主决定是否告警。 - * - * 只做文件存在性判断,不加载字体内容——加载由 FontLibrary 负责。 - */ -import { existsSync } from "node:fs" -import { join } from "node:path" -import type { FontSource } from "./load-font.js" - -/** 一个候选字体:族名 + 相对于字体目录的文件名。 */ -interface FontCandidate { - family: string - file: string - fontIndex?: number -} - -/** - * Windows 候选字体。 - * - * 顺序即优先级:先拉丁字体,再中文回退字体。 - * 中文字体用于中英混排时按字符回退(汉字在拉丁字体里通常缺失)。 - */ -const WINDOWS_CANDIDATES: readonly FontCandidate[] = [ - { family: "Arial", file: "arial.ttf" }, - { family: "Times New Roman", file: "times.ttf" }, - { family: "Courier New", file: "cour.ttf" }, - { family: "Segoe UI", file: "segoeui.ttf" }, - { family: "SimSun", file: "simsun.ttc", fontIndex: 0 }, - { family: "SimHei", file: "simhei.ttf" }, - { family: "Microsoft YaHei", file: "msyh.ttc", fontIndex: 0 }, - { family: "DengXian", file: "Deng.ttf" }, - { family: "KaiTi", file: "simkai.ttf" }, - { family: "FangSong", file: "simfang.ttf" }, -] - -/** Linux 候选字体。 */ -const LINUX_CANDIDATES: readonly FontCandidate[] = [ - { family: "DejaVu Sans", file: "truetype/dejavu/DejaVuSans.ttf" }, - { family: "Liberation Sans", file: "truetype/liberation/LiberationSans-Regular.ttf" }, - { family: "Noto Sans CJK SC", file: "opentype/noto/NotoSansCJK-Regular.ttc", fontIndex: 0 }, - { family: "WenQuanYi Zen Hei", file: "truetype/wqy/wqy-zenhei.ttc", fontIndex: 0 }, -] - -/** macOS 候选字体。 */ -const MAC_CANDIDATES: readonly FontCandidate[] = [ - { family: "Helvetica", file: "Helvetica.ttc", fontIndex: 0 }, - { family: "PingFang SC", file: "PingFang.ttc", fontIndex: 0 }, - { family: "STHeiti", file: "STHeiti Light.ttc", fontIndex: 0 }, - { family: "Songti SC", file: "Songti.ttc", fontIndex: 0 }, -] - -/** 各平台的字体目录。 */ -function fontDirectories(): { dir: string; candidates: readonly FontCandidate[] }[] { - switch (process.platform) { - case "win32": { - const winDir = process.env.WINDIR ?? "C:\\Windows" - return [{ dir: join(winDir, "Fonts"), candidates: WINDOWS_CANDIDATES }] - } - case "darwin": - return [ - { dir: "/System/Library/Fonts", candidates: MAC_CANDIDATES }, - { dir: "/Library/Fonts", candidates: MAC_CANDIDATES }, - ] - default: - return [ - { dir: "/usr/share/fonts", candidates: LINUX_CANDIDATES }, - { dir: "/usr/local/share/fonts", candidates: LINUX_CANDIDATES }, - ] - } -} - -/** - * 探测系统上真实存在的字体。 - * - * @param options.only 只返回这些族名(可选),用于缩小范围 - */ -export function findSystemFontSources(options: { only?: readonly string[] } = {}): FontSource[] { - const wanted = options.only?.map((name) => name.toLowerCase()) - const found: FontSource[] = [] - const seen = new Set() - - for (const { dir, candidates } of fontDirectories()) { - for (const candidate of candidates) { - const key = candidate.family.toLowerCase() - if (seen.has(key)) continue - if (wanted && !wanted.includes(key)) continue - - const path = join(dir, candidate.file) - if (!existsSync(path)) continue - - seen.add(key) - found.push({ - family: candidate.family, - path, - ...(candidate.fontIndex !== undefined ? { fontIndex: candidate.fontIndex } :{}), - }) - } - } - - return found -} - -/** - * 默认字体来源。 - * - * 与 findSystemFontSources 相同,但名字更直白,适合直接传给 FontLibrary.loadAll。 - */ -export function defaultFontSources(): FontSource[] { - return findSystemFontSources() -} - -/** - * 推荐的字体回退链。 - * - * 中英混排时按此顺序查找能覆盖字符的字体。 - */ -export function recommendedFallbackFamilies(): string[] { - return ["SimSun", "SimHei", "Microsoft YaHei", "DengXian", "Noto Sans CJK SC", "WenQuanYi Zen Hei", "PingFang SC", "Songti SC"] -} diff --git a/code/one-designer/packages/report-layout/src/table.ts b/code/one-designer/packages/report-layout/src/table.ts deleted file mode 100644 index 49235a47..00000000 --- a/code/one-designer/packages/report-layout/src/table.ts +++ /dev/null @@ -1,308 +0,0 @@ -/** - * 明细表展开(对应设计文档 §6.3 与 §3.3 的"表格展开"职责)。 - * - * 明细表是 V1 的特殊元素,负责把数据集展开成多行。单元格内的元素坐标 - * 相对于当前单元格。 - * - * 分页配合方式:产出"表头块 + 每行一个块"的块序列, - * 这样分页时行与行之间可以断开,而单行不会被拆散。 - */ -import type { Diagnostic, ReportElement, TableColumn, TableElement } from "@report/core" -import { DIAGNOSTIC_CODES, measureTableWidth } from "@report/core" -import type { EvalScope } from "@report/expression" -import { resolveBinding } from "@report/expression" -import type { LayoutBlock } from "./paginate.js" -import type { LayoutNode, TableColumnLayout, TableContent, TableRow } from "./layout-document.js" -import type { MeasureContext } from "./measure.js" -import { resolveElementStyle, measureElement } from "./measure.js" -import { wrapText } from "./text-wrap.js" - -/** 构建明细表的分页块序列。 */ -export function buildTableBlocks(options: { - element: ReportElement - ctx: MeasureContext - datasets: Map>> - parentWidth: number - path: string - diagnostics: Diagnostic[] -}): LayoutBlock[] { - const { element, ctx, datasets, parentWidth, path, diagnostics } = options - const table = element as TableElement - - const style = resolveElementStyle(element, ctx.document, diagnostics) - const tableWidth = element.frame.width > 0 ? element.frame.width : parentWidth - const tableX = element.frame.x - const tableTop = element.frame.y - - const datasetId = table.datasetId - const rows = datasets.get(datasetId) ?? [] - - if (!datasets.has(datasetId)) { - diagnostics.push({ - severity: "warning", - code: DIAGNOSTIC_CODES.DATA_DATASET_MISSING, - message: `明细表引用的数据集 "${datasetId}" 没有数据`, - elementId: element.id, - path: `${path}/datasetId`, - }) - } - - // 列布局:按声明宽度顺序排布;合计超出表格宽度时按比例压缩 - const declaredWidths = table.columns.map((column) => column.width) - const totalDeclared = declaredWidths.reduce((sum, width) => sum + width, 0) - const scale = totalDeclared > tableWidth && totalDeclared > 0 ? tableWidth / totalDeclared : 1 - - const columns: TableColumnLayout[] = [] - let cursorX = 0 - for (const column of table.columns) { - const width = column.width * scale - columns.push({ - id: column.id, - x: cursorX, - width, - align: column.align ?? style.align, - ...(column.header !== undefined ? { header: column.header } :{}), - }) - cursorX += width - } - - const headerHeight = table.headerHeight ?? 8 - const rowHeight = table.rowHeight ?? 7 - const rowHeightMode = table.rowHeightMode ?? "fixed" - // 表头始终存在;repeatHeaderOnEachPage 只决定"是否在后续页面重复", - // 不应影响首页是否绘制表头(早期实现把两者混为一谈,导致设为 false 时表头消失)。 - const repeatHeader = table.repeatHeaderOnEachPage !== false - const showGrid = table.showGrid !== false - - const blocks: LayoutBlock[] = [] - - // 表头块 - if (columns.length > 0) { - blocks.push({ - height: headerHeight, - kind: "header", - repeatOnEachPage: repeatHeader, - render: (top: number): LayoutNode[] => { - const content: TableContent = { - kind: "table", - rows: [], - columns, - showHeader: true, - headerHeight, - rowHeight, - showGrid, - } - return [ - { - id: `${element.id}#header`, - type: "table", - role: "table-header", - frame: { x: tableX, y: tableTop + top, width: tableWidth, height: headerHeight }, - style, - content, - }, - ] - }, - }) - } - - // 无数据占位 - if (rows.length === 0) { - const emptyText = table.emptyText ?? "无数据" - blocks.push({ - height: rowHeight, - render: (top: number): LayoutNode[] => { - const wrapped = wrapText(emptyText, { - maxWidth: tableWidth, - style, - measurer: ctx.measurer, - }) - return [ - { - id: `${element.id}#empty`, - type: "text", - role: "table-row", - frame: { x: tableX, y: tableTop + top, width: tableWidth, height: rowHeight }, - style: { ...style, align: "center" }, - content: { - kind: "text", - text: emptyText, - lines: wrapped.lines, - lineHeight: wrapped.lineHeight, - overflow: false, - }, - }, - ] - }, - }) - return blocks - } - - // 每行一个块,便于跨页拆分 - rows.forEach((row, index) => { - const scope: EvalScope = { - row, - params: ctx.renderContext.parameters, - index, - rowNumber: index + 1, - dataset: { rows, count: rows.length }, - } - - // 预先求值每列,同时计算动态行高 - const cells: { columnId: string; text: string; value?: unknown }[] = [] - let computedHeight = rowHeight - const wrappedCells = new Map() - - for (let c = 0; c < table.columns.length; c += 1) { - const column = table.columns[c]! - const layout = columns[c]! - const resolved = resolveCell(column, scope, ctx, element.id, `${path}/columns/${c}`) - diagnostics.push(...resolved.diagnostics) - - const innerWidth = Math.max(0, layout.width - style.padding.left - style.padding.right) - const wrapped = wrapText(resolved.text, { - maxWidth: innerWidth, - style, - measurer: ctx.measurer, - }) - wrappedCells.set(column.id, { lines: wrapped.lines, lineHeight: wrapped.lineHeight }) - - if (rowHeightMode === "auto" && wrapped.totalHeight > computedHeight) { - computedHeight = wrapped.totalHeight + style.padding.top + style.padding.bottom - } - - cells.push({ - columnId: column.id, - text: resolved.text, - ...(resolved.value !== undefined ? { value: resolved.value } :{}), - }) - } - - const tableRow: TableRow = { index, rowNumber: index + 1, cells, height: computedHeight } - const height = computedHeight - - blocks.push({ - height, - // 记录数据行索引,供分组按行身份选取块(不依赖数组下标) - rowIndex: index, - render: (top: number): LayoutNode[] => { - const content: TableContent = { - kind: "table", - rows: [tableRow], - columns, - showHeader: false, - headerHeight, - rowHeight, - showGrid, - } - const rowNode: LayoutNode = { - id: `${element.id}#row${index}`, - type: "table", - role: "table-row", - frame: { x: tableX, y: tableTop + top, width: tableWidth, height }, - style, - content, - } - - // 单元格内自由布局的子元素:坐标相对单元格左上角 - const cellChildren: LayoutNode[] = [] - for (let c = 0; c < table.columns.length; c += 1) { - const column = table.columns[c]! - if (!column.children?.length) continue - const layout = columns[c]! - for (const child of column.children) { - const measured = measureElement( - { - ...child, - frame: { - ...child.frame, - x: child.frame.x + layout.x, - y: child.frame.y, - }, - }, - layout.width, - ctx, - scope, - `${path}/columns/${c}`, - ) - diagnostics.push(...measured.diagnostics) - - const cellNode: LayoutNode = { - id: measured.element.id, - type: measured.element.type, - role: "table-cell", - frame: { - x: tableX, - y: tableTop + top, - width: measured.frame.width, - height: measured.frame.height, - }, - style: measured.style, - } - if (measured.text !== undefined) { - const wrapped = wrappedCells.get(column.id) - cellNode.content = { - kind: "text", - text: measured.text, - lines: wrapped?.lines ?? [measured.text], - lineHeight: wrapped?.lineHeight ?? style.fontSize, - overflow: false, - } - } - cellChildren.push(cellNode) - } - } - if (cellChildren.length > 0) rowNode.children = cellChildren - return [rowNode] - }, - }) - }) - - return blocks -} - -/** 求值一个单元格。 */ -function resolveCell( - column: TableColumn, - scope: EvalScope, - ctx: MeasureContext, - elementId: string, - path: string, -): { text: string; value: unknown; diagnostics: Diagnostic[] } { - // 优先使用列自身的 children(自由布局时由子元素承载内容) - if (column.children && column.children.length > 0 && !column.binding) { - return { text: "", value: undefined, diagnostics: [] } - } - - // 没有绑定时退回到表头文本,避免整列空白 - if (!column.binding) { - return { text: column.header ?? "", value: undefined, diagnostics: [] } - } - - const resolved = resolveBinding( - column.binding, - { scope, elementId, path: `${path}/binding` }, - ctx.cache, - ) - return { text: resolved.text, value: resolved.value, diagnostics: resolved.diagnostics } -} - -/** 计算表格在给定页高下需要多少行。 */ -export function estimateTableRowsPerPage( - rowHeight: number, - availableHeight: number, - headerHeight = 0, -): number { - if (rowHeight <= 0) return 0 - return Math.max(0, Math.floor((availableHeight - headerHeight) / rowHeight)) -} - -/** 判断元素是否为可展开的明细表。 */ -export function isExpandableTable(element: ReportElement): element is TableElement { - return element.type === "table" && Array.isArray((element as TableElement).columns) -} - -/** 计算表格声明宽度。 */ -export function declaredTableWidth(table: TableElement): number { - return measureTableWidth(table) -} diff --git a/code/one-designer/packages/report-layout/src/text-wrap.ts b/code/one-designer/packages/report-layout/src/text-wrap.ts deleted file mode 100644 index 6df4f182..00000000 --- a/code/one-designer/packages/report-layout/src/text-wrap.ts +++ /dev/null @@ -1,308 +0,0 @@ -/** - * 文本换行(对应设计文档 §3.3 的"换行"职责与 §9)。 - * - * 换行规则: - * - 优先在空白处断行(西文按词)。 - * - 中文可在任意字之间断行(无空格分词)。 - * - 标点不能出现在行首(避头点),常见的中文标点按此处理。 - * - 单个词超过行宽时强制断词,避免无限循环。 - * - * 换行结果完全由 TextMeasurer 决定,从而与具体字体环境解耦。 - */ -import type { ResolvedStyle } from "@report/core" -import type { TextMeasurer } from "./measurer.js" - -/** 不允许出现在行首的字符(避头点)。 */ -const NO_LINE_START = new Set([ - ",", "。", "、", ";", ":", "?", "!", ")", "】", "》", "」", "』", - "”", "’", "…", "—", "~", "·", "%", "‰", "℃", - ",", ".", ";", ":", "?", "!", ")", "]", "}", -]) - -/** 不允许出现在行尾的字符(避尾点)。 */ -const NO_LINE_END = new Set([ - "(", "【", "《", "「", "『", "“", "‘", - "(", "[", "{", -]) - -/** 换行选项。 */ -export interface WrapOptions { - /** 可用宽度(mm)。 */ - maxWidth: number - /** 样式,用于度量。 */ - style: ResolvedStyle - /** 度量器。 */ - measurer: TextMeasurer - /** 是否允许在词内断行(西文长词)。默认 true。 */ - breakLongWords?: boolean -} - -/** 换行结果。 */ -export interface WrapResult { - lines: string[] - /** 每行的宽度(mm),与 lines 一一对应。 */ - widths: number[] - /** 单行高度(mm)。 */ - lineHeight: number - /** 内容总高度(mm)。 */ - totalHeight: number - /** 是否发生了强制断词。 */ - brokeWords: boolean -} - -/** - * 把文本按可用宽度换行。 - * - * 输入中的显式换行符会被保留为硬换行。 - */ -export function wrapText(text: string, options: WrapOptions): WrapResult { - const { maxWidth, style, measurer, breakLongWords = true } = options - - const metrics = measurer.measure("M", style) - const lineHeight = metrics.height - - // 空文本仍占一行高度,保证空绑定元素有确定的排版高度 - if (text === "") { - return { lines: [""], widths: [0], lineHeight, totalHeight: lineHeight, brokeWords: false } - } - - const lines: string[] = [] - const widths: number[] = [] - let brokeWords = false - - // 硬换行先切分,再对每段做软换行 - const paragraphs = text.split(/\r\n|\r|\n/) - - for (const paragraph of paragraphs) { - if (paragraph === "") { - lines.push("") - widths.push(0) - continue - } - - const segments = segmentText(paragraph) - - let current = "" - let currentWidth = 0 - - const flush = (): void => { - lines.push(current) - widths.push(currentWidth) - current = "" - currentWidth = 0 - } - - for (let i = 0; i < segments.length; i += 1) { - const segment = segments[i]! - const segmentWidth = measureWidth(segment, style, measurer) - - // 空段(空白)直接累积,等待后续内容决定是否保留 - if (segment.trim() === "") { - if (current !== "") { - current += segment - currentWidth += segmentWidth - } - continue - } - - if (currentWidth + segmentWidth <= maxWidth) { - current += segment - currentWidth += segmentWidth - continue - } - - // 放不下:先结算当前行。 - // 两种避让规则都在"提交本行之前"处理,否则 flush 之后 current 已清空, - // 再判断就没有意义了。 - if (current !== "") { - if (isNoLineStart(segment) && current.length > 1) { - // 避头点:下一段不能出现在行首,把本行最后一个字符一起挪到下一行 - const lastChar = current[current.length - 1]! - const lastWidth = measureWidth(lastChar, style, measurer) - const head = current.slice(0, -1) - const headWidth = currentWidth - lastWidth - if (head.trim() !== "") { - lines.push(head) - widths.push(headWidth) - current = lastChar - currentWidth = lastWidth - } else { - flush() - } - } else if (isNoLineEnd(current)) { - // 避尾点:本行不能以「(」这类字符结尾,把它挪到下一行 - const lastChar = current[current.length - 1]! - const lastWidth = measureWidth(lastChar, style, measurer) - const head = current.slice(0, -1) - const headWidth = currentWidth - lastWidth - if (head.trim() !== "") { - lines.push(head) - widths.push(headWidth) - current = lastChar - currentWidth = lastWidth - } else { - flush() - } - } else { - flush() - } - } - - if (segmentWidth <= maxWidth) { - current = segment - currentWidth = segmentWidth - continue - } - - // 单个段就超宽:强制断词 - if (breakLongWords) { - brokeWords = true - let buffer = "" - let bufferWidth = 0 - for (const ch of segment) { - const chWidth = measureWidth(ch, style, measurer) - if (bufferWidth + chWidth > maxWidth && buffer !== "") { - lines.push(buffer) - widths.push(bufferWidth) - buffer = "" - bufferWidth = 0 - } - buffer += ch - bufferWidth += chWidth - } - current = buffer - currentWidth = bufferWidth - } else { - current = segment - currentWidth = segmentWidth - } - } - - if (current !== "" || segments.length === 0) { - // 行尾避头点:整段只剩一个标点时也要输出 - flush() - } - } - - if (lines.length === 0) { - lines.push("") - widths.push(0) - } - - const nonEmptyLines = lines.filter((line) => line !== "") - const totalHeight = lineHeight * (nonEmptyLines.length > 0 ? lines.length : 1) - - return { lines, widths, lineHeight, totalHeight, brokeWords } -} - -/** 判断字符是否不能出现在行首。 */ -export function isNoLineStart(text: string): boolean { - if (text === "") return false - return NO_LINE_START.has(text[0]!) -} - -/** 判断文本是否以不能出现在行尾的字符结尾。 */ -export function isNoLineEnd(text: string): boolean { - if (text === "") return false - return NO_LINE_END.has(text[text.length - 1]!) -} - -/** - * 把段落切成可断行的段。 - * - * 西文按词切分并保留词后空格;CJK 逐字切分。 - * 这样换行时既不会把一个英文单词拆开,也能在汉字间自由断行。 - */ -export function segmentText(paragraph: string): string[] { - const segments: string[] = [] - let buffer = "" - - const isCjk = (ch: string): boolean => { - const code = ch.codePointAt(0) ?? 0 - return ( - (code >= 0x2e80 && code <= 0x9fff) || - (code >= 0xf900 && code <= 0xfaff) || - (code >= 0xff00 && code <= 0xff60) || - (code >= 0x20000 && code <= 0x3fffd) - ) - } - - const flushBuffer = (): void => { - if (buffer !== "") { - segments.push(buffer) - buffer = "" - } - } - - for (let i = 0; i < paragraph.length; i += 1) { - const ch = paragraph[i]! - const code = ch.codePointAt(0) ?? 0 - - // 空格:结束当前段,并把空格一起带上。 - // 必须在这里 flush,否则纯西文整句会粘成一段、无法按词换行。 - // 若前面没有内容(行首空格),则空格自身成段,供避头点逻辑判断。 - if (ch === " " || ch === "\t") { - buffer += ch - flushBuffer() - continue - } - - if (isCjk(ch)) { - // CJK 字符单独成段,前面积累的西文先结算 - flushBuffer() - segments.push(ch) - continue - } - - // 代理对(emoji 等增补平面):两个码元一起处理 - if (code >= 0xd800 && code <= 0xdbff && i + 1 < paragraph.length) { - buffer += ch + paragraph[i + 1] - i += 1 - continue - } - - buffer += ch - } - - flushBuffer() - return segments -} - -/** 测量文本宽度,空串返回 0。 */ -function measureWidth(text: string, style: ResolvedStyle, measurer: TextMeasurer): number { - if (text === "") return 0 - return measurer.measure(text, style).width -} - -/** - * 计算文本在给定宽度下的高度(动态高度)。 - * - * 这是 §3.3 里"动态高度"的直接实现:表格行高、容器高度都依赖它。 - * maxHeight 缺省表示不限制高度,此时 overflow 恒为 false。 - */ -export function measureTextHeight( - text: string, - options: WrapOptions, - maxHeight?: number, -): { height: number; lineCount: number; overflow: boolean } { - const result = wrapText(text, options) - return { - height: result.totalHeight, - lineCount: result.lines.length, - overflow: maxHeight !== undefined && result.totalHeight > maxHeight + 1e-6, - } -} - -/** - * 计算换行后是否超出给定高度。 - */ -export function isTextOverflow( - text: string, - maxWidth: number, - maxHeight: number, - style: ResolvedStyle, - measurer: TextMeasurer, -): boolean { - const wrapped = wrapText(text, { maxWidth, style, measurer }) - return wrapped.totalHeight > maxHeight + 1e-6 -} diff --git a/code/one-designer/packages/report-layout/src/units.ts b/code/one-designer/packages/report-layout/src/units.ts deleted file mode 100644 index 549a684f..00000000 --- a/code/one-designer/packages/report-layout/src/units.ts +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 单位换算(对应设计文档 §7)。 - * - * 约定:文档内部统一使用 mm;px 只用于 Designer 显示层, - * pt 只在 PDF 等输出边界转换。 - * - * 本文件把该约定集中成一处可测试的换算表,避免各包各自散落常量。 - */ - -/** 1 英寸 = 25.4 毫米(精确值)。 */ -export const MM_PER_INCH = 25.4 - -/** CSS 参考像素:1 英寸 = 96px(CSS Values and Units Level 3)。 */ -export const PX_PER_INCH = 96 - -/** 排版点:1 英寸 = 72pt。 */ -export const PT_PER_INCH = 72 - -/** mm → px。 */ -export function mmToPx(mm: number): number { - return (mm / MM_PER_INCH) * PX_PER_INCH -} - -/** px → mm。 */ -export function pxToMm(px: number): number { - return (px / PX_PER_INCH) * MM_PER_INCH -} - -/** mm → pt。 */ -export function mmToPt(mm: number): number { - return (mm / MM_PER_INCH) * PT_PER_INCH -} - -/** pt → mm。 */ -export function ptToMm(pt: number): number { - return (pt / PT_PER_INCH) * MM_PER_INCH -} - -/** pt → px。 */ -export function ptToPx(pt: number): number { - return (pt / PT_PER_INCH) * PX_PER_INCH -} - -/** px → pt。 */ -export function pxToPt(px: number): number { - return (px / PX_PER_INCH) * PT_PER_INCH -} - -/** - * 字体的 em 尺寸换算:pt → mm。 - * - * 文档里的 fontSize 以 pt 表示(排版惯例),而 frame 以 mm 表示, - * 因此测量时统一把字号换算成 mm 再参与几何计算。 - */ -export function fontSizeToMm(fontSizePt: number): number { - return ptToMm(fontSizePt) -} diff --git a/code/one-designer/packages/report-layout/tests/font.test.ts b/code/one-designer/packages/report-layout/tests/font.test.ts deleted file mode 100644 index e18ab8d2..00000000 --- a/code/one-designer/packages/report-layout/tests/font.test.ts +++ /dev/null @@ -1,243 +0,0 @@ -/** - * 字体解析与真实度量测试(对应 §14 的"中文字体、长文本"测试)。 - * - * 依赖系统字体,缺少字体时相关用例自动跳过,保证在无字体环境仍可运行。 - */ -import { describe, expect, it } from "vitest" -import { existsSync } from "node:fs" -import { loadFontFile, FontLibrary, parseFontBuffer } from "../src/load-font.js" -import { createFontMeasurer } from "../src/font-measurer.js" -import { DEFAULT_RESOLVED_STYLE, type ResolvedStyle } from "@report/core" - -const ARIAL = "C:\\Windows\\Fonts\\arial.ttf" -const SIMHEI = "C:\\Windows\\Fonts\\simhei.ttf" -const MSYH = "C:\\Windows\\Fonts\\msyh.ttc" - -const hasArial = existsSync(ARIAL) -const hasSimHei = existsSync(SIMHEI) -const hasMsyh = existsSync(MSYH) - -function style(overrides: Partial = {}): ResolvedStyle { - return { ...DEFAULT_RESOLVED_STYLE, fontSize: 10, ...overrides } -} - -describe("FontLibrary 加载", () => { - it("加载失败时记录而不抛异常", () => { - const library = new FontLibrary() - const ok = library.load({ family: "Missing", path: "C:\\nope\\nope.ttf" }) - expect(ok).toBe(false) - expect(library.loadFailures()).toHaveLength(1) - expect(library.size).toBe(0) - }) - - it("clear 清空字体与失败记录", () => { - const library = new FontLibrary() - library.load({ family: "Missing", path: "C:\\nope\\nope.ttf" }) - library.clear() - expect(library.size).toBe(0) - expect(library.loadFailures()).toHaveLength(0) - }) -}) - -describe.skipIf(!hasArial)("Arial 度量", () => { - const font = loadFontFile(ARIAL) - - it("解析出正确的字体元信息", () => { - expect(font.metrics.familyName).toBe("Arial") - expect(font.metrics.unitsPerEm).toBe(2048) - expect(font.metrics.numGlyphs).toBeGreaterThan(1000) - }) - - it("比例字体的宽度各不相同", () => { - const i = font.charAdvance("i".codePointAt(0)!)! - const w = font.charAdvance("W".codePointAt(0)!)! - expect(i).toBeLessThan(w) - expect(i).toBeCloseTo(0.2222, 3) - expect(w).toBeCloseTo(0.9438, 3) - }) - - it("不覆盖中文(返回 null 而非 .notdef 宽度)", () => { - // 关键正确性检查:.notdef 本身有 advance,直接返回会把缺字当正常字符 - expect(font.hasGlyph("中".codePointAt(0)!)).toBe(false) - expect(font.charAdvance("中".codePointAt(0)!)).toBeNull() - }) - - it("覆盖 ASCII", () => { - for (const ch of ["A", "z", "0", " ", ".", ","]) { - expect(font.hasGlyph(ch.codePointAt(0)!)).toBe(true) - } - }) -}) - -describe.skipIf(!hasSimHei)("SimHei 中文字体度量", () => { - const font = loadFontFile(SIMHEI) - - it("解析出中文字体族名", () => { - expect(font.metrics.familyName).toBe("SimHei") - }) - - it("汉字宽度为全角 1.0 em", () => { - for (const ch of ["中", "文", "报", "表"]) { - expect(font.charAdvance(ch.codePointAt(0)!)).toBeCloseTo(1.0, 4) - } - }) - - it("中文标点为全角", () => { - expect(font.charAdvance(",".codePointAt(0)!)).toBeCloseTo(1.0, 4) - }) - - it("拉丁字符为半角", () => { - expect(font.charAdvance("A".codePointAt(0)!)).toBeCloseTo(0.5, 4) - }) - - it("覆盖 GB 常用汉字", () => { - for (const ch of ["销", "售", "单", "金", "额", "数", "量"]) { - expect(font.hasGlyph(ch.codePointAt(0)!)).toBe(true) - } - }) -}) - -describe.skipIf(!hasMsyh)("TTC 字体集合", () => { - it("可从集合中按索引取字体", () => { - const font0 = loadFontFile(MSYH, { fontIndex: 0 }) - expect(font0.metrics.unitsPerEm).toBeGreaterThan(0) - expect(font0.metrics.familyName).toBeTruthy() - }) - - it("索引越界时报错", () => { - expect(() => loadFontFile(MSYH, { fontIndex: 99 })).toThrow(/越界/) - }) -}) - -describe("parseFontBuffer 容错", () => { - it("拒绝非字体数据", () => { - const junk = Buffer.from("this is definitely not a font file") - expect(() => parseFontBuffer(junk)).toThrow() - }) - - it("拒绝过短的数据", () => { - expect(() => parseFontBuffer(Buffer.from([0, 1, 0, 0]))).toThrow() - }) -}) - -describe.skipIf(!hasArial || !hasSimHei)("字体库与度量器协作", () => { - function buildLibrary(): FontLibrary { - const library = new FontLibrary() - library.load({ family: "Arial", path: ARIAL }) - library.load({ family: "SimHei", path: SIMHEI }) - return library - } - - it("按字体栈解析", () => { - const library = buildLibrary() - const hit = library.resolveStack('"NoSuchFont", SimHei, sans-serif') - expect(hit?.family).toBe("SimHei") - }) - - it("全部未命中时返回 undefined", () => { - const library = buildLibrary() - expect(library.resolveStack("NoSuchFont")).toBeUndefined() - }) - - it("度量纯英文文本", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - const metrics = measurer.measure("Hello", style({ fontFamily: "Arial", fontSize: 10 })) - // 10pt 约 3.528mm;"Hello" 在 Arial 下约 2.6em - expect(metrics.width).toBeGreaterThan(6) - expect(metrics.width).toBeLessThan(12) - }) - - it("度量纯中文文本", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - const metrics = measurer.measure("中文报表", style({ fontFamily: "SimHei", fontSize: 10 })) - const em = (10 / 72) * 25.4 - // 4 个全角字符 = 4em - expect(metrics.width).toBeCloseTo(4 * em, 3) - }) - - it("中英混排按字符回退到 CJK 字体", () => { - const library = buildLibrary() - const fallbacks: string[] = [] - const measurer = createFontMeasurer({ - library, - fallbackFamilies: ["SimHei"], - onFallback: (e) => fallbacks.push(e.char), - }) - const metrics = measurer.measure("A中", style({ fontFamily: "Arial", fontSize: 10 })) - const em = (10 / 72) * 25.4 - // A(0.667) + 中(1.0) = 1.667em - expect(metrics.width).toBeCloseTo(1.667 * em, 2) - expect(fallbacks).toContain("中") - }) - - it("缺失字形提高 fallback 标记", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - // 用 Arial 度量汉字,且无 CJK 回退 - const metrics = measurer.measure("中", style({ fontFamily: "Arial" })) - expect(metrics.fallback).toBe(true) - }) - - it("完整覆盖时 fallback 为 false", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - const metrics = measurer.measure("Hello", style({ fontFamily: "Arial" })) - expect(metrics.fallback).toBe(false) - }) - - it("行高与字号成正比", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - const a = measurer.measure("x", style({ fontFamily: "Arial", fontSize: 10 })) - const b = measurer.measure("x", style({ fontFamily: "Arial", fontSize: 20 })) - expect(b.height).toBeCloseTo(a.height * 2, 4) - }) - - it("字体栈中首选命中时不回退", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library, fallbackFamilies: ["SimHei"] }) - const resolved = measurer.resolver.resolve("Arial, SimHei") - expect(resolved.resolved).toBe("Arial") - expect(resolved.fallback).toBe(false) - }) - - it("字体栈全部未命中时标记回退", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - const resolved = measurer.resolver.resolve("Nonexistent") - expect(resolved.fallback).toBe(true) - }) - - it("长文本宽度随字符数线性增长", () => { - const library = buildLibrary() - const measurer = createFontMeasurer({ library }) - const short = measurer.measure("中".repeat(10), style({ fontFamily: "SimHei" })) - const long = measurer.measure("中".repeat(100), style({ fontFamily: "SimHei" })) - expect(long.width).toBeCloseTo(short.width * 10, 3) - }) -}) - -describe("估算度量器(无字体环境)", () => { - it("全角字符为 1em", async () => { - const { createEstimateMeasurer } = await import("../src/measurer.js") - const measurer = createEstimateMeasurer() - const em = (10 / 72) * 25.4 - expect(measurer.measure("中", style()).width).toBeCloseTo(em, 4) - }) - - it("半角字符为 0.5em 附近", async () => { - const { createEstimateMeasurer } = await import("../src/measurer.js") - const measurer = createEstimateMeasurer() - const em = (10 / 72) * 25.4 - const width = measurer.measure("n", style()).width - expect(width).toBeGreaterThan(0.4 * em) - expect(width).toBeLessThan(0.7 * em) - }) - - it("始终标记 fallback", async () => { - const { createEstimateMeasurer } = await import("../src/measurer.js") - expect(createEstimateMeasurer().measure("x", style()).fallback).toBe(true) - }) -}) diff --git a/code/one-designer/packages/report-layout/tests/group.test.ts b/code/one-designer/packages/report-layout/tests/group.test.ts deleted file mode 100644 index 9e7dcdc4..00000000 --- a/code/one-designer/packages/report-layout/tests/group.test.ts +++ /dev/null @@ -1,560 +0,0 @@ -/** - * 分组测试(对应设计文档 §16 阶段 3 与 §6.1 的分组区域)。 - * - * 分组语义:相邻行键值相同即同组,不改变行顺序。 - */ -import { describe, expect, it } from "vitest" -import { - createDocument, - createTableElement, - type ReportDocument, - type ReportSection, -} from "@report/core" -import { createEstimateMeasurer, createPassthroughFontResolver } from "../src/measurer.js" -import { layoutDocument } from "../src/engine.js" -import { computeGroups, collectGroupLevels, isSameGroupKey } from "../src/group.js" -import type { GroupLevelSpec } from "../src/group.js" -import { walkLayoutNodes } from "../src/layout-document.js" -import type { RenderContext } from "../src/context.js" - -const measurer = createEstimateMeasurer() -const fontResolver = createPassthroughFontResolver() - -async function layout(doc: ReportDocument, context: RenderContext) { - return layoutDocument(doc, context, { textMeasurer: measurer, fontResolver }) -} - -const ROWS = [ - { region: "华北", city: "北京", amount: 100 }, - { region: "华北", city: "天津", amount: 200 }, - { region: "华东", city: "上海", amount: 300 }, - { region: "华东", city: "杭州", amount: 400 }, - { region: "华南", city: "广州", amount: 500 }, -] - -function baseDoc(): ReportDocument { - const doc = createDocument({ name: "分组报表" }) - doc.datasets = { sales: { id: "sales" } } - doc.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl", { x: 0, y: 0, width: 180, height: 20 }, "sales", [ - { id: "c1", width: 60, header: "地区", binding: { field: "region" } }, - { id: "c2", width: 60, header: "城市", binding: { field: "city" } }, - { id: "c3", width: 60, header: "金额", binding: { field: "amount" }, align: "right" }, - ]), - ) - return doc -} - -/** 插入一个分组区域。 */ -function addGroupSection( - doc: ReportDocument, - kind: "group-header" | "group-footer", - children: ReportSection["children"], - extra: Partial = {}, -): ReportSection { - const section: ReportSection = { - id: `grp-${kind}`, - kind, - children, - groupExpression: "row.region", - groupLevel: 1, - ...extra, - } - // 插在 detail 之前(组头)或之后(组脚) - const detailIndex = doc.sections.findIndex((s) => s.kind === "detail") - const insertAt = kind === "group-header" ? detailIndex : detailIndex + 1 - doc.sections.splice(insertAt, 0, section) - return section -} - -describe("isSameGroupKey", () => { - it("相同标量为同组", () => { - expect(isSameGroupKey("a", "a")).toBe(true) - expect(isSameGroupKey(1, 1)).toBe(true) - }) - - it("不同标量不同组", () => { - expect(isSameGroupKey("a", "b")).toBe(false) - expect(isSameGroupKey(1, 2)).toBe(false) - }) - - it("数字与字符串等价(避免 1 与 '1' 被拆成两组)", () => { - expect(isSameGroupKey(1, "1")).toBe(true) - }) - - it("null 与 undefined 视为同组", () => { - expect(isSameGroupKey(null, undefined)).toBe(true) - expect(isSameGroupKey(null, null)).toBe(true) - expect(isSameGroupKey(null, 0)).toBe(false) - }) -}) - -describe("computeGroups", () => { - it("按相邻行切分", () => { - const levels: GroupLevelSpec[] = [{ level: 1, expression: "row.region" }] - const tree = computeGroups(ROWS, levels, []) - expect(tree.groups).toHaveLength(3) - expect(tree.groups[0]?.key).toBe("华北") - expect(tree.groups[1]?.key).toBe("华东") - expect(tree.groups[2]?.key).toBe("华南") - }) - - it("记录每组的行区间", () => { - const tree = computeGroups(ROWS, [{ level: 1, expression: "row.region" }], []) - expect(tree.groups[0]?.start).toBe(0) - expect(tree.groups[0]?.end).toBe(2) - expect(tree.groups[1]?.start).toBe(2) - expect(tree.groups[1]?.end).toBe(4) - expect(tree.groups[2]?.start).toBe(4) - expect(tree.groups[2]?.end).toBe(5) - }) - - it("每组携带该组行数据", () => { - const tree = computeGroups(ROWS, [{ level: 1, expression: "row.region" }], []) - expect(tree.groups[0]?.rows).toHaveLength(2) - expect(tree.groups[0]?.rows[0]?.city).toBe("北京") - }) - - it("标记首组与末组", () => { - const tree = computeGroups(ROWS, [{ level: 1, expression: "row.region" }], []) - expect(tree.groups[0]?.isFirst).toBe(true) - expect(tree.groups[0]?.isLast).toBe(false) - expect(tree.groups[2]?.isLast).toBe(true) - }) - - it("相同键不相邻时视为不同组(不排序)", () => { - const rows = [ - { region: "A" }, - { region: "B" }, - { region: "A" }, - ] - const tree = computeGroups(rows, [{ level: 1, expression: "row.region" }], []) - // 相邻切分:A / B / A 共 3 组 - expect(tree.groups).toHaveLength(3) - }) - - it("空数据集不产生分组", () => { - const tree = computeGroups([], [{ level: 1, expression: "row.region" }], []) - expect(tree.groups).toHaveLength(0) - }) - - it("无分组定义时不产生分组", () => { - const tree = computeGroups(ROWS, [], []) - expect(tree.groups).toHaveLength(0) - }) - - it("坏表达式产生诊断而非抛异常", () => { - const diagnostics: import("@report/core").Diagnostic[] = [] - const tree = computeGroups(ROWS, [{ level: 1, expression: "row." }], diagnostics) - expect(tree.groups).toHaveLength(0) - expect(diagnostics.some((d) => d.code === "expression.parse-error")).toBe(true) - }) - - it("支持多级分组", () => { - const rows = [ - { region: "华北", city: "北京" }, - { region: "华北", city: "北京" }, - { region: "华北", city: "天津" }, - { region: "华东", city: "上海" }, - ] - const tree = computeGroups( - rows, - [ - { level: 1, expression: "row.region" }, - { level: 2, expression: "row.city" }, - ], - [], - ) - // L1: 华北(0-3), 华东(3-4);L2: 北京(0-2), 天津(2-3), 上海(3-4) - const l1 = tree.groups.filter((g) => g.level === 1) - const l2 = tree.groups.filter((g) => g.level === 2) - expect(l1).toHaveLength(2) - expect(l2).toHaveLength(3) - }) - - it("多级分组中各级区间相互独立", () => { - const rows = [ - { region: "A", city: "x" }, - { region: "A", city: "y" }, - { region: "B", city: "z" }, - ] - const tree = computeGroups( - rows, - [ - { level: 1, expression: "row.region" }, - { level: 2, expression: "row.city" }, - ], - [], - ) - const l2 = tree.groups.filter((g) => g.level === 2) - expect(l2[0]?.rows).toHaveLength(1) - expect(l2[1]?.rows).toHaveLength(1) - }) - - it("分组结果按出现位置排序", () => { - const tree = computeGroups(ROWS, [{ level: 1, expression: "row.region" }], []) - const starts = tree.groups.map((g) => g.start) - expect([...starts].sort((a, b) => a - b)).toEqual(starts) - }) -}) - -describe("collectGroupLevels", () => { - it("从区域收集分组级别", () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", []) - addGroupSection(doc, "group-footer", []) - const levels = collectGroupLevels(doc.sections, []) - expect(levels).toHaveLength(1) - expect(levels[0]?.expression).toBe("row.region") - expect(levels[0]?.headerSection).toBeDefined() - expect(levels[0]?.footerSection).toBeDefined() - }) - - it("缺少 groupExpression 时产生诊断", () => { - const diagnostics: import("@report/core").Diagnostic[] = [] - const section: ReportSection = { - id: "g1", - kind: "group-header", - children: [], - } - collectGroupLevels([section], diagnostics) - expect(diagnostics.some((d) => d.message.includes("缺少 groupExpression"))).toBe(true) - }) - - it("同级别表达式不一致时告警", () => { - const diagnostics: import("@report/core").Diagnostic[] = [] - const sections: ReportSection[] = [ - { id: "h", kind: "group-header", children: [], groupExpression: "row.a", groupLevel: 1 }, - { id: "f", kind: "group-footer", children: [], groupExpression: "row.b", groupLevel: 1 }, - ] - collectGroupLevels(sections, diagnostics) - expect(diagnostics.some((d) => d.message.includes("不同的"))).toBe(true) - }) - - it("多级别按 level 升序返回", () => { - const sections: ReportSection[] = [ - { id: "h2", kind: "group-header", children: [], groupExpression: "row.b", groupLevel: 2 }, - { id: "h1", kind: "group-header", children: [], groupExpression: "row.a", groupLevel: 1 }, - ] - const levels = collectGroupLevels(sections, []) - expect(levels.map((l) => l.level)).toEqual([1, 2]) - }) -}) - -describe("分组布局输出", () => { - it("组头渲染到输出中", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", [ - { - id: "gh", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - binding: { expression: "'地区:' + row.region" }, - }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const texts: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.content?.kind === "text") texts.push(node.content.text) - }) - // 三个地区各输出一次组头 - expect(texts.filter((t) => t.startsWith("地区:"))).toHaveLength(3) - expect(texts).toContain("地区:华北") - expect(texts).toContain("地区:华东") - expect(texts).toContain("地区:华南") - }) - - it("组脚按组聚合(sum)", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { - id: "gf", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - binding: { expression: "sum(group.amount) + ' / ' + group.count + ' 笔'" }, - }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const texts: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.content?.kind === "text") texts.push(node.content.text) - }) - // 华北 100+200=300(2 笔),华东 300+400=700(2 笔),华南 500(1 笔) - expect(texts).toContain("300 / 2 笔") - expect(texts).toContain("700 / 2 笔") - expect(texts).toContain("500 / 1 笔") - }) - - it("组脚可用 avg 聚合", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { - id: "gf", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - binding: { expression: "avg(group.amount)" }, - }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - const texts: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.content?.kind === "text") texts.push(node.content.text) - }) - // 华北均值 150,华东 350,华南 500 - expect(texts).toContain("150") - expect(texts).toContain("350") - }) - - it("组脚可访问 group.key", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { - id: "gf", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - binding: { expression: "string(group.key)" }, - }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - const texts: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.content?.kind === "text") texts.push(node.content.text) - }) - expect(texts).toContain("华北") - expect(texts).toContain("华南") - }) - - it("详细行全部保留(分组不丢行)", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", [ - { id: "gh", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组" } }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - let rowCount = 0 - walkLayoutNodes(result, (node) => { - if (node.role === "table-row" && node.content?.kind === "table") rowCount += 1 - }) - expect(rowCount).toBe(ROWS.length) - }) - - it("分组后行顺序不变", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", [ - { id: "gh", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组" } }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const cities: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.content?.kind === "table" && node.role === "table-row") { - const cell = node.content.rows[0]?.cells[1] - if (cell) cities.push(cell.text) - } - }) - expect(cities).toEqual(["北京", "天津", "上海", "杭州", "广州"]) - }) - - it("组头在详细行之前、组脚之后", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", [ - { id: "gh", type: "text", frame: { x: 0, y: 0, width: 100, height: 10 }, props: { text: "组头" } }, - ]) - addGroupSection(doc, "group-footer", [ - { id: "gf", type: "text", frame: { x: 0, y: 0, width: 100, height: 10 }, props: { text: "组脚" } }, - ]) - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const order: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.id === "gh") order.push("H") - if (node.id === "gf") order.push("F") - if (node.role === "table-row") order.push("R") - }) - // 期望:H R R F H R R F H R F(3 组) - expect(order.join("")).toBe("HRRFHRRFHRF") - }) - - it("无数据时不输出分组区域", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { id: "gf", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组脚" } }, - ]) - const result = await layout(doc, { data: { sales: [] }, parameters: {} }) - const texts: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.content?.kind === "text") texts.push(node.content.text) - }) - expect(texts).not.toContain("组脚") - expect(result.diagnostics.some((d) => d.code === "data.dataset-missing")).toBe(true) - }) - - it("没有分组定义时行为与之前一致", async () => { - const doc = baseDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - let rowCount = 0 - walkLayoutNodes(result, (node) => { - if (node.role === "table-row") rowCount += 1 - }) - expect(rowCount).toBe(ROWS.length) - }) - - it("表头仍每页重复(分组不影响)", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", [ - { id: "gh", type: "text", frame: { x: 0, y: 0, width: 100, height: 6 }, props: { text: "组" } }, - ]) - // 用大量数据迫使多页 - const manyRows = Array.from({ length: 200 }, (_, i) => ({ - region: `地区${Math.floor(i / 20)}`, - city: `城市${i}`, - amount: i, - })) - const result = await layout(doc, { data: { sales: manyRows }, parameters: {} }) - expect(result.pages.length).toBeGreaterThan(1) - for (const page of result.pages) { - expect(page.nodes.some((n) => n.role === "table-header")).toBe(true) - } - }) - - it("分组跨页时组脚仍输出", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { - id: "gf", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - binding: { expression: "sum(group.amount)" }, - }, - ]) - const manyRows = Array.from({ length: 200 }, (_, i) => ({ - region: `地区${Math.floor(i / 20)}`, - city: `城市${i}`, - amount: 1, - })) - const result = await layout(doc, { data: { sales: manyRows }, parameters: {} }) - - const totals: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.id === "gf" && node.content?.kind === "text") totals.push(node.content.text) - }) - // 10 个组,每组 20 行 × 1 = 20 - expect(totals).toHaveLength(10) - expect(totals.every((t) => t === "20")).toBe(true) - }) - - it("组头不与组内首行分离(keepWithNext)", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-header", [ - { id: "gh", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组头" } }, - ]) - // 大量行迫使多页;每个组头后面一定紧跟数据行 - const manyRows = Array.from({ length: 200 }, (_, i) => ({ - region: `地区${Math.floor(i / 20)}`, - city: `城市${i}`, - amount: i, - })) - const result = await layout(doc, { data: { sales: manyRows }, parameters: {} }) - - // 逐页检查:任何一页里,组头 gh 之后必然存在至少一个数据行 - for (const page of result.pages) { - const ids: string[] = [] - walkLayoutNodes({ ...result, pages: [page] }, (node) => { - if (node.id === "gh") ids.push("H") - else if (node.role === "table-row") ids.push("R") - }) - // 若本页有组头,则其后必须有数据行(组头不孤立) - const headerPos = ids.indexOf("H") - if (headerPos >= 0) { - expect(ids.slice(headerPos + 1)).toContain("R") - } - } - }) - - it("组脚不与组内末行分离(keepWithPrevious)", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { id: "gf", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组脚" } }, - ]) - const manyRows = Array.from({ length: 200 }, (_, i) => ({ - region: `地区${Math.floor(i / 20)}`, - city: `城市${i}`, - amount: i, - })) - const result = await layout(doc, { data: { sales: manyRows }, parameters: {} }) - - // 逐页检查:任何一页里,组脚 gf 之前必然存在数据行(组脚不孤立) - for (const page of result.pages) { - const ids: string[] = [] - walkLayoutNodes({ ...result, pages: [page] }, (node) => { - if (node.id === "gf") ids.push("F") - else if (node.role === "table-row") ids.push("R") - }) - const footerPos = ids.lastIndexOf("F") - if (footerPos >= 0) { - expect(ids.slice(0, footerPos)).toContain("R") - } - } - }) - - it("组脚不丢失(跨页后每组的组脚都在)", async () => { - const doc = baseDoc() - addGroupSection(doc, "group-footer", [ - { id: "gf", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组脚" } }, - ]) - const manyRows = Array.from({ length: 60 }, (_, i) => ({ - region: `地区${Math.floor(i / 6)}`, - city: `城市${i}`, - amount: 1, - })) - const result = await layout(doc, { data: { sales: manyRows }, parameters: {} }) - - const footers: string[] = [] - walkLayoutNodes(result, (node) => { - if (node.id === "gf" && node.content?.kind === "text") footers.push(node.content.text) - }) - // 10 个组,每个组的组脚都必须出现一次 - expect(footers).toHaveLength(10) - expect(footers.every((t) => t === "组脚")).toBe(true) - }) - - it("pageBreakBefore 使每组独占一页起始", async () => { - const doc = baseDoc() - addGroupSection( - doc, - "group-header", - [{ id: "gh", type: "text", frame: { x: 0, y: 0, width: 100, height: 8 }, props: { text: "组头" } }], - { pageBreakBefore: true }, - ) - // 3 组,每组若干行,组头声明 pageBreakBefore - const rows = Array.from({ length: 30 }, (_, i) => ({ - region: `地区${Math.floor(i / 10)}`, - city: `城市${i}`, - amount: i, - })) - const result = await layout(doc, { data: { sales: rows }, parameters: {} }) - - // 每个组头应落在其所在页的主体顶部(即该页第一个主体块) - const pageHeaders: string[][] = [] - for (const page of result.pages) { - const ids: string[] = [] - walkLayoutNodes({ ...result, pages: [page] }, (node) => { - if (node.id === "gh") ids.push("H") - else if (node.role === "table-row") ids.push("R") - else if (node.role === "table-header") ids.push("T") - }) - pageHeaders.push(ids) - } - - // 至少应有多页;每个含组头的页,组头应是首个非表头块 - const pagesWithHeader = pageHeaders.filter((ids) => ids.includes("H")) - expect(pagesWithHeader.length).toBe(3) - for (const ids of pagesWithHeader) { - // 去掉前导表头后,第一个主体块应是组头 - const firstBody = ids.find((x) => x !== "T") - expect(firstBody).toBe("H") - } - }) -}) diff --git a/code/one-designer/packages/report-layout/tests/pagination.test.ts b/code/one-designer/packages/report-layout/tests/pagination.test.ts deleted file mode 100644 index a3eb819c..00000000 --- a/code/one-designer/packages/report-layout/tests/pagination.test.ts +++ /dev/null @@ -1,558 +0,0 @@ -/** - * 分页与布局引擎测试(对应设计文档 §14 的"页眉、页脚和多页分页测试"、 - * "固定元素和明细表的布局快照测试")。 - */ -import { describe, expect, it } from "vitest" -import { - createDocument, - createTableElement, - type ReportDocument, -} from "@report/core" -import { createEstimateMeasurer, createPassthroughFontResolver } from "../src/measurer.js" -import { layoutDocument } from "../src/engine.js" -import { computePageGeometry } from "../src/paginate.js" -import { countLayoutNodes, walkLayoutNodes } from "../src/layout-document.js" -import type { RenderContext } from "../src/context.js" - -const measurer = createEstimateMeasurer() -const fontResolver = createPassthroughFontResolver() - -function emptyContext(parameters: Record = {}): RenderContext { - return { data: {}, parameters } -} - -async function layout(doc: ReportDocument, context = emptyContext()) { - return layoutDocument(doc, context, { textMeasurer: measurer, fontResolver }) -} - -/** 一份含页眉、明细文本、页脚的文档。 */ -function documentWith(configure: (doc: ReportDocument) => void): ReportDocument { - const doc = createDocument({ name: "测试报表" }) - configure(doc) - return doc -} - -describe("页面几何", () => { - it("A4 纵向尺寸正确", () => { - const doc = createDocument({ page: { paper: "A4", orientation: "portrait" } }) - const geometry = computePageGeometry(doc) - expect(geometry.width).toBe(210) - expect(geometry.height).toBe(297) - // 默认边距 15mm - expect(geometry.contentWidth).toBe(180) - expect(geometry.contentHeight).toBe(267) - }) - - it("横向交换宽高", () => { - const doc = createDocument({ page: { paper: "A4", orientation: "landscape" } }) - const geometry = computePageGeometry(doc) - expect(geometry.width).toBe(297) - expect(geometry.height).toBe(210) - }) - - it("A5 尺寸正确", () => { - const doc = createDocument({ page: { paper: "A5" } }) - const geometry = computePageGeometry(doc) - expect(geometry.width).toBe(148) - expect(geometry.height).toBe(210) - }) - - it("自定义纸张生效", () => { - const doc = createDocument({ - page: { paper: "custom", customSize: { width: 100, height: 150 }, margin: { top: 5, right: 5, bottom: 5, left: 5 } }, - }) - const geometry = computePageGeometry(doc) - expect(geometry.width).toBe(100) - expect(geometry.height).toBe(150) - expect(geometry.contentWidth).toBe(90) - }) -}) - -describe("单页布局", () => { - it("空文档产出一页", async () => { - const result = await layout(createDocument()) - expect(result.pages).toHaveLength(1) - expect(result.pageCount).toBe(1) - }) - - it("页面尺寸写入布局结果", async () => { - const result = await layout(createDocument({ page: { paper: "A5" } })) - expect(result.pages[0]?.width).toBe(148) - expect(result.pages[0]?.height).toBe(210) - }) - - it("页眉元素被渲染", async () => { - const doc = documentWith((d) => { - const header = d.sections.find((s) => s.kind === "page-header")! - header.children.push({ - id: "h1", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - props: { text: "销售单" }, - }) - }) - const result = await layout(doc) - const ids: string[] = [] - walkLayoutNodes(result, (node) => ids.push(node.id)) - expect(ids).toContain("h1") - }) - - it("文本内容被写入布局节点", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "t1", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - props: { text: "正文" }, - }) - }) - const result = await layout(doc) - let found: string | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "t1" && node.content?.kind === "text") found = node.content.text - }) - expect(found).toBe("正文") - }) - - it("页脚每页重复", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "page-footer")!.children.push({ - id: "f1", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 6 }, - props: { text: "页脚" }, - }) - }) - const result = await layout(doc) - expect(result.pages).toHaveLength(1) - const footerNode = result.pages[0]?.nodes.find((n) => n.id === "f1") - expect(footerNode).toBeDefined() - }) - - it("元素坐标为绝对坐标", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "t1", - type: "text", - frame: { x: 10, y: 5, width: 50, height: 8 }, - props: { text: "x" }, - }) - }) - const result = await layout(doc) - let frame: { x: number; y: number } | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "t1") frame = node.frame - }) - // x 保持元素自身偏移;y = 内容区起点(15) + 页眉高度(0) + 元素 y(5) - expect(frame?.x).toBe(10) - expect(frame?.y).toBeGreaterThanOrEqual(15) - }) - - it("无 TextMeasurer 时产生诊断", async () => { - const result = await layoutDocument(createDocument(), emptyContext(), { fontResolver }) - expect(result.diagnostics.some((d) => d.message.includes("估算度量器"))).toBe(true) - }) - - it("提供 TextMeasurer 时不产生该诊断", async () => { - const result = await layout(createDocument()) - expect(result.diagnostics.some((d) => d.message.includes("估算度量器"))).toBe(false) - }) -}) - -describe("多页分页", () => { - it("内容超出页面时产生多页", async () => { - const doc = documentWith((d) => { - const detail = d.sections.find((s) => s.kind === "detail")! - // 明细区放置一个很高的表格,迫使分页 - d.datasets = { ds1: { id: "ds1" } } - detail.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 90, header: "名称" }, - { id: "c2", width: 90, header: "数量" }, - ]), - ) - }) - const context: RenderContext = { - data: { - ds1: Array.from({ length: 100 }, (_, i) => ({ name: `项目${i}`, qty: i })), - }, - parameters: {}, - } - const result = await layout(doc, context) - expect(result.pages.length).toBeGreaterThan(1) - expect(result.pageCount).toBe(result.pages.length) - }) - - it("页码连续递增", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - d.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 180, header: "值" }, - ]), - ) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 60 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - result.pages.forEach((page, index) => { - expect(page.pageNumber).toBe(index + 1) - }) - }) - - it("页眉在每一页都出现", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - d.sections.find((s) => s.kind === "page-header")!.children.push({ - id: "hdr", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - props: { text: "页眉" }, - }) - d.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 180, header: "值" }, - ]), - ) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 80 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - expect(result.pages.length).toBeGreaterThan(1) - for (const page of result.pages) { - expect(page.nodes.some((n) => n.id === "hdr")).toBe(true) - } - }) - - it("页脚在每一页都出现", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - d.sections.find((s) => s.kind === "page-footer")!.children.push({ - id: "ftr", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 6 }, - props: { text: "页脚" }, - }) - d.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 180, header: "值" }, - ]), - ) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 80 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - for (const page of result.pages) { - expect(page.nodes.some((n) => n.id === "ftr")).toBe(true) - } - }) - - it("不存在内容溢出的页(除超高大块外)", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - d.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 180, header: "值" }, - ]), - ) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 50 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - expect(result.diagnostics.filter((d) => d.code === "layout.page-overflow")).toEqual([]) - }) - - // 回归测试:曾出现"表头只出现在第一页"的问题—— - // 分页器记录了 isHeader 标记却没有真正在后续页面补插表头。 - it("明细表表头在每一页都重复", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - d.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 180, header: "值" }, - ]), - ) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 200 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - expect(result.pages.length).toBeGreaterThan(1) - for (const page of result.pages) { - const headers = page.nodes.filter((n) => n.role === "table-header") - expect(headers).toHaveLength(1) - } - }) - - it("表头重复时不超出内容区", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - d.sections.find((s) => s.kind === "detail")!.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "ds1", [ - { id: "c1", width: 180, header: "值" }, - ]), - ) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 200 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - // 内容区底部 = 15 + 267 = 282mm - const contentBottom = 282 - for (const page of result.pages) { - for (const node of page.nodes) { - expect(node.frame.y + node.frame.height).toBeLessThanOrEqual(contentBottom + 0.01) - } - } - }) - - it("repeatHeaderOnEachPage 为 false 时表头只出现一次", async () => { - const doc = documentWith((d) => { - d.datasets = { ds1: { id: "ds1" } } - const table = createTableElement( - "tbl1", - { x: 0, y: 0, width: 180, height: 20 }, - "ds1", - [{ id: "c1", width: 180, header: "值" }], - ) - table.repeatHeaderOnEachPage = false - d.sections.find((s) => s.kind === "detail")!.children.push(table) - }) - const context: RenderContext = { - data: { ds1: Array.from({ length: 200 }, (_, i) => ({ value: i })) }, - parameters: {}, - } - const result = await layout(doc, context) - expect(result.pages.length).toBeGreaterThan(1) - // 仅首页有表头 - expect(result.pages[0]!.nodes.some((n) => n.role === "table-header")).toBe(true) - for (let i = 1; i < result.pages.length; i += 1) { - expect(result.pages[i]!.nodes.some((n) => n.role === "table-header")).toBe(false) - } - }) -}) - -describe("页眉页脚过高", () => { - it("页眉页脚占满内容区时报错并返回空页集", async () => { - const doc = documentWith((d) => { - const header = d.sections.find((s) => s.kind === "page-header")! - const footer = d.sections.find((s) => s.kind === "page-footer")! - // 页眉 200mm + 页脚 200mm 远超 267mm 内容区 - header.children.push({ - id: "big-header", - type: "rect", - frame: { x: 0, y: 0, width: 180, height: 200 }, - }) - footer.children.push({ - id: "big-footer", - type: "rect", - frame: { x: 0, y: 0, width: 180, height: 200 }, - }) - }) - const result = await layout(doc) - expect(result.pages).toHaveLength(0) - expect(result.diagnostics.some((d) => d.code === "layout.page-overflow")).toBe(true) - }) -}) - -describe("Y 坐标分层", () => { - it("页眉在上、页脚在下、主体居中", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "page-header")!.children.push({ - id: "hdr", - type: "rect", - frame: { x: 0, y: 0, width: 100, height: 10 }, - }) - d.sections.find((s) => s.kind === "page-footer")!.children.push({ - id: "ftr", - type: "rect", - frame: { x: 0, y: 0, width: 100, height: 10 }, - }) - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "body", - type: "rect", - frame: { x: 0, y: 0, width: 100, height: 10 }, - }) - }) - const result = await layout(doc) - const page = result.pages[0]! - const hdr = page.nodes.find((n) => n.id === "hdr")! - const body = page.nodes.find((n) => n.id === "body")! - const ftr = page.nodes.find((n) => n.id === "ftr")! - - expect(hdr.frame.y).toBeLessThan(body.frame.y) - expect(body.frame.y).toBeLessThan(ftr.frame.y) - // 页脚贴内容区底部:15 + 267 - 10 = 272 - expect(ftr.frame.y).toBeCloseTo(272, 4) - }) -}) - -describe("区域记录", () => { - it("页面记录区域落位信息", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "page-header")!.children.push({ - id: "hdr", - type: "rect", - frame: { x: 0, y: 0, width: 100, height: 10 }, - }) - }) - const result = await layout(doc) - const kinds = result.pages[0]!.sections.map((s) => s.kind) - expect(kinds).toContain("page-header") - }) -}) - -describe("元素类型渲染", () => { - it("rect 产出 rect 内容", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "r1", - type: "rect", - frame: { x: 0, y: 0, width: 20, height: 10 }, - }) - }) - const result = await layout(doc) - let kind: string | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "r1") kind = node.content?.kind - }) - expect(kind).toBe("rect") - }) - - it("line 产出 line 内容", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "l1", - type: "line", - frame: { x: 0, y: 0, width: 50, height: 0.2 }, - props: { direction: "horizontal" }, - }) - }) - const result = await layout(doc) - let content: { kind: string; direction?: string } | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "l1" && node.content?.kind === "line") content = node.content - }) - expect(content?.kind).toBe("line") - expect(content?.direction).toBe("horizontal") - }) - - it("image 产出 image 内容", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "i1", - type: "image", - frame: { x: 0, y: 0, width: 20, height: 20 }, - props: { src: "logo.png" }, - }) - }) - const result = await layout(doc) - let src: string | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "i1" && node.content?.kind === "image") src = node.content.src - }) - expect(src).toBe("logo.png") - }) - - it("container 子元素被递归布局", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "c1", - type: "container", - frame: { x: 0, y: 0, width: 50, height: 30 }, - children: [ - { - id: "child1", - type: "text", - frame: { x: 2, y: 2, width: 20, height: 6 }, - props: { text: "子元素" }, - }, - ], - }) - }) - const result = await layout(doc) - const ids: string[] = [] - walkLayoutNodes(result, (node) => ids.push(node.id)) - expect(ids).toContain("child1") - }) -}) - -describe("动态高度", () => { - it("长文本自动增高", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "long", - type: "text", - // 高度只给 5mm,但内容需要多行 - frame: { x: 0, y: 0, width: 20, height: 5 }, - props: { text: "这是一段很长的中文文本需要换行显示" }, - }) - }) - const result = await layout(doc) - let height: number | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "long") height = node.frame.height - }) - expect(height).toBeGreaterThan(5) - }) - - it("短文本保持原高度", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "short", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 20 }, - props: { text: "短" }, - }) - }) - const result = await layout(doc) - let height: number | undefined - walkLayoutNodes(result, (node) => { - if (node.id === "short") height = node.frame.height - }) - expect(height).toBe(20) - }) -}) - -describe("未知区域处理", () => { - it("V1 之外的区域被跳过并产生提示", async () => { - const doc = createDocument() - doc.sections.push({ - id: "sum1", - kind: "summary", - children: [ - { id: "s1", type: "text", frame: { x: 0, y: 0, width: 50, height: 8 }, props: { text: "汇总" } }, - ], - }) - const result = await layout(doc) - const ids: string[] = [] - walkLayoutNodes(result, (node) => ids.push(node.id)) - expect(ids).not.toContain("s1") - expect(result.diagnostics.some((d) => d.message.includes("不在 V1 渲染范围内"))).toBe(true) - }) -}) - -describe("节点统计", () => { - it("countLayoutNodes 统计所有页节点", async () => { - const doc = documentWith((d) => { - d.sections.find((s) => s.kind === "detail")!.children.push({ - id: "a", - type: "text", - frame: { x: 0, y: 0, width: 50, height: 8 }, - props: { text: "a" }, - }) - }) - const result = await layout(doc) - expect(countLayoutNodes(result)).toBeGreaterThan(0) - }) -}) diff --git a/code/one-designer/packages/report-layout/tests/text-wrap.test.ts b/code/one-designer/packages/report-layout/tests/text-wrap.test.ts deleted file mode 100644 index d2cd01bc..00000000 --- a/code/one-designer/packages/report-layout/tests/text-wrap.test.ts +++ /dev/null @@ -1,230 +0,0 @@ -/** - * 文本换行测试(对应设计文档 §14 的"中文字体、长文本"测试)。 - * - * 使用确定性估算度量器,保证断言与字体环境无关。 - */ -import { describe, expect, it } from "vitest" -import { DEFAULT_RESOLVED_STYLE, type ResolvedStyle } from "@report/core" -import { createEstimateMeasurer } from "../src/measurer.js" -import { - wrapText, - segmentText, - isTextOverflow, - measureTextHeight, - isNoLineStart, - isNoLineEnd, -} from "../src/text-wrap.js" - -const measurer = createEstimateMeasurer() - -function style(overrides: Partial = {}): ResolvedStyle { - return { ...DEFAULT_RESOLVED_STYLE, fontSize: 10, ...overrides } -} - -/** 10pt 字号下 1em ≈ 3.5278mm */ -const EM = (10 / 72) * 25.4 - -describe("segmentText 分段", () => { - it("西文按词切分并保留空格", () => { - expect(segmentText("hello world")).toEqual(["hello ", "world"]) - }) - - it("中文逐字切分", () => { - expect(segmentText("中文报表")).toEqual(["中", "文", "报", "表"]) - }) - - it("中英混排正确切分", () => { - // 空格自身成段:它终结前一个词,同时供避头点逻辑判断 - expect(segmentText("销售 abc 单")).toEqual(["销", "售", " ", "abc ", "单"]) - }) - - it("空串返回空数组", () => { - expect(segmentText("")).toEqual([]) - }) -}) - -describe("wrapText 基本换行", () => { - it("短文本不换行", () => { - const result = wrapText("abc", { maxWidth: 100, style: style(), measurer }) - expect(result.lines).toEqual(["abc"]) - }) - - it("超宽英文在词边界换行", () => { - // "hello world" 约 5em;限制到 4em 才能触发词边界换行 - const result = wrapText("hello world", { - maxWidth: 4 * EM, - style: style(), - measurer, - }) - expect(result.lines.length).toBeGreaterThan(1) - // 不拆开单词:每行去掉空格后仍应是完整单词 - for (const line of result.lines) { - expect(["hello", "world"]).toContain(line.trim()) - } - }) - - it("中文在任意字之间换行", () => { - const result = wrapText("中文报表测试", { maxWidth: 3 * EM, style: style(), measurer }) - expect(result.lines.length).toBe(2) - expect(result.lines[0]).toBe("中文报") - expect(result.lines[1]).toBe("表测试") - }) - - it("保留硬换行", () => { - const result = wrapText("a\nb", { maxWidth: 100, style: style(), measurer }) - expect(result.lines).toEqual(["a", "b"]) - }) - - it("空文本占一行", () => { - const result = wrapText("", { maxWidth: 100, style: style(), measurer }) - expect(result.lines).toEqual([""]) - expect(result.totalHeight).toBeCloseTo(EM * 1.2, 4) - }) - - it("每行宽度不超过限制(中文)", () => { - const result = wrapText("中文报表测试内容", { maxWidth: 2 * EM, style: style(), measurer }) - for (const width of result.widths) { - expect(width).toBeLessThanOrEqual(2 * EM + 1e-6) - } - }) - - it("长文本换行后行数合理", () => { - const text = "中".repeat(100) - const result = wrapText(text, { maxWidth: 10 * EM, style: style(), measurer }) - expect(result.lines.length).toBe(10) - }) - - it("总高度 = 行数 × 行高", () => { - const result = wrapText("中".repeat(10), { maxWidth: 5 * EM, style: style(), measurer }) - expect(result.totalHeight).toBeCloseTo(result.lineHeight * result.lines.length, 4) - }) - - it("行高随字号变化", () => { - const a = wrapText("x", { maxWidth: 100, style: style({ fontSize: 10 }), measurer }) - const b = wrapText("x", { maxWidth: 100, style: style({ fontSize: 20 }), measurer }) - expect(b.lineHeight).toBeCloseTo(a.lineHeight * 2, 4) - }) -}) - -describe("wrapText 强制断词", () => { - it("超长单词被强制断开", () => { - const result = wrapText("abcdefghijklmnop", { maxWidth: 5 * EM, style: style(), measurer }) - expect(result.brokeWords).toBe(true) - expect(result.lines.length).toBeGreaterThan(1) - }) - - it("禁用断词时整词放一行(允许溢出)", () => { - const result = wrapText("abcdefghijklmnop", { - maxWidth: 5 * EM, - style: style(), - measurer, - breakLongWords: false, - }) - expect(result.brokeWords).toBe(false) - expect(result.lines).toEqual(["abcdefghijklmnop"]) - }) - - it("超长中文串不触发 brokeWords(逐字即可换行)", () => { - const result = wrapText("中".repeat(20), { maxWidth: 3 * EM, style: style(), measurer }) - expect(result.brokeWords).toBe(false) - }) -}) - -describe("避头点规则", () => { - it("识别不可行首的标点", () => { - expect(isNoLineStart(",")).toBe(true) - expect(isNoLineStart("。")).toBe(true) - expect(isNoLineStart(")")).toBe(true) - expect(isNoLineStart("中")).toBe(false) - }) - - it("识别不可行尾的标点", () => { - expect(isNoLineEnd("(")).toBe(true) - expect(isNoLineEnd("中")).toBe(false) - }) - - it("空串两种规则都返回 false", () => { - expect(isNoLineStart("")).toBe(false) - expect(isNoLineEnd("")).toBe(false) - }) - - it("行尾不出现左括号", () => { - // 宽度刚好让 "(" 落在行尾时,应把它推到下一行 - const result = wrapText("中文(测试)", { maxWidth: 3 * EM, style: style(), measurer }) - for (const line of result.lines) { - if (line === "") continue - expect(isNoLineEnd(line)).toBe(false) - } - }) - - it("行首不出现逗号", () => { - const result = wrapText("中文,测试", { maxWidth: 3 * EM, style: style(), measurer }) - for (const line of result.lines) { - if (line === "") continue - expect(isNoLineStart(line)).toBe(false) - } - }) -}) - -describe("measureTextHeight", () => { - it("返回高度与行数", () => { - const result = measureTextHeight("中".repeat(10), { - maxWidth: 5 * EM, - style: style(), - measurer, - }) - expect(result.lineCount).toBe(2) - expect(result.height).toBeGreaterThan(0) - }) - - it("指定最大高度时能识别溢出", () => { - const result = measureTextHeight( - "中".repeat(10), - { maxWidth: 5 * EM, style: style(), measurer }, - EM, // 只允许一行 - ) - expect(result.overflow).toBe(true) - }) - - it("未指定最大高度时 overflow 恒为 false", () => { - const result = measureTextHeight("中".repeat(100), { - maxWidth: 5 * EM, - style: style(), - measurer, - }) - expect(result.overflow).toBe(false) - }) -}) - -describe("isTextOverflow", () => { - it("内容超出高度返回 true", () => { - expect(isTextOverflow("中".repeat(10), 5 * EM, EM, style(), measurer)).toBe(true) - }) - - it("内容未超出返回 false", () => { - expect(isTextOverflow("中", 5 * EM, 10 * EM, style(), measurer)).toBe(false) - }) -}) - -describe("边界情况", () => { - it("零宽度时每字一行", () => { - const result = wrapText("中文字", { maxWidth: 0, style: style(), measurer }) - expect(result.lines.length).toBe(3) - }) - - it("纯空白文本", () => { - const result = wrapText(" ", { maxWidth: 100, style: style(), measurer }) - expect(result.lines.length).toBeGreaterThanOrEqual(1) - }) - - it("连续硬换行保留空行", () => { - const result = wrapText("a\n\nb", { maxWidth: 100, style: style(), measurer }) - expect(result.lines).toEqual(["a", "", "b"]) - }) - - it("标签或特殊字符不崩溃", () => { - expect(() => - wrapText("粗体 & \"引号\"", { maxWidth: 3 * EM, style: style(), measurer }), - ).not.toThrow() - }) -}) diff --git a/code/one-designer/packages/report-layout/tsconfig.json b/code/one-designer/packages/report-layout/tsconfig.json deleted file mode 100644 index 23cc1372..00000000 --- a/code/one-designer/packages/report-layout/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src", - "types": ["node"] - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist", "tests"] -} diff --git a/code/one-designer/packages/report-layout/tsconfig.test.json b/code/one-designer/packages/report-layout/tsconfig.test.json deleted file mode 100644 index 6cefc694..00000000 --- a/code/one-designer/packages/report-layout/tsconfig.test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "noEmit": true, - "types": ["node", "vitest/globals"] - }, - "include": ["src/**/*.ts", "tests/**/*.ts", "*.config.ts"] -} diff --git a/code/one-designer/packages/report-layout/tsup.config.ts b/code/one-designer/packages/report-layout/tsup.config.ts deleted file mode 100644 index bd9d9bd4..00000000 --- a/code/one-designer/packages/report-layout/tsup.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { defineConfig } from "tsup" - -export default defineConfig({ - // fonts 单独入口:Node 侧字体解析会用到 node:fs, - // 与纯逻辑入口分离,避免浏览器打包被迫引入 Node 内置模块。 - entry: ["src/index.ts", "src/fonts.ts"], - format: ["esm", "cjs"], - dts: true, - sourcemap: true, - clean: true, - treeshake: true, - target: "es2022", - external: ["node:fs", "node:path"], -}) diff --git a/code/one-designer/packages/report-layout/vitest.config.ts b/code/one-designer/packages/report-layout/vitest.config.ts deleted file mode 100644 index 0af27743..00000000 --- a/code/one-designer/packages/report-layout/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "vitest/config" - -export default defineConfig({ - test: { - include: ["tests/**/*.test.ts"], - environment: "node", - }, -}) diff --git a/code/one-designer/packages/report-renderer/package.json b/code/one-designer/packages/report-renderer/package.json deleted file mode 100644 index 16eb8438..00000000 --- a/code/one-designer/packages/report-renderer/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "@report/renderer", - "version": "0.1.0", - "description": "消费 LayoutDocument 的 HTML / SVG / PDF 渲染器与浏览器打印", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.cjs" - } - }, - "files": ["dist"], - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit -p tsconfig.test.json" - }, - "dependencies": { - "@report/core": "workspace:*", - "@report/layout": "workspace:*" - }, - "devDependencies": { - "tsup": "^8.3.5", - "typescript": "^5.7.2", - "vitest": "^2.1.8" - } -} diff --git a/code/one-designer/packages/report-renderer/src/html.ts b/code/one-designer/packages/report-renderer/src/html.ts deleted file mode 100644 index ef547a7a..00000000 --- a/code/one-designer/packages/report-renderer/src/html.ts +++ /dev/null @@ -1,250 +0,0 @@ -/** - * HTML Renderer(对应设计文档 §4.4、§3.3)。 - * - * 消费 LayoutDocument,产出可直接打印的 HTML 文档字符串。 - * 每页一个
,绝对定位的节点用内联样式表达, - * 便于浏览器打印时按页分页。 - */ -import type { Diagnostic } from "@report/core" -import type { - LayoutDocument, - LayoutNode, - LayoutPage, - TableContent, -} from "@report/layout" -import type { RenderOptions, TextRenderResult } from "./types.js" -import { styleToCss, toUnit, unitSuffix } from "./style.js" - -/** HTML 渲染器。 */ -export interface HtmlRenderer { - render(document: LayoutDocument, options?: RenderOptions): TextRenderResult -} - -/** 创建 HTML 渲染器。 */ -export function createHtmlRenderer(): HtmlRenderer { - return { - render(document, options = {}) { - return renderHtml(document, options) - }, - } -} - -/** - * 把布局文档渲染为 HTML。 - * - * 产出一个完整的 HTML 文档(含 打印样式),页面用 - * `page-break-after` 实现浏览器打印分页。 - */ -export function renderHtml(document: LayoutDocument, options: RenderOptions = {}): TextRenderResult { - const diagnostics: Diagnostic[] = [] - const unit = unitSuffix(options) - const pages = document.pages - .map((page) => renderHtmlPage(page, options, diagnostics)) - .join("\n") - - const content = - `\n\n\n\n` + - `\n\n\n` + - `${pages}\n\n` - - return { - target: "html", - pageCount: document.pageCount, - diagnostics, - content, - } -} - -/** 打印样式表。 */ -function printCss(unit: string): string { - return [ - "* { box-sizing: border-box; margin: 0; padding: 0; }", - "body { background: #f5f5f5; }", - ".rd-page {", - " position: relative;", - " background: white;", - " margin: 0 auto;", - " box-shadow: 0 1px 3px rgba(0,0,0,0.2);", - " page-break-after: always;", - "}", - ".rd-node { position: absolute; overflow: hidden; }", - ".rd-text { display: flex; }", - ".rd-table { position: absolute; }", - ".rd-table table { border-collapse: collapse; width: 100%; }", - ".rd-table th, .rd-table td {", - " padding: 0;", - " overflow: hidden;", - " white-space: nowrap;", - "}", - "@media print {", - " body { background: white; }", - " .rd-page { box-shadow: none; margin: 0; }", - "}", - "", - ].join("\n") -} - -/** 渲染单页为
。 */ -function renderHtmlPage( - page: LayoutPage, - options: RenderOptions, - diagnostics: Diagnostic[], -): string { - const width = toUnit(page.width, options) - const height = toUnit(page.height, options) - const unit = unitSuffix(options) - const nodes = page.nodes - .map((node) => renderHtmlNode(node, options, diagnostics)) - .join("\n") - - return ( - `
\n` + - `${nodes}\n` + - `
` - ) -} - -/** 渲染单个布局节点为 HTML 元素。 */ -function renderHtmlNode( - node: LayoutNode, - options: RenderOptions, - diagnostics: Diagnostic[], -): string { - const x = toUnit(node.frame.x, options) - const y = toUnit(node.frame.y, options) - const width = toUnit(node.frame.width, options) - const height = toUnit(node.frame.height, options) - const unit = unitSuffix(options) - const pos = `position:absolute;left:${x}${unit};top:${y}${unit};width:${width}${unit};height:${height}${unit}` - const id = escapeAttr(node.id) - - switch (node.type) { - case "text": { - const content = node.content - if (content?.kind !== "text") return "" - const css = styleToCss(node.style) - const text = escapeHtml(content.text).replace(/\n/g, "
") - return ( - `
` + - `${text}
` - ) - } - case "rect": { - const css = styleToCss(node.style) - return `
` - } - case "line": { - const content = node.content - if (content?.kind !== "line") return "" - const color = node.style.color ?? "#000000" - const thickness = toUnit(content.thickness, options) - const isVertical = content.direction === "vertical" - const lineCss = - isVertical - ? `border-left:${thickness}${unit} solid ${color}` - : `border-top:${thickness}${unit} solid ${color}` - return `
` - } - case "image": { - const content = node.content - if (content?.kind !== "image") return "" - if (!content.src) { - diagnostics.push({ - severity: "warning", - code: "render.image-missing", - message: `图片元素 "${node.id}" 缺少 src`, - elementId: node.id, - }) - return "" - } - const fit = content.fit === "fill" ? "100% 100%" : content.fit - return ( - `
` + - `` + - `
` - ) - } - case "table": { - const content = node.content - if (content?.kind !== "table") return "" - return renderHtmlTable(node, content, options) - } - default: { - diagnostics.push({ - severity: "warning", - code: "render.unknown-node", - message: `不支持的节点类型 "${node.type}",已跳过`, - elementId: node.id, - }) - return "" - } - } -} - -/** 渲染表格节点为 HTML 表格。 */ -function renderHtmlTable( - node: LayoutNode, - content: TableContent, - options: RenderOptions, -): string { - const x = toUnit(node.frame.x, options) - const y = toUnit(node.frame.y, options) - const width = toUnit(node.frame.width, options) - const height = toUnit(node.frame.height, options) - const unit = unitSuffix(options) - const id = escapeAttr(node.id) - - const colgroup = content.columns - .map((col) => ``) - .join("") - - const headerRow = content.showHeader - ? `${content.columns - .map((col) => { - const align = `text-align:${col.align}` - return `${escapeHtml(col.header ?? "")}` - }) - .join("")}` - : "" - - const bodyRows = content.rows - .map((row) => { - const cells = content.columns - .map((col) => { - const cell = row.cells.find((c) => c.columnId === col.id) - const align = `text-align:${col.align}` - return `${escapeHtml(cell?.text ?? "")}` - }) - .join("") - return `${cells}` - }) - .join("") - - const borderCss = content.showGrid ? "border-collapse:collapse;" : "" - const cellBorder = content.showGrid ? "border:1px solid #000;" : "" - - return ( - `
` + - `` + - `${colgroup}` + - (content.showHeader ? `${headerRow}` : "") + - `${bodyRows}` + - `
` - ) -} - -function escapeHtml(text: string): string { - return text - .replace(/&/g, "&") - .replace(//g, ">") -} - -function escapeAttr(value: string): string { - return value - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) -} diff --git a/code/one-designer/packages/report-renderer/src/index.ts b/code/one-designer/packages/report-renderer/src/index.ts deleted file mode 100644 index d411cef5..00000000 --- a/code/one-designer/packages/report-renderer/src/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @report/renderer 公共入口(对应设计文档 §4.4、§3.3)。 - * - * Renderer 只消费 LayoutDocument,把分页结果绘制成 HTML / SVG / PDF。 - * 所有 Renderer 共享同一份布局结果,保证分页结构一致(§15)。 - */ -export type { - RenderTarget, - RenderResult, - TextRenderResult, - BinaryRenderResult, - RenderOptions, - Renderer, -} from "./types.js" - -// 样式与坐标共享工具 -export { styleToCss, styleToSvgTextAttrs, toUnit, unitSuffix } from "./style.js" - -// SVG Renderer -export type { SvgRenderer } from "./svg.js" -export { createSvgRenderer, renderSvg } from "./svg.js" - -// HTML Renderer -export type { HtmlRenderer } from "./html.js" -export { createHtmlRenderer, renderHtml } from "./html.js" - -// PDF Renderer 契约 -export type { PdfBackend, PdfRenderer } from "./pdf.js" -export { createPdfRenderer } from "./pdf.js" diff --git a/code/one-designer/packages/report-renderer/src/pdf.ts b/code/one-designer/packages/report-renderer/src/pdf.ts deleted file mode 100644 index 577f74e6..00000000 --- a/code/one-designer/packages/report-renderer/src/pdf.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** - * PDF Renderer 契约(对应设计文档 §4.4、§3.3)。 - * - * PDF 的具体后端可运行在浏览器或 Node/服务端,但都遵循统一的 - * Renderer 接口。本包只提供契约与一个"占位"实现,真实 PDF 生成 - * 由阶段 5 结合部署环境确定后端(§16)。 - * - * 设计要点: - * - PDF 是二进制输出,结果携带 Uint8Array。 - * - 后端缺失或未配置时返回诊断而非抛异常(§13)。 - */ -import type { Diagnostic } from "@report/core" -import type { LayoutDocument } from "@report/layout" -import type { BinaryRenderResult, RenderOptions } from "./types.js" - -/** - * PDF 后端契约。 - * - * 宿主实现此接口,把 LayoutDocument 转成 PDF 字节。 - * 典型后端:浏览器端 pdf-lib / jsPDF,Node 端 Puppeteer / pdfkit。 - */ -export interface PdfBackend { - /** 后端名称,用于诊断与日志。 */ - readonly name: string - /** 把布局文档渲染为 PDF 字节。 */ - render(document: LayoutDocument, options?: RenderOptions): Uint8Array -} - -/** PDF 渲染器。 */ -export interface PdfRenderer { - render(document: LayoutDocument, options?: RenderOptions): BinaryRenderResult -} - -/** 创建 PDF 渲染器。 */ -export function createPdfRenderer(backend?: PdfBackend): PdfRenderer { - return { - render(document, options = {}) { - const diagnostics: Diagnostic[] = [] - if (!backend) { - diagnostics.push({ - severity: "warning", - code: "render.pdf-backend-missing", - message: - "未配置 PDF 后端;请注入 PdfBackend(如 pdf-lib / jsPDF / Puppeteer)。" + - "当前返回空字节。", - }) - return { - target: "pdf", - pageCount: document.pageCount, - diagnostics, - bytes: new Uint8Array(0), - } - } - - try { - const bytes = backend.render(document, options) - return { - target: "pdf", - pageCount: document.pageCount, - diagnostics, - bytes, - } - } catch (error) { - diagnostics.push({ - severity: "error", - code: "render.pdf-backend-error", - message: `PDF 后端 "${backend.name}" 渲染失败:${(error as Error)?.message ?? String(error)}`, - }) - return { - target: "pdf", - pageCount: document.pageCount, - diagnostics, - bytes: new Uint8Array(0), - } - } - }, - } -} diff --git a/code/one-designer/packages/report-renderer/src/style.ts b/code/one-designer/packages/report-renderer/src/style.ts deleted file mode 100644 index 164544f0..00000000 --- a/code/one-designer/packages/report-renderer/src/style.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 样式与坐标转换的共享工具(HTML / SVG 共用)。 - * - * 布局结果内部统一使用 mm;SVG/HTML 输出按需换算为 px。 - * 样式统一转成 CSS 声明,保证各 Renderer 视觉一致(§15)。 - */ -import type { ResolvedStyle } from "@report/core" -import { mmToPx } from "@report/layout" -import type { RenderOptions } from "./types.js" - -/** 把 mm 值按目标单位换算为数值(SVG/HTML 里直接写数字)。 */ -export function toUnit(value: number, options: RenderOptions): number { - return options.unit === "px" ? mmToPx(value) : value -} - -/** 单位后缀。 */ -export function unitSuffix(options: RenderOptions): string { - return options.unit === "px" ? "px" : "mm" -} - -/** - * 把已解析样式转成 CSS 声明字符串。 - * - * 字号在文档中是 pt,HTML/SVG 里也以 pt 表达,保证与布局测量一致。 - * 边框只输出四边统一值;逐边覆盖的边框由 Renderer 按需处理。 - */ -export function styleToCss(style: ResolvedStyle): string { - const parts: string[] = [] - parts.push(`font-family:${style.fontFamily}`) - parts.push(`font-size:${style.fontSize}pt`) - parts.push(`font-weight:${style.fontWeight}`) - parts.push(`font-style:${style.fontStyle}`) - parts.push(`line-height:${style.lineHeight}`) - parts.push(`color:${style.color}`) - if (style.background && style.background !== "transparent") { - parts.push(`background:${style.background}`) - } - parts.push(`text-align:${style.align}`) - parts.push(`text-decoration:${style.textDecoration}`) - if (style.border) { - const width = style.border.width ?? 0.1 - const color = style.border.color ?? "#000000" - const lineStyle = style.border.style ?? "solid" - parts.push(`border:${width}mm ${lineStyle} ${color}`) - } - return parts.join(";") -} - -/** 把已解析样式转成 SVG 文本属性(fill / font-size 等)。 */ -export function styleToSvgTextAttrs(style: ResolvedStyle): Record { - const attrs: Record = { - fill: style.color, - "font-family": style.fontFamily, - "font-size": `${style.fontSize}pt`, - "font-weight": String(style.fontWeight), - "font-style": style.fontStyle, - } - if (style.textDecoration === "underline") attrs["text-decoration"] = "underline" - if (style.textDecoration === "line-through") attrs["text-decoration"] = "line-through" - return attrs -} diff --git a/code/one-designer/packages/report-renderer/src/svg.ts b/code/one-designer/packages/report-renderer/src/svg.ts deleted file mode 100644 index 45676db2..00000000 --- a/code/one-designer/packages/report-renderer/src/svg.ts +++ /dev/null @@ -1,293 +0,0 @@ -/** - * SVG Renderer(对应设计文档 §4.4、§3.3)。 - * - * 消费 LayoutDocument,产出可直接打印的 SVG 文档字符串。 - * SVG 的 viewBox 以 mm 为单位标注,便于与打印尺寸精确对应。 - */ -import type { Diagnostic } from "@report/core" -import type { - LayoutDocument, - LayoutNode, - LayoutPage, - TableContent, -} from "@report/layout" -import type { RenderOptions, TextRenderResult } from "./types.js" -import { styleToSvgTextAttrs } from "./style.js" - -/** SVG 渲染器。 */ -export interface SvgRenderer { - render(document: LayoutDocument, options?: RenderOptions): TextRenderResult -} - -/** 创建 SVG 渲染器。 */ -export function createSvgRenderer(): SvgRenderer { - return { - render(document, options = {}) { - return renderSvg(document, options) - }, - } -} - -/** - * 把布局文档渲染为 SVG。 - * - * 每个页面产出一个 ,包含在单个 下, - * 页面之间用空行分隔,便于宿主逐页切分或整体打印。 - */ -export function renderSvg(document: LayoutDocument, options: RenderOptions = {}): TextRenderResult { - const diagnostics: Diagnostic[] = [] - const pages = document.pages.map((page) => renderSvgPage(page, options, diagnostics)) - - const content = pages.join("\n\n") - return { - target: "svg", - pageCount: document.pageCount, - diagnostics, - content, - } -} - -/** 渲染单页为 元素。 */ -function renderSvgPage( - page: LayoutPage, - options: RenderOptions, - diagnostics: Diagnostic[], -): string { - const width = page.width - const height = page.height - const nodes = page.nodes.map((node) => renderSvgNode(node, options, diagnostics)).join("\n") - - return ( - `\n` + - `\n` + - `${nodes}\n` + - `` - ) -} - -/** 渲染单个布局节点为 SVG 元素。 */ -function renderSvgNode( - node: LayoutNode, - options: RenderOptions, - diagnostics: Diagnostic[], -): string { - const { x, y, width, height } = node.frame - const id = escapeAttr(node.id) - - switch (node.type) { - case "text": { - const content = node.content - if (content?.kind !== "text") return "" - const attrs = styleToSvgTextAttrs(node.style) - const lines = content.lines - // 逐行输出 ,行高按 lineHeight(mm)累加 - const lineHeightMm = content.lineHeight - const anchor = node.style.align === "center" ? "middle" : node.style.align === "right" ? "end" : "start" - const textX = anchor === "start" ? x : anchor === "middle" ? x + width / 2 : x + width - const rows = lines - .map((line, i) => { - const ly = y + lineHeightMm * (i + 1) - return ( - `${escapeText(line)}` - ) - }) - .join("\n") - return rows - } - case "rect": { - const fill = node.style.background && node.style.background !== "transparent" - ? node.style.background - : "none" - const stroke = node.style.border ? (node.style.border.color ?? "#000000") : "none" - const strokeWidth = node.style.border ? (node.style.border.width ?? 0.1) : 0 - return ( - `` - ) - } - case "line": { - const content = node.content - if (content?.kind !== "line") return "" - const color = node.style.color ?? "#000000" - const thickness = content.thickness - const direction = content.direction - if (direction === "vertical") { - const cx = x + width / 2 - return ( - `` - ) - } - const cy = y + height / 2 - return ( - `` - ) - } - case "image": { - const content = node.content - if (content?.kind !== "image") return "" - // SVG 图片:若无 src 则记录诊断并跳过 - if (!content.src) { - diagnostics.push({ - severity: "warning", - code: "render.image-missing", - message: `图片元素 "${node.id}" 缺少 src`, - elementId: node.id, - }) - return "" - } - const preserve = fitToPreserve(content.fit) - return ( - `` - ) - } - case "table": { - const content = node.content - if (content?.kind !== "table") return "" - return renderSvgTable(node, content, options, diagnostics) - } - default: { - // 未知节点类型:不抛异常,记录诊断并跳过(§13) - diagnostics.push({ - severity: "warning", - code: "render.unknown-node", - message: `不支持的节点类型 "${node.type}",已跳过`, - elementId: node.id, - }) - return "" - } - } -} - -/** 渲染表格节点(含表头、行、单元格网格)。 */ -function renderSvgTable( - node: LayoutNode, - content: TableContent, - options: RenderOptions, - diagnostics: Diagnostic[], -): string { - const { x, y, width } = node.frame - const parts: string[] = [] - const headerHeight = content.headerHeight - const rowHeight = content.rowHeight - - // 表格外框 - if (content.showGrid) { - parts.push( - ``, - ) - } - - // 列分隔线 - if (content.showGrid) { - let cx = x - for (const col of content.columns) { - cx += col.width - parts.push( - ``, - ) - } - } - - // 表头 - if (content.showHeader) { - const rowY = y - for (const col of content.columns) { - if (col.header === undefined) continue - const colX = x + col.x - const attrs = styleToSvgTextAttrs({ ...defaultCellStyle(), align: col.align }) - const anchor = col.align === "center" ? "middle" : col.align === "right" ? "end" : "start" - const textX = anchor === "start" ? colX : anchor === "middle" ? colX + col.width / 2 : colX + col.width - parts.push( - `${escapeText(col.header)}`, - ) - } - if (content.showGrid) { - parts.push( - ``, - ) - } - } - - // 数据行 - let rowCursor = y + (content.showHeader ? headerHeight : 0) - for (const row of content.rows) { - const rowH = row.height - for (const cell of row.cells) { - const col = content.columns.find((c) => c.id === cell.columnId) - if (!col) continue - const colX = x + col.x - const align = col.align - const anchor = align === "center" ? "middle" : align === "right" ? "end" : "start" - const textX = anchor === "start" ? colX : anchor === "middle" ? colX + col.width / 2 : colX + col.width - const attrs = styleToSvgTextAttrs({ ...defaultCellStyle(), align }) - parts.push( - `${escapeText(cell.text)}`, - ) - } - if (content.showGrid) { - parts.push( - ``, - ) - } - rowCursor += rowH - } - - return parts.join("\n") -} - -function defaultCellStyle(): import("@report/core").ResolvedStyle { - return { - fontFamily: "sans-serif", - fontSize: 10, - fontWeight: "normal", - fontStyle: "normal", - lineHeight: 1.2, - color: "#000000", - background: "transparent", - padding: { top: 0, right: 0, bottom: 0, left: 0 }, - align: "left", - verticalAlign: "top", - textDecoration: "none", - } -} - -function fitToPreserve(fit: "contain" | "cover" | "fill" | "none"): string { - switch (fit) { - case "contain": return "xMidYMid meet" - case "cover": return "xMidYMid slice" - case "none": return "none" - default: return "none" - } -} - -function attrsToStr(attrs: Record): string { - return Object.entries(attrs) - .map(([k, v]) => `${k}="${escapeAttr(v)}"`) - .join(" ") -} - -function escapeText(text: string): string { - return text - .replace(/&/g, "&") - .replace(//g, ">") -} - -function escapeAttr(value: string): string { - return value - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) -} diff --git a/code/one-designer/packages/report-renderer/src/types.ts b/code/one-designer/packages/report-renderer/src/types.ts deleted file mode 100644 index 8d68687b..00000000 --- a/code/one-designer/packages/report-renderer/src/types.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Renderer 统一契约(对应设计文档 §4.4、§3.3)。 - * - * Renderer 只消费 LayoutDocument,绝不重新计算分页。 - * 所有 Renderer 针对同一份 LayoutDocument 产出结构一致的输出, - * 以保证 HTML / SVG / PDF 的分页结果一致(§15)。 - */ -import type { LayoutDocument } from "@report/layout" - -/** 渲染目标格式。 */ -export type RenderTarget = "html" | "svg" | "pdf" - -/** - * 渲染器输出。 - * - * 各 Renderer 的具体产物不同(HTML 字符串、SVG 字符串、PDF 字节), - * 但都遵循这一统一契约,便于宿主在多个目标间切换。 - */ -export interface RenderResult { - /** 目标格式。 */ - target: RenderTarget - /** 分页结果快照(供宿主校验分页一致性)。 */ - pageCount: number - /** 渲染过程中的诊断(缺失资源、不支持的节点类型等)。 */ - diagnostics: import("@report/core").Diagnostic[] -} - -/** HTML / SVG 这类文本型输出的结果。 */ -export interface TextRenderResult extends RenderResult { - /** 产出的文本(HTML 或 SVG 文档字符串)。 */ - content: string -} - -/** 二进制型输出(PDF)的结果。 */ -export interface BinaryRenderResult extends RenderResult { - /** 产出的字节(PDF 等)。 */ - bytes: Uint8Array -} - -/** 渲染选项。 */ -export interface RenderOptions { - /** - * 目标单位。默认 "mm"。 - * - * 布局结果内部统一为 mm;SVG 输出通常按 mm 标注 viewBox 便于打印, - * HTML 输出可按 mm 或 px。px 换算走 1in = 96px。 - */ - unit?: "mm" | "px" - /** 是否内联样式(默认 true,便于打印与独立保存)。 */ - inlineStyle?: boolean -} - -/** - * Renderer 契约。 - * - * 每个目标格式实现一个 Renderer。PDF 的具体后端可在浏览器或 - * Node/服务端实现,但都必须实现本契约(§4.4)。 - */ -export interface Renderer { - /** 目标格式。 */ - readonly target: RenderTarget - /** 把布局文档渲染为目标格式。 */ - render(document: LayoutDocument, options?: RenderOptions): TResult -} diff --git a/code/one-designer/packages/report-renderer/tests/renderer.test.ts b/code/one-designer/packages/report-renderer/tests/renderer.test.ts deleted file mode 100644 index 7af64d97..00000000 --- a/code/one-designer/packages/report-renderer/tests/renderer.test.ts +++ /dev/null @@ -1,220 +0,0 @@ -/** - * Renderer 一致性测试(对应设计文档 §15 的 - * "HTML、SVG、PDF Renderer 的公共布局结果一致性测试")。 - * - * 核心断言:同一份 LayoutDocument 经 HTML / SVG 渲染后, - * 分页结构一致(页数相同、节点都能找到)。 - */ -import { describe, expect, it } from "vitest" -import { createDocument, createTableElement, type ReportDocument } from "@report/core" -import { createEstimateMeasurer, createPassthroughFontResolver } from "@report/layout" -import { layoutDocument } from "@report/layout" -import { renderHtml, renderSvg, createPdfRenderer } from "../src/index.js" -import type { RenderContext } from "@report/layout" - -const measurer = createEstimateMeasurer() -const fontResolver = createPassthroughFontResolver() - -async function layout(doc: ReportDocument, context: RenderContext) { - return layoutDocument(doc, context, { textMeasurer: measurer, fontResolver }) -} - -/** 构造一份含页眉、文本、明细表、页脚的报表文档。 */ -function sampleDoc(): ReportDocument { - const doc = createDocument({ name: "渲染测试" }) - doc.datasets = { sales: { id: "sales" } } - - const header = doc.sections.find((s) => s.kind === "page-header")! - header.children.push({ - id: "h1", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 8 }, - props: { text: "销售单" }, - }) - - const detail = doc.sections.find((s) => s.kind === "detail")! - detail.children.push( - createTableElement("tbl1", { x: 0, y: 0, width: 180, height: 20 }, "sales", [ - { id: "c1", width: 90, header: "商品", binding: { field: "name" } }, - { id: "c2", width: 90, header: "金额", binding: { field: "amount" }, align: "right" }, - ]), - ) - - const footer = doc.sections.find((s) => s.kind === "page-footer")! - footer.children.push({ - id: "f1", - type: "text", - frame: { x: 0, y: 0, width: 100, height: 6 }, - binding: { expression: "'第 ' + page.pageNumber + ' 页'" }, - }) - - return doc -} - -const ROWS = [ - { name: "苹果", amount: 100 }, - { name: "香蕉", amount: 200 }, - { name: "橙子", amount: 300 }, -] - -describe("HTML / SVG 分页一致性", () => { - it("同一文档渲染为 HTML 与 SVG 时页数一致", async () => { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const html = renderHtml(result) - const svg = renderSvg(result) - - expect(html.target).toBe("html") - expect(svg.target).toBe("svg") - expect(html.pageCount).toBe(result.pageCount) - expect(svg.pageCount).toBe(result.pageCount) - expect(html.pageCount).toBe(svg.pageCount) - }) - - it("HTML 输出包含与页数一致的 .rd-page 容器", async () => { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const html = renderHtml(result) - const pageCount = (html.content.match(/class="rd-page"/g) ?? []).length - expect(pageCount).toBe(result.pageCount) - }) - - it("SVG 输出包含与页数一致的 元素", async () => { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const svg = renderSvg(result) - const svgCount = (svg.content.match(/ { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const html = renderHtml(result) - const svg = renderSvg(result) - - // 页眉文本 "销售单" 应出现在两种输出中 - expect(html.content).toContain("销售单") - expect(svg.content).toContain("销售单") - }) - - it("明细表数据在 HTML 与 SVG 中都被渲染", async () => { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const html = renderHtml(result) - const svg = renderSvg(result) - - expect(html.content).toContain("苹果") - expect(html.content).toContain("橙子") - expect(svg.content).toContain("苹果") - expect(svg.content).toContain("橙子") - }) - - it("页脚页码占位符在渲染前已被替换", async () => { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const html = renderHtml(result) - // 页脚应有 "第 1 页" 而非原始占位符 - expect(html.content).toContain("第 1 页") - expect(html.content).not.toContain("{pageNumber}") - }) -}) - -describe("多页渲染", () => { - it("多页文档在 HTML 与 SVG 中页数一致", async () => { - const doc = sampleDoc() - const manyRows = Array.from({ length: 200 }, (_, i) => ({ - name: `商品${i}`, - amount: i, - })) - const result = await layout(doc, { data: { sales: manyRows }, parameters: {} }) - - expect(result.pageCount).toBeGreaterThan(1) - - const html = renderHtml(result) - const svg = renderSvg(result) - - const htmlPages = (html.content.match(/class="rd-page"/g) ?? []).length - const svgPages = (svg.content.match(/ { - it("SVG 使用 mm 标注宽度和 viewBox", async () => { - const doc = sampleDoc() - const result = await layout(doc, { data: { sales: ROWS }, parameters: {} }) - - const svg = renderSvg(result) - const page = result.pages[0]! - // width 与 height 用 mm,viewBox 用无单位数值 - expect(svg.content).toContain(`width="${page.width}mm"`) - expect(svg.content).toContain(`viewBox="0 0 ${page.width} ${page.height}"`) - }) - - it("矩形节点渲染为 ", async () => { - const doc = createDocument({ name: "矩形测试" }) - const detail = doc.sections.find((s) => s.kind === "detail")! - detail.children.push({ - id: "r1", - type: "rect", - frame: { x: 5, y: 5, width: 50, height: 20 }, - }) - const result = await layout(doc, { data: {}, parameters: {} }) - - const svg = renderSvg(result) - expect(svg.content).toContain(" { - it("未配置后端时返回诊断而非抛异常", () => { - const result = createPdfRenderer().render({ - pages: [], - diagnostics: [], - pageCount: 0, - }) - expect(result.target).toBe("pdf") - expect(result.bytes).toBeInstanceOf(Uint8Array) - expect(result.bytes.length).toBe(0) - expect(result.diagnostics.some((d) => d.code === "render.pdf-backend-missing")).toBe(true) - }) - - it("后端抛错时返回错误诊断", () => { - const backend = { - name: "mock", - render: () => { - throw new Error("boom") - }, - } - const result = createPdfRenderer(backend).render({ - pages: [], - diagnostics: [], - pageCount: 0, - }) - expect(result.diagnostics.some((d) => d.code === "render.pdf-backend-error")).toBe(true) - }) - - it("后端正常时返回字节", () => { - const backend = { - name: "mock", - render: () => new Uint8Array([1, 2, 3]), - } - const result = createPdfRenderer(backend).render({ - pages: [], - diagnostics: [], - pageCount: 0, - }) - expect(result.bytes.length).toBe(3) - expect(result.diagnostics).toHaveLength(0) - }) -}) diff --git a/code/one-designer/packages/report-renderer/tsconfig.json b/code/one-designer/packages/report-renderer/tsconfig.json deleted file mode 100644 index 23cc1372..00000000 --- a/code/one-designer/packages/report-renderer/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src", - "types": ["node"] - }, - "include": ["src/**/*.ts"], - "exclude": ["node_modules", "dist", "tests"] -} diff --git a/code/one-designer/packages/report-renderer/tsconfig.test.json b/code/one-designer/packages/report-renderer/tsconfig.test.json deleted file mode 100644 index 6cefc694..00000000 --- a/code/one-designer/packages/report-renderer/tsconfig.test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "noEmit": true, - "types": ["node", "vitest/globals"] - }, - "include": ["src/**/*.ts", "tests/**/*.ts", "*.config.ts"] -} diff --git a/code/one-designer/packages/report-renderer/tsup.config.ts b/code/one-designer/packages/report-renderer/tsup.config.ts deleted file mode 100644 index be47bf93..00000000 --- a/code/one-designer/packages/report-renderer/tsup.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "tsup" - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["esm", "cjs"], - dts: true, - sourcemap: true, - clean: true, - treeshake: true, - target: "es2022", -}) diff --git a/code/one-designer/pnpm-lock.yaml b/code/one-designer/pnpm-lock.yaml deleted file mode 100644 index 3d725f2d..00000000 --- a/code/one-designer/pnpm-lock.yaml +++ /dev/null @@ -1,2569 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - devDependencies: - '@types/node': - specifier: ^22.10.2 - version: 22.20.4 - tsup: - specifier: ^8.3.5 - version: 8.5.1(postcss@8.5.28)(typescript@5.9.3) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - - apps/demo: - dependencies: - '@report/core': - specifier: workspace:* - version: link:../../packages/report-core - '@report/designer': - specifier: workspace:* - version: link:../../packages/report-designer - '@report/designer-vue': - specifier: workspace:* - version: link:../../packages/report-designer-vue - '@report/layout': - specifier: workspace:* - version: link:../../packages/report-layout - '@report/renderer': - specifier: workspace:* - version: link:../../packages/report-renderer - vue: - specifier: ^3.5.13 - version: 3.5.43(typescript@5.9.3) - devDependencies: - '@vitejs/plugin-vue': - specifier: ^5.2.1 - version: 5.2.4(vite@5.4.21(@types/node@22.20.4))(vue@3.5.43(typescript@5.9.3)) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vite: - specifier: ^5.4.11 - version: 5.4.21(@types/node@22.20.4) - - packages/report-core: - devDependencies: - tsup: - specifier: ^8.3.5 - version: 8.5.1(postcss@8.5.28)(typescript@5.9.3) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - - packages/report-designer: - dependencies: - '@report/core': - specifier: workspace:* - version: link:../report-core - '@report/layout': - specifier: workspace:* - version: link:../report-layout - devDependencies: - '@report/renderer': - specifier: workspace:* - version: link:../report-renderer - tsup: - specifier: ^8.3.5 - version: 8.5.1(postcss@8.5.28)(typescript@5.9.3) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - - packages/report-designer-vue: - dependencies: - '@report/core': - specifier: workspace:* - version: link:../report-core - '@report/designer': - specifier: workspace:* - version: link:../report-designer - '@report/layout': - specifier: workspace:* - version: link:../report-layout - devDependencies: - '@vitejs/plugin-vue': - specifier: ^5.2.1 - version: 5.2.4(vite@5.4.21(@types/node@22.20.4))(vue@3.5.43(typescript@5.9.3)) - '@vue/test-utils': - specifier: ^2.4.6 - version: 2.5.1(@vue/compiler-dom@3.5.43)(@vue/server-renderer@3.5.43)(vue@3.5.43(typescript@5.9.3)) - jsdom: - specifier: ^25.0.1 - version: 25.0.1 - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vite: - specifier: ^5.4.11 - version: 5.4.21(@types/node@22.20.4) - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - vue: - specifier: ^3.5.13 - version: 3.5.43(typescript@5.9.3) - vue-tsc: - specifier: ^2.1.10 - version: 2.2.12(typescript@5.9.3) - - packages/report-expression: - dependencies: - '@report/core': - specifier: workspace:* - version: link:../report-core - devDependencies: - tsup: - specifier: ^8.3.5 - version: 8.5.1(postcss@8.5.28)(typescript@5.9.3) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - - packages/report-layout: - dependencies: - '@report/core': - specifier: workspace:* - version: link:../report-core - '@report/expression': - specifier: workspace:* - version: link:../report-expression - devDependencies: - tsup: - specifier: ^8.3.5 - version: 8.5.1(postcss@8.5.28)(typescript@5.9.3) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - - packages/report-renderer: - dependencies: - '@report/core': - specifier: workspace:* - version: link:../report-core - '@report/layout': - specifier: workspace:* - version: link:../report-layout - devDependencies: - tsup: - specifier: ^8.3.5 - version: 8.5.1(postcss@8.5.28)(typescript@5.9.3) - typescript: - specifier: ^5.7.2 - version: 5.9.3 - vitest: - specifier: ^2.1.8 - version: 2.1.9(@types/node@22.20.4)(jsdom@25.0.1) - -packages: - - '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} - - '@babel/helper-string-parser@7.29.7': - resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.9': - resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/types@7.29.8': - resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} - engines: {node: '>=6.9.0'} - - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} - engines: {node: '>=18'} - - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} - engines: {node: '>=18'} - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.27.7': - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.27.7': - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.27.7': - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.27.7': - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.27.7': - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.7': - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.27.7': - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.7': - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.27.7': - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.27.7': - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.27.7': - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.27.7': - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.27.7': - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.27.7': - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.7': - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.27.7': - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.27.7': - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.7': - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.7': - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.7': - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.7': - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.7': - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.27.7': - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.27.7': - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.27.7': - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.27.7': - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.6.0': - resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@napi-rs/lzma-linux-x64-gnu@1.5.1': - resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} - engines: {node: ^22.20 || ^24.12 || >=25} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@one-ini/wasm@0.2.1': - resolution: {integrity: sha512-TUqERXGNTifZ9y2g3wPxQrw3HpHv/02DsW3D90T9x0hhonrL1ZqpSmNrU2XkoIq0fP1N6gZfVQzy2Fw1ZvGBNg==} - - '@rollup/rollup-android-arm-eabi@4.63.4': - resolution: {integrity: sha512-I+BSHzTAhKN2n7ZwGZsegGcZjDpLqFOMAtJz/u6uFGe0pUFbq56dEHjqJV/ZUdRJtNXNxA+hREUatZBvMR3Oiw==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.63.4': - resolution: {integrity: sha512-pu3BdjS2LtEzRu2elmGzS3fIeWSZy4BMDIaLNwjorO76+k2d0LMluijhsDx3KQyQBQ/lLUZCQA9/s6csvUfuhw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.63.4': - resolution: {integrity: sha512-xfSrj9MHnWK9GaSqT9U0ImHtH/N8WZlHLx4cZHiuLcqs640hvZ3hLPd5UR2AZS57FaE8HrRUSpltbZdWRxHiDA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.63.4': - resolution: {integrity: sha512-bqU99PLJb/dqb3S0GIMdeuyAEETSUgZBoqXYd3Sd+WCsV+MmPhnN6JrotWyir31+QgH7EvvE5/mwGJlEoci8Fw==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.63.4': - resolution: {integrity: sha512-JinsFZ5G40oXQb+sUuiA5x689vhr6dDYK0H0NL+rwKdL6CqnmYN8PE4ZwfRSoIjrCxqTQG/SLfTtSvHeGxoVlw==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.63.4': - resolution: {integrity: sha512-GAdA4UxpiNm27cLHr2GqXBpAD0x9FqwYBY7/YSP0Ss0/PNi4k8gbviqpIpYbVSRBaS2ZcegXEzgTQMbRNCwxCw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.63.4': - resolution: {integrity: sha512-qDd6NoA1znaLjp4jR5U/KWCdLAKDJNB8W9ChbbDaKbo0xA+Atln5HK6LFCZ4oJQpemtRZA288DCirFRjrspptw==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.63.4': - resolution: {integrity: sha512-WtB5Tz5KTNINb8ZA+8sQ7bmjuS1JrRT7YverYIhUGdWWDlpzVWmIwuZE+jidkEXUn1l0zrEkaIMa8dHF3NGcsA==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.63.4': - resolution: {integrity: sha512-VcQ3L1tjnkKzWjryAVaFhHEWcqOfICX9uxVVoDzm2t0DpgKRHd2zOpVrJc0xsWeBZcBFyYROCIBdyR/fS174pg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.63.4': - resolution: {integrity: sha512-6+ZQX6P5s0cMDN2Ypb8Lbm2+/sZYmZjdaYny992ujUU9UKi/4CWoJWsl1pNvjWJHNHGK51m+jKGLlh1ylb2ifQ==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.63.4': - resolution: {integrity: sha512-D72ZnvkFkBXOfzMMQLcwfPLyGkKb7HZ9/mf97B7v6/P5Lbv4oFOtSY/uHbS8lH6uKUOxoKiuokdb50XZSzzbJw==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.63.4': - resolution: {integrity: sha512-piU6BxeqA3O9KSu3kRCIQQtNqFFaTu21SEV4FwaRZowpnj3bLaWPZHw+xFqCs0XlJ+aOH3PTRWGoglH+mKA/OA==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.63.4': - resolution: {integrity: sha512-/5PGpHwqt2EEEOUs1XwzubE/ucr0dWDQ+to3zqi4Ds7EWpwtQ79wXc4JBoxqj/OwpawTsKWzJxHfSuBOq3DrWA==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.63.4': - resolution: {integrity: sha512-cX3beZDLWt7G2oJF+nhChiT+qtaihs+S2xi7ziGmVB+2pwPng6D0Ed0HmElQOgv2UsUmSJJLGwpBao/3TDx3VA==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.63.4': - resolution: {integrity: sha512-1uz2mGWHyptR7DgHHrlbdRAjXK7v7elGZ9lMja910/RP+ZYbX6xAmCiU9UZSX4hqmgtHMv6lr5l3kq1HIOpcag==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.63.4': - resolution: {integrity: sha512-nLS8topojxyz7SRpKR2IODRpQ0XPZ+xaOXvT3+hqK/Uy8Lo5HFgkkIBiIrCu5tL5YqzTvgovGw55PwpahTAGig==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.63.4': - resolution: {integrity: sha512-gs7DRKotr3l3q+jGPQBjH0ng1FjlEDm5ueQrkw5JtQvtLyEIcLASqAEaor56BhkKRzk+IcQzrcanBdb/bBQn8g==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.63.4': - resolution: {integrity: sha512-791ET7W17NnScOZM7h4dX5hYspxE28htPFsb1awY/NRR8+PRNkS53e475rDdxXXDrP+kwnCcNWg9CX5ztn/Aqw==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.63.4': - resolution: {integrity: sha512-iwZQRcmj7g88g3tzefIrQY7qvmuA/cfYwhrDtTBhsmukO4U2huVO5W+86XacUMRvdSFVAc6kZUZy21JaRwiB9w==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.63.4': - resolution: {integrity: sha512-dVHFp9gRWrdTpnqQuGfCwd7hOQDatK1VCP2iWhLY/cGrOQs/ucFzJ6A5SRqbXX12ZDI8EUuejSM5kwg+ja7Png==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.63.4': - resolution: {integrity: sha512-t3NlauOW6gxZVVFcBEnO62Cb4wbyDFL416gTg1uFI/2tgqYQlf69FbSE115Ajre9I+c26Lk4mcmdFUsS/DGifQ==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.63.4': - resolution: {integrity: sha512-xWuIaSye5FWZF8+UYtVEcHtRJDN5kN9Kfgxx3Kq8XIov9KSKbc1fiqQCm90SKrgQbUXZelbnUhnlUJmfSE7P9A==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.63.4': - resolution: {integrity: sha512-9ALJJUOg/ZflMJepVo2PlgsGxSaxN7SQ4Z8GoZfVlarWr6r3rkHUNsd/zAio7p4YMtChSMXPionxej4Hkf6CXQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.63.4': - resolution: {integrity: sha512-blj9z5qx/Pv4WU0W1NMFDB97e0JH5ed+aZGywW8WCvp/NhWX/4PFAq5uu6Q0AebNn+Vo6KzUYDT++JzTT5ojlQ==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.63.4': - resolution: {integrity: sha512-Erx822VRBwLa124shbj+wNXe//BOgMEctDV0m1aqTQdNO1S69DgNUCFKC1RCeZfixs1J31l6igk1ziyXErbigQ==} - cpu: [x64] - os: [win32] - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/node@22.20.4': - resolution: {integrity: sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==} - - '@vitejs/plugin-vue@5.2.4': - resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 - vue: ^3.2.25 - - '@vitest/expect@2.1.9': - resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} - - '@vitest/mocker@2.1.9': - resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} - - '@vitest/runner@2.1.9': - resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} - - '@vitest/snapshot@2.1.9': - resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} - - '@vitest/spy@2.1.9': - resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} - - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} - - '@volar/language-core@2.4.15': - resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==} - - '@volar/source-map@2.4.15': - resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==} - - '@volar/typescript@2.4.15': - resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==} - - '@vue/compiler-core@3.5.43': - resolution: {integrity: sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==} - - '@vue/compiler-dom@3.5.43': - resolution: {integrity: sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==} - - '@vue/compiler-sfc@3.5.43': - resolution: {integrity: sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==} - - '@vue/compiler-ssr@3.5.43': - resolution: {integrity: sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==} - - '@vue/compiler-vue2@2.7.16': - resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} - - '@vue/language-core@2.2.12': - resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/reactivity@3.5.43': - resolution: {integrity: sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==} - - '@vue/runtime-core@3.5.43': - resolution: {integrity: sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==} - - '@vue/runtime-dom@3.5.43': - resolution: {integrity: sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==} - - '@vue/server-renderer@3.5.43': - resolution: {integrity: sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==} - - '@vue/shared@3.5.43': - resolution: {integrity: sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==} - - '@vue/test-utils@2.5.1': - resolution: {integrity: sha512-V/4a99odJ7hapr0bRt35XxljGk8hefq31gSOnlKTcEq2fUeoj2qb+FcpJYfQu4qfYhW9Ug+O2+CZ3QmZ7gXDzA==} - peerDependencies: - '@vue/compiler-dom': 3.x - '@vue/server-renderer': 3.x - vue: 3.x - peerDependenciesMeta: - '@vue/server-renderer': - optional: true - - abbrev@5.0.0: - resolution: {integrity: sha512-/XrFJgzQQQHpti1raDJC6m4ws6aNktmjBlhk8Fdlk7LwCEuDoieEJJY9OFHjfiFJFFRM2tK+Ky/IsfbbmlMu1w==} - engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - - acorn@8.18.0: - resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - - alien-signals@1.0.13: - resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - brace-expansion@2.1.7: - resolution: {integrity: sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==} - - brace-expansion@5.0.12: - resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} - engines: {node: 20 || >=22} - - bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.18' - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} - - check-error@2.1.3: - resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} - engines: {node: '>= 16'} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - config-chain@1.1.13: - resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} - engines: {node: '>=18'} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - data-urls@5.0.0: - resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} - engines: {node: '>=18'} - - de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - editorconfig@3.0.2: - resolution: {integrity: sha512-T0ix8GhtxyKVfUFEcvdNDt3YGqlwkFHbD4/5bgFUDgFmxhI/cSRAeJ87/Sz//Cq8Eam6JX/e23RkoFO71P7aAA==} - engines: {node: '>=20'} - hasBin: true - - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - es-object-atoms@1.1.2: - resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} - engines: {node: '>=18'} - hasBin: true - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - expect-type@1.4.0: - resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} - engines: {node: '>=12.0.0'} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - - form-data@4.0.6: - resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} - engines: {node: '>= 6'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - glob@13.0.6: - resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} - engines: {node: 18 || 20 || >=22} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} - - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - - js-beautify@2.0.3: - resolution: {integrity: sha512-cyFbh3tkPhknnTD/0bLf0T0yy2ZIbqL05mttzbt4y1Zfr7NxqXQZ62dkBLKs3oHH/lpjmDRAnciJiSUyOy8XwQ==} - engines: {node: '>=14'} - hasBin: true - - js-cookie@3.0.8: - resolution: {integrity: sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==} - - jsdom@25.0.1: - resolution: {integrity: sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==} - engines: {node: '>=18'} - peerDependencies: - canvas: ^2.11.2 - peerDependenciesMeta: - canvas: - optional: true - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@11.5.3: - resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} - engines: {node: 20 || >=22} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - minimatch@10.2.6: - resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} - engines: {node: 18 || 20 || >=22} - - minimatch@9.0.9: - resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} - engines: {node: '>=16 || 14 >=14.17'} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.19: - resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nopt@10.0.1: - resolution: {integrity: sha512-df3sBr/6ax9hSGuC3CspvLlbnX8cP5L5nZwXF8cGN8l0zSWR6BvzmQ6jPUKjvo6+/xdpkNvEcucBNUdBeeV13g==} - engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - hasBin: true - - nwsapi@2.2.28: - resolution: {integrity: sha512-IlVB7OS7qrOsVYlpnFIkETjMwT9jwvmocJmmM+GZU/PAB3uGi9Ezd7vcWhWBUnSc0ya4ppmQITOyP1ez9gg8cg==} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - path-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.7: - resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} - engines: {node: '>=12'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss@8.5.28: - resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} - engines: {node: ^10 || ^12 || >=14} - - proto-list@1.2.4: - resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - rollup@4.63.4: - resolution: {integrity: sha512-4U0liVayNIoLp3GFl1FcI8561WepLnZ1rqfraGh7S9B3Ur5F9S283y8Futii7RUU2C/97tOBmBy7nYvhoiOpbQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rrweb-cssom@0.7.1: - resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} - - rrweb-cssom@0.8.0: - resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} - - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} - engines: {node: '>=10'} - hasBin: true - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} - - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} - engines: {node: '>=14.0.0'} - - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} - engines: {node: '>=14.0.0'} - - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} - hasBin: true - - tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} - - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} - engines: {node: '>=18'} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsup@8.5.1: - resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - vite-node@2.1.9: - resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - vite@5.4.21: - resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vitest@2.1.9: - resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.9 - '@vitest/ui': 2.1.9 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - vscode-uri@3.2.0: - resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==} - - vue-component-type-helpers@3.3.11: - resolution: {integrity: sha512-LwcxzeliO9fkQcpJG0PoX8X5kmAhKmH9wkpDLxNabwzkQ9Zeib2YVHwFV4pcWmMLfXVfjr/dSV+DaJ3cIPgSNA==} - - vue-tsc@2.2.12: - resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==} - hasBin: true - peerDependencies: - typescript: '>=5.0.0' - - vue@3.5.43: - resolution: {integrity: sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} - - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation - - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} - engines: {node: '>=18'} - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - ws@8.21.3: - resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} - 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 - - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - -snapshots: - - '@asamuzakjp/css-color@3.2.0': - dependencies: - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - lru-cache: 10.4.3 - - '@babel/helper-string-parser@7.29.7': {} - - '@babel/helper-validator-identifier@7.29.7': {} - - '@babel/parser@7.29.9': - dependencies: - '@babel/types': 7.29.8 - - '@babel/types@7.29.8': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - - '@csstools/color-helpers@5.1.0': {} - - '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/color-helpers': 5.1.0 - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-tokenizer@3.0.4': {} - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.27.7': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.27.7': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-arm@0.27.7': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/android-x64@0.27.7': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.27.7': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.27.7': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.27.7': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.27.7': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.27.7': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-arm@0.27.7': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.27.7': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.27.7': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.27.7': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.27.7': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.27.7': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.27.7': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/linux-x64@0.27.7': - optional: true - - '@esbuild/netbsd-arm64@0.27.7': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.27.7': - optional: true - - '@esbuild/openbsd-arm64@0.27.7': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.27.7': - optional: true - - '@esbuild/openharmony-arm64@0.27.7': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.27.7': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.27.7': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.27.7': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@esbuild/win32-x64@0.27.7': - optional: true - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.6.0': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.6.0 - - '@napi-rs/lzma-linux-x64-gnu@1.5.1': - optional: true - - '@one-ini/wasm@0.2.1': {} - - '@rollup/rollup-android-arm-eabi@4.63.4': - optional: true - - '@rollup/rollup-android-arm64@4.63.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.63.4': - optional: true - - '@rollup/rollup-darwin-x64@4.63.4': - optional: true - - '@rollup/rollup-freebsd-arm64@4.63.4': - optional: true - - '@rollup/rollup-freebsd-x64@4.63.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.63.4': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.63.4': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.63.4': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.63.4': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.63.4': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.63.4': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.63.4': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.63.4': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.63.4': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.63.4': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.63.4': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.63.4': - optional: true - - '@rollup/rollup-linux-x64-musl@4.63.4': - optional: true - - '@rollup/rollup-openbsd-x64@4.63.4': - optional: true - - '@rollup/rollup-openharmony-arm64@4.63.4': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.63.4': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.63.4': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.63.4': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.63.4': - optional: true - - '@types/estree@1.0.9': {} - - '@types/node@22.20.4': - dependencies: - undici-types: 6.21.0 - - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@22.20.4))(vue@3.5.43(typescript@5.9.3))': - dependencies: - vite: 5.4.21(@types/node@22.20.4) - vue: 3.5.43(typescript@5.9.3) - - '@vitest/expect@2.1.9': - dependencies: - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - tinyrainbow: 1.2.0 - - '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.20.4))': - dependencies: - '@vitest/spy': 2.1.9 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 5.4.21(@types/node@22.20.4) - - '@vitest/pretty-format@2.1.9': - dependencies: - tinyrainbow: 1.2.0 - - '@vitest/runner@2.1.9': - dependencies: - '@vitest/utils': 2.1.9 - pathe: 1.1.2 - - '@vitest/snapshot@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - magic-string: 0.30.21 - pathe: 1.1.2 - - '@vitest/spy@2.1.9': - dependencies: - tinyspy: 3.0.2 - - '@vitest/utils@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - loupe: 3.2.1 - tinyrainbow: 1.2.0 - - '@volar/language-core@2.4.15': - dependencies: - '@volar/source-map': 2.4.15 - - '@volar/source-map@2.4.15': {} - - '@volar/typescript@2.4.15': - dependencies: - '@volar/language-core': 2.4.15 - path-browserify: 1.0.1 - vscode-uri: 3.2.0 - - '@vue/compiler-core@3.5.43': - dependencies: - '@babel/parser': 7.29.9 - '@vue/shared': 3.5.43 - entities: 7.0.1 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.43': - dependencies: - '@vue/compiler-core': 3.5.43 - '@vue/shared': 3.5.43 - - '@vue/compiler-sfc@3.5.43': - dependencies: - '@babel/parser': 7.29.9 - '@vue/compiler-core': 3.5.43 - '@vue/compiler-dom': 3.5.43 - '@vue/compiler-ssr': 3.5.43 - '@vue/shared': 3.5.43 - estree-walker: 2.0.2 - magic-string: 0.30.21 - postcss: 8.5.28 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.43': - dependencies: - '@vue/compiler-dom': 3.5.43 - '@vue/shared': 3.5.43 - - '@vue/compiler-vue2@2.7.16': - dependencies: - de-indent: 1.0.2 - he: 1.2.0 - - '@vue/language-core@2.2.12(typescript@5.9.3)': - dependencies: - '@volar/language-core': 2.4.15 - '@vue/compiler-dom': 3.5.43 - '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.43 - alien-signals: 1.0.13 - minimatch: 9.0.9 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - optionalDependencies: - typescript: 5.9.3 - - '@vue/reactivity@3.5.43': - dependencies: - '@vue/shared': 3.5.43 - - '@vue/runtime-core@3.5.43': - dependencies: - '@vue/reactivity': 3.5.43 - '@vue/shared': 3.5.43 - - '@vue/runtime-dom@3.5.43': - dependencies: - '@vue/reactivity': 3.5.43 - '@vue/runtime-core': 3.5.43 - '@vue/shared': 3.5.43 - csstype: 3.2.3 - - '@vue/server-renderer@3.5.43': - dependencies: - '@vue/compiler-ssr': 3.5.43 - '@vue/runtime-dom': 3.5.43 - '@vue/shared': 3.5.43 - - '@vue/shared@3.5.43': {} - - '@vue/test-utils@2.5.1(@vue/compiler-dom@3.5.43)(@vue/server-renderer@3.5.43)(vue@3.5.43(typescript@5.9.3))': - dependencies: - '@vue/compiler-dom': 3.5.43 - js-beautify: 2.0.3 - vue: 3.5.43(typescript@5.9.3) - vue-component-type-helpers: 3.3.11 - optionalDependencies: - '@vue/server-renderer': 3.5.43 - - abbrev@5.0.0: {} - - acorn@8.18.0: {} - - agent-base@7.1.4: {} - - alien-signals@1.0.13: {} - - any-promise@1.3.0: {} - - assertion-error@2.0.1: {} - - asynckit@0.4.0: {} - - balanced-match@1.0.2: {} - - balanced-match@4.0.4: {} - - brace-expansion@2.1.7: - dependencies: - balanced-match: 1.0.2 - - brace-expansion@5.0.12: - dependencies: - balanced-match: 4.0.4 - - bundle-require@5.1.0(esbuild@0.27.7): - dependencies: - esbuild: 0.27.7 - load-tsconfig: 0.2.5 - - cac@6.7.14: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - chai@5.3.3: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.3 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 - - check-error@2.1.3: {} - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@14.0.3: {} - - commander@4.1.1: {} - - confbox@0.1.8: {} - - config-chain@1.1.13: - dependencies: - ini: 1.3.8 - proto-list: 1.2.4 - - consola@3.4.2: {} - - cssstyle@4.6.0: - dependencies: - '@asamuzakjp/css-color': 3.2.0 - rrweb-cssom: 0.8.0 - - csstype@3.2.3: {} - - data-urls@5.0.0: - dependencies: - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - - de-indent@1.0.2: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decimal.js@10.6.0: {} - - deep-eql@5.0.2: {} - - delayed-stream@1.0.0: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - editorconfig@3.0.2: - dependencies: - '@one-ini/wasm': 0.2.1 - commander: 14.0.3 - minimatch: 10.2.6 - semver: 7.8.5 - - entities@6.0.1: {} - - entities@7.0.1: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.7.0: {} - - es-object-atoms@1.1.2: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.4 - - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - esbuild@0.27.7: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.7 - '@esbuild/android-arm': 0.27.7 - '@esbuild/android-arm64': 0.27.7 - '@esbuild/android-x64': 0.27.7 - '@esbuild/darwin-arm64': 0.27.7 - '@esbuild/darwin-x64': 0.27.7 - '@esbuild/freebsd-arm64': 0.27.7 - '@esbuild/freebsd-x64': 0.27.7 - '@esbuild/linux-arm': 0.27.7 - '@esbuild/linux-arm64': 0.27.7 - '@esbuild/linux-ia32': 0.27.7 - '@esbuild/linux-loong64': 0.27.7 - '@esbuild/linux-mips64el': 0.27.7 - '@esbuild/linux-ppc64': 0.27.7 - '@esbuild/linux-riscv64': 0.27.7 - '@esbuild/linux-s390x': 0.27.7 - '@esbuild/linux-x64': 0.27.7 - '@esbuild/netbsd-arm64': 0.27.7 - '@esbuild/netbsd-x64': 0.27.7 - '@esbuild/openbsd-arm64': 0.27.7 - '@esbuild/openbsd-x64': 0.27.7 - '@esbuild/openharmony-arm64': 0.27.7 - '@esbuild/sunos-x64': 0.27.7 - '@esbuild/win32-arm64': 0.27.7 - '@esbuild/win32-ia32': 0.27.7 - '@esbuild/win32-x64': 0.27.7 - - estree-walker@2.0.2: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.9 - - expect-type@1.4.0: {} - - fdir@6.5.0(picomatch@4.0.7): - optionalDependencies: - picomatch: 4.0.7 - - fix-dts-default-cjs-exports@1.0.1: - dependencies: - magic-string: 0.30.21 - mlly: 1.8.2 - rollup: 4.63.4 - - form-data@4.0.6: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.4 - mime-types: 2.1.35 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.2 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.4 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.2 - - glob@13.0.6: - dependencies: - minimatch: 10.2.6 - minipass: 7.1.3 - path-scurry: 2.0.2 - - gopd@1.2.0: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.4: - dependencies: - function-bind: 1.1.2 - - he@1.2.0: {} - - html-encoding-sniffer@4.0.0: - dependencies: - whatwg-encoding: 3.1.1 - - http-proxy-agent@7.0.2: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - ini@1.3.8: {} - - is-potential-custom-element-name@1.0.1: {} - - joycon@3.1.1: {} - - js-beautify@2.0.3: - dependencies: - config-chain: 1.1.13 - editorconfig: 3.0.2 - glob: 13.0.6 - js-cookie: 3.0.8 - nopt: 10.0.1 - - js-cookie@3.0.8: {} - - jsdom@25.0.1: - dependencies: - cssstyle: 4.6.0 - data-urls: 5.0.0 - decimal.js: 10.6.0 - form-data: 4.0.6 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.28 - parse5: 7.3.0 - rrweb-cssom: 0.7.1 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 5.1.2 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.21.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} - - load-tsconfig@0.2.5: {} - - loupe@3.2.1: {} - - lru-cache@10.4.3: {} - - lru-cache@11.5.3: {} - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - - math-intrinsics@1.1.0: {} - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - minimatch@10.2.6: - dependencies: - brace-expansion: 5.0.12 - - minimatch@9.0.9: - dependencies: - brace-expansion: 2.1.7 - - minipass@7.1.3: {} - - mlly@1.8.2: - dependencies: - acorn: 8.18.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.4 - - ms@2.1.3: {} - - muggle-string@0.4.1: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.19: {} - - nopt@10.0.1: - dependencies: - abbrev: 5.0.0 - - nwsapi@2.2.28: {} - - object-assign@4.1.1: {} - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - path-browserify@1.0.1: {} - - path-scurry@2.0.2: - dependencies: - lru-cache: 11.5.3 - minipass: 7.1.3 - - pathe@1.1.2: {} - - pathe@2.0.3: {} - - pathval@2.0.1: {} - - picocolors@1.1.1: {} - - picomatch@4.0.7: {} - - pirates@4.0.7: {} - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - - postcss-load-config@6.0.1(postcss@8.5.28): - dependencies: - lilconfig: 3.1.3 - optionalDependencies: - postcss: 8.5.28 - - postcss@8.5.28: - dependencies: - nanoid: 3.3.19 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - proto-list@1.2.4: {} - - punycode@2.3.1: {} - - readdirp@4.1.2: {} - - resolve-from@5.0.0: {} - - rollup@4.63.4: - dependencies: - '@types/estree': 1.0.9 - optionalDependencies: - '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@rollup/rollup-android-arm-eabi': 4.63.4 - '@rollup/rollup-android-arm64': 4.63.4 - '@rollup/rollup-darwin-arm64': 4.63.4 - '@rollup/rollup-darwin-x64': 4.63.4 - '@rollup/rollup-freebsd-arm64': 4.63.4 - '@rollup/rollup-freebsd-x64': 4.63.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.63.4 - '@rollup/rollup-linux-arm-musleabihf': 4.63.4 - '@rollup/rollup-linux-arm64-gnu': 4.63.4 - '@rollup/rollup-linux-arm64-musl': 4.63.4 - '@rollup/rollup-linux-loong64-gnu': 4.63.4 - '@rollup/rollup-linux-loong64-musl': 4.63.4 - '@rollup/rollup-linux-ppc64-gnu': 4.63.4 - '@rollup/rollup-linux-ppc64-musl': 4.63.4 - '@rollup/rollup-linux-riscv64-gnu': 4.63.4 - '@rollup/rollup-linux-riscv64-musl': 4.63.4 - '@rollup/rollup-linux-s390x-gnu': 4.63.4 - '@rollup/rollup-linux-x64-gnu': 4.63.4 - '@rollup/rollup-linux-x64-musl': 4.63.4 - '@rollup/rollup-openbsd-x64': 4.63.4 - '@rollup/rollup-openharmony-arm64': 4.63.4 - '@rollup/rollup-win32-arm64-msvc': 4.63.4 - '@rollup/rollup-win32-ia32-msvc': 4.63.4 - '@rollup/rollup-win32-x64-gnu': 4.63.4 - '@rollup/rollup-win32-x64-msvc': 4.63.4 - fsevents: 2.3.3 - - rrweb-cssom@0.7.1: {} - - rrweb-cssom@0.8.0: {} - - safer-buffer@2.1.2: {} - - saxes@6.0.0: - dependencies: - xmlchars: 2.2.0 - - semver@7.8.5: {} - - siginfo@2.0.0: {} - - source-map-js@1.2.1: {} - - source-map@0.7.6: {} - - stackback@0.0.2: {} - - std-env@3.10.0: {} - - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.17 - ts-interface-checker: 0.1.13 - - symbol-tree@3.2.4: {} - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - tinybench@2.9.0: {} - - tinyexec@0.3.2: {} - - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.7) - picomatch: 4.0.7 - - tinypool@1.1.1: {} - - tinyrainbow@1.2.0: {} - - tinyspy@3.0.2: {} - - tldts-core@6.1.86: {} - - tldts@6.1.86: - dependencies: - tldts-core: 6.1.86 - - tough-cookie@5.1.2: - dependencies: - tldts: 6.1.86 - - tr46@5.1.1: - dependencies: - punycode: 2.3.1 - - tree-kill@1.2.2: {} - - ts-interface-checker@0.1.13: {} - - tsup@8.5.1(postcss@8.5.28)(typescript@5.9.3): - dependencies: - bundle-require: 5.1.0(esbuild@0.27.7) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.3 - esbuild: 0.27.7 - fix-dts-default-cjs-exports: 1.0.1 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1(postcss@8.5.28) - resolve-from: 5.0.0 - rollup: 4.63.4 - source-map: 0.7.6 - sucrase: 3.35.1 - tinyexec: 0.3.2 - tinyglobby: 0.2.17 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.28 - typescript: 5.9.3 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - - typescript@5.9.3: {} - - ufo@1.6.4: {} - - undici-types@6.21.0: {} - - vite-node@2.1.9(@types/node@22.20.4): - dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 1.1.2 - vite: 5.4.21(@types/node@22.20.4) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - vite@5.4.21(@types/node@22.20.4): - dependencies: - esbuild: 0.21.5 - postcss: 8.5.28 - rollup: 4.63.4 - optionalDependencies: - '@types/node': 22.20.4 - fsevents: 2.3.3 - - vitest@2.1.9(@types/node@22.20.4)(jsdom@25.0.1): - dependencies: - '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.20.4)) - '@vitest/pretty-format': 2.1.9 - '@vitest/runner': 2.1.9 - '@vitest/snapshot': 2.1.9 - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - debug: 4.4.3 - expect-type: 1.4.0 - magic-string: 0.30.21 - pathe: 1.1.2 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.1.1 - tinyrainbow: 1.2.0 - vite: 5.4.21(@types/node@22.20.4) - vite-node: 2.1.9(@types/node@22.20.4) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 22.20.4 - jsdom: 25.0.1 - transitivePeerDependencies: - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - vscode-uri@3.2.0: {} - - vue-component-type-helpers@3.3.11: {} - - vue-tsc@2.2.12(typescript@5.9.3): - dependencies: - '@volar/typescript': 2.4.15 - '@vue/language-core': 2.2.12(typescript@5.9.3) - typescript: 5.9.3 - - vue@3.5.43(typescript@5.9.3): - dependencies: - '@vue/compiler-dom': 3.5.43 - '@vue/compiler-sfc': 3.5.43 - '@vue/runtime-dom': 3.5.43 - '@vue/server-renderer': 3.5.43 - '@vue/shared': 3.5.43 - optionalDependencies: - typescript: 5.9.3 - - w3c-xmlserializer@5.0.0: - dependencies: - xml-name-validator: 5.0.0 - - webidl-conversions@7.0.0: {} - - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 - - whatwg-mimetype@4.0.0: {} - - whatwg-url@14.2.0: - dependencies: - tr46: 5.1.1 - webidl-conversions: 7.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - ws@8.21.3: {} - - xml-name-validator@5.0.0: {} - - xmlchars@2.2.0: {} diff --git a/code/one-designer/pnpm-workspace.yaml b/code/one-designer/pnpm-workspace.yaml deleted file mode 100644 index 759f4317..00000000 --- a/code/one-designer/pnpm-workspace.yaml +++ /dev/null @@ -1,8 +0,0 @@ -packages: - - "apps/*" - - "packages/*" - - "packages/plugins/*" - - "examples/*" - -allowBuilds: - esbuild: true diff --git a/code/one-designer/s.yaml b/code/one-designer/s.yaml deleted file mode 100644 index 031e1e7a..00000000 --- a/code/one-designer/s.yaml +++ /dev/null @@ -1,61 +0,0 @@ -- generic [ref=e3]: - - banner [ref=e4]: - - generic [ref=e5]: Web Report Designer · Demo - - button "🌙 暗色" [ref=e6] [cursor=pointer] - - main [ref=e7]: - - generic [ref=e8]: - - toolbar "工具栏" [ref=e9]: - - generic [ref=e10]: - - button "撤销" [disabled] [ref=e11] - - button "重做" [disabled] [ref=e12] - - generic [ref=e13]: - - button "缩小" [ref=e14] [cursor=pointer]: − - - generic [ref=e15]: 100% - - button "放大" [ref=e16] [cursor=pointer]: + - - button "预览" [ref=e18] [cursor=pointer] - - generic [ref=e19]: - - complementary "工具箱" [ref=e20]: - - generic [ref=e21]: 元素 - - button "文本" [ref=e22] [cursor=pointer] - - button "矩形" [ref=e23] [cursor=pointer] - - generic [ref=e24]: - - generic [ref=e25]: mm - - generic [aria-hidden] [ref=e26]: - - generic [ref=e27]: "0" - - generic [ref=e32]: "20" - - generic [ref=e37]: "40" - - generic [ref=e42]: "60" - - generic [ref=e47]: "80" - - generic [ref=e52]: "100" - - generic [ref=e57]: "120" - - generic [ref=e62]: "140" - - generic [ref=e67]: "160" - - generic [ref=e72]: "180" - - generic [ref=e77]: "200" - - generic [aria-hidden] [ref=e81]: - - generic [ref=e82]: "0" - - generic [ref=e87]: "20" - - generic [ref=e92]: "40" - - generic [ref=e97]: "60" - - generic [ref=e102]: "80" - - generic [ref=e107]: "100" - - generic [ref=e112]: "120" - - generic [ref=e117]: "140" - - generic [ref=e122]: "160" - - generic [ref=e127]: "180" - - generic [ref=e132]: "200" - - generic [ref=e137]: "220" - - generic [ref=e142]: "240" - - generic [ref=e147]: "260" - - generic [ref=e152]: "280" - - generic [ref=e159]: - - generic [ref=e160]: 销售出库单 - - generic [ref=e163]: 客户:示例公司 - - generic [ref=e165]: 日期:2025-01-01 - - generic [ref=e167]: 在左侧工具箱添加元素,点击画布元素可在右侧编辑属性,工具栏支持撤销/重做与缩放。 - - complementary "属性面板" [ref=e169]: - - generic [ref=e170]: 未选中元素 - - status [ref=e171]: - - generic [ref=e172]: 缩放 100% - - generic [ref=e173]: 单位 mm - - generic [ref=e174]: 元素 5 \ No newline at end of file diff --git a/code/one-designer/s2.yaml b/code/one-designer/s2.yaml deleted file mode 100644 index cdddc2e2..00000000 --- a/code/one-designer/s2.yaml +++ /dev/null @@ -1,76 +0,0 @@ -- generic [ref=e3]: - - banner [ref=e4]: - - generic [ref=e5]: Web Report Designer · Demo - - button "🌙 暗色" [ref=e6] [cursor=pointer] - - main [ref=e7]: - - generic [ref=e8]: - - toolbar "工具栏" [ref=e9]: - - generic [ref=e10]: - - button "撤销" [ref=e11] [cursor=pointer] - - button "重做" [disabled] [ref=e12] - - generic [ref=e13]: - - button "缩小" [ref=e14] [cursor=pointer]: − - - generic [ref=e15]: 100% - - button "放大" [ref=e16] [cursor=pointer]: + - - button "预览" [ref=e18] [cursor=pointer] - - generic [ref=e19]: - - complementary "工具箱" [ref=e20]: - - generic [ref=e21]: 元素 - - button "文本" [ref=e22] [cursor=pointer] - - button "矩形" [ref=e23] [cursor=pointer] - - generic [ref=e24]: - - generic [ref=e25]: mm - - generic [aria-hidden] [ref=e26]: - - generic [ref=e27]: "0" - - generic [ref=e32]: "20" - - generic [ref=e37]: "40" - - generic [ref=e42]: "60" - - generic [ref=e47]: "80" - - generic [ref=e52]: "100" - - generic [ref=e57]: "120" - - generic [ref=e62]: "140" - - generic [ref=e67]: "160" - - generic [ref=e72]: "180" - - generic [ref=e77]: "200" - - generic [aria-hidden] [ref=e81]: - - generic [ref=e82]: "0" - - generic [ref=e87]: "20" - - generic [ref=e92]: "40" - - generic [ref=e97]: "60" - - generic [ref=e102]: "80" - - generic [ref=e107]: "100" - - generic [ref=e112]: "120" - - generic [ref=e117]: "140" - - generic [ref=e122]: "160" - - generic [ref=e127]: "180" - - generic [ref=e132]: "200" - - generic [ref=e137]: "220" - - generic [ref=e142]: "240" - - generic [ref=e147]: "260" - - generic [ref=e152]: "280" - - generic [ref=e159]: - - generic [ref=e160]: 销售出库单 - - generic [ref=e163]: 客户:示例公司 - - generic [ref=e165]: 日期:2025-01-01 - - generic [ref=e167]: 在左侧工具箱添加元素,点击画布元素可在右侧编辑属性,工具栏支持撤销/重做与缩放。 - - complementary "属性面板" [ref=e169]: - - generic [ref=e175]: 属性 - - generic [ref=e176]: - - generic [ref=e177]: ID - - generic [ref=e178]: title-1 - - generic [ref=e179]: - - generic [ref=e180]: 类型 - - generic [ref=e181]: text - - generic [ref=e182]: - - generic [ref=e183]: 位置 - - generic [ref=e184]: x36 y19 - - generic [ref=e185]: - - generic [ref=e186]: 尺寸 - - generic [ref=e187]: 120 × 12 - - generic [ref=e188]: - - generic [ref=e189]: 文本 - - textbox "文本" [ref=e190]: 销售出库单 - - status [ref=e171]: - - generic [ref=e172]: 缩放 100% - - generic [ref=e173]: 单位 mm - - generic [ref=e174]: 元素 5 \ No newline at end of file diff --git a/code/one-designer/s3.yaml b/code/one-designer/s3.yaml deleted file mode 100644 index 75a0b309..00000000 --- a/code/one-designer/s3.yaml +++ /dev/null @@ -1,76 +0,0 @@ -- generic [ref=e3]: - - banner [ref=e4]: - - generic [ref=e5]: Web Report Designer · Demo - - button "🌙 暗色" [ref=e6] [cursor=pointer] - - main [ref=e7]: - - generic [ref=e8]: - - toolbar "工具栏" [ref=e9]: - - generic [ref=e10]: - - button "撤销" [active] [ref=e11] [cursor=pointer] - - button "重做" [ref=e12] [cursor=pointer] - - generic [ref=e13]: - - button "缩小" [ref=e14] [cursor=pointer]: − - - generic [ref=e15]: 100% - - button "放大" [ref=e16] [cursor=pointer]: + - - button "预览" [ref=e18] [cursor=pointer] - - generic [ref=e19]: - - complementary "工具箱" [ref=e20]: - - generic [ref=e21]: 元素 - - button "文本" [ref=e22] [cursor=pointer] - - button "矩形" [ref=e23] [cursor=pointer] - - generic [ref=e24]: - - generic [ref=e25]: mm - - generic [aria-hidden] [ref=e26]: - - generic [ref=e27]: "0" - - generic [ref=e32]: "20" - - generic [ref=e37]: "40" - - generic [ref=e42]: "60" - - generic [ref=e47]: "80" - - generic [ref=e52]: "100" - - generic [ref=e57]: "120" - - generic [ref=e62]: "140" - - generic [ref=e67]: "160" - - generic [ref=e72]: "180" - - generic [ref=e77]: "200" - - generic [aria-hidden] [ref=e81]: - - generic [ref=e82]: "0" - - generic [ref=e87]: "20" - - generic [ref=e92]: "40" - - generic [ref=e97]: "60" - - generic [ref=e102]: "80" - - generic [ref=e107]: "100" - - generic [ref=e112]: "120" - - generic [ref=e117]: "140" - - generic [ref=e122]: "160" - - generic [ref=e127]: "180" - - generic [ref=e132]: "200" - - generic [ref=e137]: "220" - - generic [ref=e142]: "240" - - generic [ref=e147]: "260" - - generic [ref=e152]: "280" - - generic [ref=e159]: - - generic [ref=e160]: 销售出库单 - - generic [ref=e163]: 客户:示例公司 - - generic [ref=e165]: 日期:2025-01-01 - - generic [ref=e167]: 在左侧工具箱添加元素,点击画布元素可在右侧编辑属性,工具栏支持撤销/重做与缩放。 - - complementary "属性面板" [ref=e169]: - - generic [ref=e175]: 属性 - - generic [ref=e176]: - - generic [ref=e177]: ID - - generic [ref=e178]: title-1 - - generic [ref=e179]: - - generic [ref=e180]: 类型 - - generic [ref=e181]: text - - generic [ref=e182]: - - generic [ref=e183]: 位置 - - generic [ref=e184]: x23 y13 - - generic [ref=e185]: - - generic [ref=e186]: 尺寸 - - generic [ref=e187]: 120 × 12 - - generic [ref=e188]: - - generic [ref=e189]: 文本 - - textbox "文本" [ref=e190]: 销售出库单 - - status [ref=e171]: - - generic [ref=e172]: 缩放 100% - - generic [ref=e173]: 单位 mm - - generic [ref=e174]: 元素 5 \ No newline at end of file diff --git a/code/one-designer/tsconfig.base.json b/code/one-designer/tsconfig.base.json deleted file mode 100644 index a4943746..00000000 --- a/code/one-designer/tsconfig.base.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "compilerOptions": { - "target": "ES2022", - "lib": ["ES2022"], - "module": "ESNext", - "moduleResolution": "Bundler", - "moduleDetection": "force", - - "strict": true, - "noUncheckedIndexedAccess": true, - "noImplicitOverride": true, - "noFallthroughCasesInSwitch": true, - "exactOptionalPropertyTypes": false, - - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "isolatedModules": true, - "verbatimModuleSyntax": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - } -} diff --git a/code/one-designer/v1.png b/code/one-designer/v1.png deleted file mode 100644 index 1eeb9f3b..00000000 Binary files a/code/one-designer/v1.png and /dev/null differ diff --git a/code/test-demo/.gitignore b/code/test-demo/.gitignore deleted file mode 100644 index a547bf36..00000000 --- a/code/test-demo/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/code/test-demo/.oxlintrc.json b/code/test-demo/.oxlintrc.json deleted file mode 100644 index 6fa991da..00000000 --- a/code/test-demo/.oxlintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": ["react", "typescript", "oxc"], - "rules": { - "react/rules-of-hooks": "error", - "react/only-export-components": ["warn", { "allowConstantExport": true }] - } -} diff --git a/code/test-demo/AI_CONTEXT.md b/code/test-demo/AI_CONTEXT.md deleted file mode 100644 index 1a3a678d..00000000 --- a/code/test-demo/AI_CONTEXT.md +++ /dev/null @@ -1,58 +0,0 @@ -# AI Context — FMS 新系统配置中心 Demo - -## 项目目标 - -这是一个 **FMS 新系统配置中心演示**,用 React 实现,用于直观展示如何配置业务域、实体、菜单与权限,对应《FMS新系统核心表结构设计.md》中的核心元数据结构。 - -命名风格参考旧系统:表名 `s_` 前缀、字段 `b_` 前缀 + 驼峰(如 `b_viewtable`、`b_inputdatetime`)。 - -## 技术栈 - -| 项 | 值 | -|---|-----| -| 框架 | React 19 + TypeScript 6 | -| 构建 | Vite 8 | -| 样式 | Tailwind CSS v4 (`@tailwindcss/vite`) | -| 包管理 | pnpm | - -## 文件结构 - -``` -src/ -└── src/ - ├── App.tsx # 单页配置中心:总览 / 业务域与实体 / 菜单与权限 / 角色与用户 - ├── index.css # 整体样式 - └── main.tsx # 入口 -``` - -## 设计理念 - -1. **四个工作区**:总览、业务域与实体、菜单与权限、角色与用户 -2. **业务域只管归属**:`s_module` 仅表示业务分组,不承载菜单和权限 -3. **实体维护数据边界**:`s_entity` 负责数据源、保存表、主键,字段属于实体 -4. **菜单承载访问入口**:`s_menu` 直接绑定实体或固定页面,动作权限跟着菜单生成 -5. **权限跟随菜单**:角色只做授权主体,权限点来源于菜单动作 - -## 覆盖的表 - -| 工作区 | 表 | -| --- | --- | -| 业务域 | `s_module` | -| 实体与字段 | `s_entity`、`s_field_group`、`s_field`、`s_field_list`、`s_field_edit`、`s_field_query` | -| 菜单与页面 | `s_menu` | -| 权限 | `s_role`、`s_user_role`、`s_power`、`s_role_power` | - -## 启动 - -```bash -pnpm install # 已安装 -pnpm dev # http://localhost:3000 -``` - -## 注意事项 - -- 这版 Demo 按维护关联度合并页面:业务域、实体和实体关系在同一棵配置树及详情工作区维护,菜单和权限一起维护 -- 业务模型树同时展示 `s_module` 和 `s_entity`:业务域节点表达归属,实体节点表达数据对象;只有 `owned` 主从实体继续嵌套,`reference` 引用不改变树位置 -- 权限是跟着菜单走的:一个数据菜单或页面菜单会生成一组动作权限,再由角色去勾选 -- `s_relation` 在实体详情中维护关系类型、来源字段、目标字段、所有权和删除策略 -- `src/index.css` 里有完整布局样式;如果要继续精修,可以在这份文件上直接改 diff --git a/code/test-demo/README.md b/code/test-demo/README.md deleted file mode 100644 index b275eda2..00000000 --- a/code/test-demo/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# FMS 配置中心 Demo - -这是一个用于验证 FMS 新系统元数据维护方式的前端演示。业务域和实体在同一棵配置树中展示:业务域表达归属,实体表达数据边界,实体的主从关系可以继续嵌套,普通引用关系在实体详情中配置。 - -## 启动 - -```bash -pnpm install -pnpm dev -``` - -浏览器访问 `http://localhost:3000/`。 - -## 使用流程 - -1. 在“业务域与实体”中选择或创建业务域,并直接维护该域下的实体、数据源、主键和字段。 -2. 在“菜单与权限”中维护菜单树。选中菜单后,通过页签同时维护页面绑定、动作权限、角色授权和数据范围。 -3. 在“角色与用户”中维护角色本身及其成员,具体菜单授权仍在菜单工作区完成。 -4. 顶部“保存”用于模拟保存配置;菜单权限工作区的“发布”用于模拟发布。 - -## 对应核心表 - -| 工作区 | 主要表 | -| --- | --- | -| 业务模型树 | `s_module`、`s_entity`、`s_relation` | -| 实体与字段 | `s_entity`、`s_field_group`、`s_field`、`s_field_list`、`s_field_edit`、`s_field_query` | -| 菜单与页面 | `s_menu` | -| 权限 | `s_role`、`s_user_role`、`s_power`、`s_role_power` | - -Demo 当前使用内存状态模拟维护,不连接后端接口;刷新页面会恢复示例数据。 diff --git a/code/test-demo/index.html b/code/test-demo/index.html deleted file mode 100644 index 19607be5..00000000 --- a/code/test-demo/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - FMS 售后配置中心 Demo - - -
- - - diff --git a/code/test-demo/package.json b/code/test-demo/package.json deleted file mode 100644 index 9d0ff5d7..00000000 --- a/code/test-demo/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "test-demo", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "oxlint", - "preview": "vite preview" - }, - "dependencies": { - "@dnd-kit/core": "^6.3.1", - "@dnd-kit/modifiers": "^9.0.0", - "@dnd-kit/sortable": "^10.0.0", - "@dnd-kit/utilities": "^3.2.2", - "@tailwindcss/vite": "^4.3.3", - "lucide-react": "^1.33.0", - "react": "^19.2.8", - "react-dom": "^19.2.8", - "tailwindcss": "^4.3.3" - }, - "devDependencies": { - "@types/node": "^24.13.3", - "@types/react": "^19.2.17", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^6.0.4", - "oxlint": "^1.75.0", - "typescript": "~6.0.2", - "vite": "^8.2.0" - } -} diff --git a/code/test-demo/pnpm-lock.yaml b/code/test-demo/pnpm-lock.yaml deleted file mode 100644 index 97782bc0..00000000 --- a/code/test-demo/pnpm-lock.yaml +++ /dev/null @@ -1,1221 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@dnd-kit/core': - specifier: ^6.3.1 - version: 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@dnd-kit/modifiers': - specifier: ^9.0.0 - version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8) - '@dnd-kit/sortable': - specifier: ^10.0.0 - version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8) - '@dnd-kit/utilities': - specifier: ^3.2.2 - version: 3.2.2(react@19.2.8) - '@tailwindcss/vite': - specifier: ^4.3.3 - version: 4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) - lucide-react: - specifier: ^1.33.0 - version: 1.33.0(react@19.2.8) - react: - specifier: ^19.2.8 - version: 19.2.8 - react-dom: - specifier: ^19.2.8 - version: 19.2.8(react@19.2.8) - tailwindcss: - specifier: ^4.3.3 - version: 4.3.3 - devDependencies: - '@types/node': - specifier: ^24.13.3 - version: 24.13.3 - '@types/react': - specifier: ^19.2.17 - version: 19.2.18 - '@types/react-dom': - specifier: ^19.2.3 - version: 19.2.4(@types/react@19.2.18) - '@vitejs/plugin-react': - specifier: ^6.0.4 - version: 6.0.5(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) - oxlint: - specifier: ^1.75.0 - version: 1.78.0 - typescript: - specifier: ~6.0.2 - version: 6.0.3 - vite: - specifier: ^8.2.0 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) - -packages: - - '@dnd-kit/accessibility@3.1.1': - resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==} - peerDependencies: - react: '>=16.8.0' - - '@dnd-kit/core@6.3.1': - resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - - '@dnd-kit/modifiers@9.0.0': - resolution: {integrity: sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw==} - peerDependencies: - '@dnd-kit/core': ^6.3.0 - react: '>=16.8.0' - - '@dnd-kit/sortable@10.0.0': - resolution: {integrity: sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==} - peerDependencies: - '@dnd-kit/core': ^6.3.0 - react: '>=16.8.0' - - '@dnd-kit/utilities@3.2.2': - resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==} - peerDependencies: - react: '>=16.8.0' - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.4.10': - resolution: {integrity: sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==} - - '@jridgewell/sourcemap-codec@1.4.14': - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@oxc-project/types@0.143.0': - resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} - - '@oxlint/binding-android-arm-eabi@1.78.0': - resolution: {integrity: sha512-Bu819lmAfZMUHErrpe0cEWj3iaefuUODHSU8+UbXy67V/r7/7f4K3FL0NmbD85E+wiFLDYuhP8Zlv0XnVeXshw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxlint/binding-android-arm64@1.78.0': - resolution: {integrity: sha512-CDfxZgB61B7buRdY2FJoAYYPPXCZ1EoC1LKscnC5dg3kjobdxiconvAvvN1BmHyW4PyFT3jRLDag/BY/roSNBQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxlint/binding-darwin-arm64@1.78.0': - resolution: {integrity: sha512-2Y2U9Ahrz+OO0Ej88f9SJYq51/jUBp1Mc7iZu0ukrbeeZ3gpRGfzIFnoqfHDY96xr0GEfNrPUBFEy0nN5aD7HA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxlint/binding-darwin-x64@1.78.0': - resolution: {integrity: sha512-rpych6eJq6m9jDRypTEaPD1xysaEW5h9+xuxhGK/QhOg+/xaqPZrCrTNoIl/f3nEjuJeCEmstNDlrE9rJi/3/g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxlint/binding-freebsd-x64@1.78.0': - resolution: {integrity: sha512-IcMGrQT3QizkOESUJd5et+rOhVqSkNDfNik1cvrKDqIbzqx9KMtRswpFgkCuNTSwylCFLKhGUu8KmqY1ZnC0Dg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxlint/binding-linux-arm-gnueabihf@1.78.0': - resolution: {integrity: sha512-/uLdoJ0IXE6vo/0f0LKjinQAp+re+VMaCWaNT8ENIv2EOCkSsc8SGaflXAuW0Jua2dq5+GLVWm1NQK7P3UFSNQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm-musleabihf@1.78.0': - resolution: {integrity: sha512-7xi4Wb/O8NRJhLoUXmDJMUVpNYvB5kefdhFU1Jb8rtae4QoXlTiLwI14X4YvAXVZLNZChP8m5qO9SQAlWQTbkQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm64-gnu@1.78.0': - resolution: {integrity: sha512-4hFW0+fVXa3OIh1Y4A5SPkmvI4wuuBSrCVKzOyE7PTjhc7yEqZ1pmvEEeS5Lj/MaqvegFxXyF33N+6jkehxdyg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-arm64-musl@1.78.0': - resolution: {integrity: sha512-oC0mvsgBJjlMijSDEhx9KuvR9zYeHXceA9MjbuXB1F8NSR78Yj2unOBrstEvTVaq+pko+kuue6DajC00eqvTdg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxlint/binding-linux-ppc64-gnu@1.78.0': - resolution: {integrity: sha512-XAllT5SUZS+ohjuZ3/5S0cwe0r7eboiuigeStCZ5DXRYx/2KVM2UvQXvAfyzXEimtQjAB7cDQ2YxDe2Zl2WNQQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-riscv64-gnu@1.78.0': - resolution: {integrity: sha512-trucMER/0QtecoXvc1y/UVqE3kwJipDwrx4oHfj+nNm3dq2zjP44WT0CfHNDPM3G1DXIkx/gY6lAD21NSCZVhA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-riscv64-musl@1.78.0': - resolution: {integrity: sha512-cm3O4F/HQbdzOUX5mKHqG5KDL6E5w0pnlZ+fbBy2rmLryPOowkuLagFHTopQsEIpjcaZoPOrL+BmmAytAG9HFg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxlint/binding-linux-s390x-gnu@1.78.0': - resolution: {integrity: sha512-33wRf6HqGNsybJ3qX4cGaQN2ODPxNmc1rMa0mrTmx3eFq1VzOnvQooi9bIGVYakW8a/wmqVx1mgsUm8R2xfTiw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-x64-gnu@1.78.0': - resolution: {integrity: sha512-rRdISSYegj6VganMZ9tjRjijowfHJ09IZU01i0toBAqr6n5LEtwHq2IeS4FjW2RoskOHlb6efB26H5izYb3GEQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-x64-musl@1.78.0': - resolution: {integrity: sha512-GmsP4rW0xTL6u5CVdcDsaN5Fbc7hBc382Wmar1kttbnwSEviM+rSINKOMQ+UQ6iH+AGwC+8gaAiwu134Tgh6Lg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxlint/binding-openharmony-arm64@1.78.0': - resolution: {integrity: sha512-sy9yeYuADc8a+n4TLBayzMCZiHPW78DcIFVpOXTmdKHWQeM9xe5uzkqIIZmi326D5hY9XVwacipEB1p7tQjPAg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxlint/binding-win32-arm64-msvc@1.78.0': - resolution: {integrity: sha512-rjc2hF1KfMi8fZj1X/m3AmnHbdsF3rL0v6KQg0Uc880Yb2khjz+3U14sfdZ7jWTpRnN1m1NQa/TT7uU9lJWPrA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxlint/binding-win32-ia32-msvc@1.78.0': - resolution: {integrity: sha512-zcuXFVrEFHIafRfkCQT8w/Xe41o07ozl/vwHq7p94vB29xVzsB0sZGYORU1jhcYKv3Lr0J3HbJ2T4fHH5rWmvA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxlint/binding-win32-x64-msvc@1.78.0': - resolution: {integrity: sha512-Sb5ocmLSuYeOuXd+CFOToGKp/gjXUEWDnvIGwhnh8aq8wY4TMmEnKnvbogSW7RdMZv77JSARduS7/gv+khYEjA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/binding-android-arm64@1.2.3': - resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.2.3': - resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.2.3': - resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.2.3': - resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.2.3': - resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.2.3': - resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.2.3': - resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.2.3': - resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.2.3': - resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.2.3': - resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.2.3': - resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.2.3': - resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-win32-arm64-msvc@1.2.3': - resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.2.3': - resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - - '@tailwindcss/node@4.3.3': - resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} - - '@tailwindcss/oxide-android-arm64@4.3.3': - resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [android] - - '@tailwindcss/oxide-darwin-arm64@4.3.3': - resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [darwin] - - '@tailwindcss/oxide-darwin-x64@4.3.3': - resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [darwin] - - '@tailwindcss/oxide-freebsd-x64@4.3.3': - resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [freebsd] - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': - resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} - engines: {node: '>= 20'} - cpu: [arm] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': - resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@tailwindcss/oxide-linux-arm64-musl@4.3.3': - resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@tailwindcss/oxide-linux-x64-gnu@4.3.3': - resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@tailwindcss/oxide-linux-x64-musl@4.3.3': - resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@tailwindcss/oxide-wasm32-wasi@4.3.3': - resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib - - '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': - resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [win32] - - '@tailwindcss/oxide-win32-x64-msvc@4.3.3': - resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} - engines: {node: '>= 20'} - cpu: [x64] - os: [win32] - - '@tailwindcss/oxide@4.3.3': - resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} - engines: {node: '>= 20'} - - '@tailwindcss/vite@4.3.3': - resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} - peerDependencies: - vite: ^5.2.0 || ^6 || ^7 || ^8 - - '@types/node@24.13.3': - resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} - - '@types/react-dom@19.2.4': - resolution: {integrity: sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==} - peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.18': - resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} - - '@vitejs/plugin-react@6.0.5': - resolution: {integrity: sha512-BOVzne/NL162sMdResB25mUv+vWMF5NoAjNf09TeGlE7ZpszZWSD3winycicLJw72yeVsoCn/2kOhEuCvEShMA==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 - babel-plugin-react-compiler: ^1.0.0 - vite: ^8.0.0 - peerDependenciesMeta: - '@rolldown/plugin-babel': - optional: true - babel-plugin-react-compiler: - optional: true - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - enhanced-resolve@5.24.5: - resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} - engines: {node: '>=10.13.0'} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - jiti@2.7.0: - resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} - hasBin: true - - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-android-arm64@1.33.0: - resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-arm64@1.33.0: - resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-darwin-x64@1.33.0: - resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-freebsd-x64@1.33.0: - resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm-gnueabihf@1.33.0: - resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-gnu@1.33.0: - resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-arm64-musl@1.33.0: - resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-gnu@1.33.0: - resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-musl@1.33.0: - resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-arm64-msvc@1.33.0: - resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss-win32-x64-msvc@1.33.0: - resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - - lightningcss@1.33.0: - resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} - engines: {node: '>= 12.0.0'} - - lucide-react@1.33.0: - resolution: {integrity: sha512-MTRwMy0ZlL8Ur/vOAiJ9XGHE+kFPC7brq6MxAm0GiGXEBj0qy0jA/pG4N675oSzciO/UCdX8T+5yUQdmDeTLxg==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - nanoid@3.3.18: - resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - oxlint@1.78.0: - resolution: {integrity: sha512-QgQePuxIqKOzo1KSjG2EnITEeWvWnKAm77eq8nrMtf6AGoA+zyGc4PFYtDNJSD25g/ibOwfQ851hZ4/SPkMVoA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - oxlint-tsgolint: '>=7.0.2001' - vite-plus: '*' - peerDependenciesMeta: - oxlint-tsgolint: - optional: true - vite-plus: - optional: true - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} - engines: {node: '>=12'} - - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} - engines: {node: ^10 || ^12 || >=14} - - react-dom@19.2.8: - resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} - peerDependencies: - react: ^19.2.8 - - react@19.2.8: - resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} - engines: {node: '>=0.10.0'} - - rolldown@1.2.3: - resolution: {integrity: sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - tailwindcss@4.3.3: - resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} - - tapable@2.3.3: - resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} - engines: {node: '>=6'} - - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@7.18.2: - resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - - vite@8.2.1: - resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.4.0 - esbuild: ^0.27.0 || ^0.28.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 - '@vitejs/devtools': - 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 - -snapshots: - - '@dnd-kit/accessibility@3.1.1(react@19.2.8)': - dependencies: - react: 19.2.8 - tslib: 2.8.1 - - '@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@dnd-kit/accessibility': 3.1.1(react@19.2.8) - '@dnd-kit/utilities': 3.2.2(react@19.2.8) - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - tslib: 2.8.1 - - '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)': - dependencies: - '@dnd-kit/core': 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@dnd-kit/utilities': 3.2.2(react@19.2.8) - react: 19.2.8 - tslib: 2.8.1 - - '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)': - dependencies: - '@dnd-kit/core': 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@dnd-kit/utilities': 3.2.2(react@19.2.8) - react: 19.2.8 - tslib: 2.8.1 - - '@dnd-kit/utilities@3.2.2(react@19.2.8)': - dependencies: - react: 19.2.8 - tslib: 2.8.1 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.10 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.4.10': {} - - '@jridgewell/sourcemap-codec@1.4.14': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - - '@oxc-project/types@0.143.0': {} - - '@oxlint/binding-android-arm-eabi@1.78.0': - optional: true - - '@oxlint/binding-android-arm64@1.78.0': - optional: true - - '@oxlint/binding-darwin-arm64@1.78.0': - optional: true - - '@oxlint/binding-darwin-x64@1.78.0': - optional: true - - '@oxlint/binding-freebsd-x64@1.78.0': - optional: true - - '@oxlint/binding-linux-arm-gnueabihf@1.78.0': - optional: true - - '@oxlint/binding-linux-arm-musleabihf@1.78.0': - optional: true - - '@oxlint/binding-linux-arm64-gnu@1.78.0': - optional: true - - '@oxlint/binding-linux-arm64-musl@1.78.0': - optional: true - - '@oxlint/binding-linux-ppc64-gnu@1.78.0': - optional: true - - '@oxlint/binding-linux-riscv64-gnu@1.78.0': - optional: true - - '@oxlint/binding-linux-riscv64-musl@1.78.0': - optional: true - - '@oxlint/binding-linux-s390x-gnu@1.78.0': - optional: true - - '@oxlint/binding-linux-x64-gnu@1.78.0': - optional: true - - '@oxlint/binding-linux-x64-musl@1.78.0': - optional: true - - '@oxlint/binding-openharmony-arm64@1.78.0': - optional: true - - '@oxlint/binding-win32-arm64-msvc@1.78.0': - optional: true - - '@oxlint/binding-win32-ia32-msvc@1.78.0': - optional: true - - '@oxlint/binding-win32-x64-msvc@1.78.0': - optional: true - - '@rolldown/binding-android-arm64@1.2.3': - optional: true - - '@rolldown/binding-darwin-arm64@1.2.3': - optional: true - - '@rolldown/binding-darwin-x64@1.2.3': - optional: true - - '@rolldown/binding-freebsd-x64@1.2.3': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.2.3': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.2.3': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.2.3': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.2.3': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.2.3': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.2.3': - optional: true - - '@rolldown/binding-linux-x64-musl@1.2.3': - optional: true - - '@rolldown/binding-openharmony-arm64@1.2.3': - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.2.3': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.2.3': - optional: true - - '@rolldown/pluginutils@1.0.1': {} - - '@tailwindcss/node@4.3.3': - dependencies: - '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.24.5 - jiti: 2.7.0 - lightningcss: 1.32.0 - magic-string: 0.30.21 - source-map-js: 1.2.1 - tailwindcss: 4.3.3 - - '@tailwindcss/oxide-android-arm64@4.3.3': - optional: true - - '@tailwindcss/oxide-darwin-arm64@4.3.3': - optional: true - - '@tailwindcss/oxide-darwin-x64@4.3.3': - optional: true - - '@tailwindcss/oxide-freebsd-x64@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-arm64-musl@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-x64-gnu@4.3.3': - optional: true - - '@tailwindcss/oxide-linux-x64-musl@4.3.3': - optional: true - - '@tailwindcss/oxide-wasm32-wasi@4.3.3': - optional: true - - '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': - optional: true - - '@tailwindcss/oxide-win32-x64-msvc@4.3.3': - optional: true - - '@tailwindcss/oxide@4.3.3': - optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.3.3 - '@tailwindcss/oxide-darwin-arm64': 4.3.3 - '@tailwindcss/oxide-darwin-x64': 4.3.3 - '@tailwindcss/oxide-freebsd-x64': 4.3.3 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 - '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 - '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 - '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 - '@tailwindcss/oxide-linux-x64-musl': 4.3.3 - '@tailwindcss/oxide-wasm32-wasi': 4.3.3 - '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 - '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 - - '@tailwindcss/vite@4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))': - dependencies: - '@tailwindcss/node': 4.3.3 - '@tailwindcss/oxide': 4.3.3 - tailwindcss: 4.3.3 - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) - - '@types/node@24.13.3': - dependencies: - undici-types: 7.18.2 - - '@types/react-dom@19.2.4(@types/react@19.2.18)': - dependencies: - '@types/react': 19.2.18 - - '@types/react@19.2.18': - dependencies: - csstype: 3.2.3 - - '@vitejs/plugin-react@6.0.5(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))': - dependencies: - '@rolldown/pluginutils': 1.0.1 - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) - - csstype@3.2.3: {} - - detect-libc@2.1.2: {} - - enhanced-resolve@5.24.5: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - - fdir@6.5.0(picomatch@4.0.5): - optionalDependencies: - picomatch: 4.0.5 - - fsevents@2.3.3: - optional: true - - graceful-fs@4.2.11: {} - - jiti@2.7.0: {} - - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-android-arm64@1.33.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.33.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.33.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.33.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.33.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.33.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.33.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.33.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.33.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.33.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.33.0: - optional: true - - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - - lightningcss@1.33.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.33.0 - lightningcss-darwin-arm64: 1.33.0 - lightningcss-darwin-x64: 1.33.0 - lightningcss-freebsd-x64: 1.33.0 - lightningcss-linux-arm-gnueabihf: 1.33.0 - lightningcss-linux-arm64-gnu: 1.33.0 - lightningcss-linux-arm64-musl: 1.33.0 - lightningcss-linux-x64-gnu: 1.33.0 - lightningcss-linux-x64-musl: 1.33.0 - lightningcss-win32-arm64-msvc: 1.33.0 - lightningcss-win32-x64-msvc: 1.33.0 - - lucide-react@1.33.0(react@19.2.8): - dependencies: - react: 19.2.8 - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - nanoid@3.3.18: {} - - oxlint@1.78.0: - optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.78.0 - '@oxlint/binding-android-arm64': 1.78.0 - '@oxlint/binding-darwin-arm64': 1.78.0 - '@oxlint/binding-darwin-x64': 1.78.0 - '@oxlint/binding-freebsd-x64': 1.78.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.78.0 - '@oxlint/binding-linux-arm-musleabihf': 1.78.0 - '@oxlint/binding-linux-arm64-gnu': 1.78.0 - '@oxlint/binding-linux-arm64-musl': 1.78.0 - '@oxlint/binding-linux-ppc64-gnu': 1.78.0 - '@oxlint/binding-linux-riscv64-gnu': 1.78.0 - '@oxlint/binding-linux-riscv64-musl': 1.78.0 - '@oxlint/binding-linux-s390x-gnu': 1.78.0 - '@oxlint/binding-linux-x64-gnu': 1.78.0 - '@oxlint/binding-linux-x64-musl': 1.78.0 - '@oxlint/binding-openharmony-arm64': 1.78.0 - '@oxlint/binding-win32-arm64-msvc': 1.78.0 - '@oxlint/binding-win32-ia32-msvc': 1.78.0 - '@oxlint/binding-win32-x64-msvc': 1.78.0 - - picocolors@1.1.1: {} - - picomatch@4.0.5: {} - - postcss@8.5.26: - dependencies: - nanoid: 3.3.18 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - react-dom@19.2.8(react@19.2.8): - dependencies: - react: 19.2.8 - scheduler: 0.27.0 - - react@19.2.8: {} - - rolldown@1.2.3: - dependencies: - '@oxc-project/types': 0.143.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.3 - '@rolldown/binding-darwin-arm64': 1.2.3 - '@rolldown/binding-darwin-x64': 1.2.3 - '@rolldown/binding-freebsd-x64': 1.2.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.3 - '@rolldown/binding-linux-arm64-gnu': 1.2.3 - '@rolldown/binding-linux-arm64-musl': 1.2.3 - '@rolldown/binding-linux-ppc64-gnu': 1.2.3 - '@rolldown/binding-linux-s390x-gnu': 1.2.3 - '@rolldown/binding-linux-x64-gnu': 1.2.3 - '@rolldown/binding-linux-x64-musl': 1.2.3 - '@rolldown/binding-openharmony-arm64': 1.2.3 - '@rolldown/binding-win32-arm64-msvc': 1.2.3 - '@rolldown/binding-win32-x64-msvc': 1.2.3 - - scheduler@0.27.0: {} - - source-map-js@1.2.1: {} - - tailwindcss@4.3.3: {} - - tapable@2.3.3: {} - - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 - - tslib@2.8.1: {} - - typescript@6.0.3: {} - - undici-types@7.18.2: {} - - vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0): - dependencies: - lightningcss: 1.33.0 - picomatch: 4.0.5 - postcss: 8.5.26 - rolldown: 1.2.3 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 24.13.3 - fsevents: 2.3.3 - jiti: 2.7.0 diff --git a/code/test-demo/src/App.tsx b/code/test-demo/src/App.tsx deleted file mode 100644 index e0dddf51..00000000 --- a/code/test-demo/src/App.tsx +++ /dev/null @@ -1,1940 +0,0 @@ -import { useState, type ReactNode } from "react"; -import { - Activity, - ChevronDown, - ChevronRight, - CircleHelp, - Database, - FilePlus2, - FolderPlus, - FolderTree, - KeyRound, - LayoutGrid, - Menu as MenuIcon, - MoreHorizontal, - Plus, - Save, - Search, - ShieldCheck, - Trash2, - Users, -} from "lucide-react"; -import "./index.css"; - -type Workspace = "overview" | "domainEntities" | "menuPermissions" | "roles"; -type Domain = { - id: number; - code: string; - name: string; - parentId: number | null; - enabled: boolean; - description: string; -}; -type Entity = { - id: number; - domainId: number; - code: string; - name: string; - view: string; - save: string; - key: string; - type: "table" | "view" | "query"; - enabled: boolean; -}; -type Field = { - id: number; - entityId: number; - code: string; - name: string; - type: string; - nullable: boolean; - enabled: boolean; -}; -type Relation = { - id: number; - entityId: number; - targetEntityId: number; - relationType: "one-to-one" | "one-to-many" | "many-to-one" | "many-to-many"; - foreignField: string; - linkField: string; - ownership: "reference" | "owned"; - deletePolicy: "restrict" | "set-null" | "cascade" | "archive"; - enabled: boolean; -}; -type Menu = { - id: number; - parentId: number | null; - code: string; - name: string; - type: "directory" | "page" | "data"; - route: string; - entityId: number | null; - domainId: number | null; - enabled: boolean; - visible: boolean; -}; -type Role = { id: number; code: string; name: string; members: number }; -type Power = { - id: number; - menuId: number; - code: string; - name: string; - enabled: boolean; -}; - -const initialDomains: Domain[] = [ - { - id: 1, - code: "ocean", - name: "海运业务", - parentId: null, - enabled: true, - description: "订舱、运输节点与费用相关业务能力", - }, - { - id: 2, - code: "booking", - name: "订舱管理", - parentId: 1, - enabled: true, - description: "订舱单据及审核流程", - }, - { - id: 3, - code: "master-data", - name: "基础资料", - parentId: null, - enabled: true, - description: "客户、港口、航线等公共主数据", - }, -]; -const initialEntities: Entity[] = [ - { - id: 1, - domainId: 2, - code: "ocean_booking", - name: "订舱单", - view: "v_ocean_booking_list", - save: "ocean_booking", - key: "b_id", - type: "view", - enabled: true, - }, - { - id: 2, - domainId: 2, - code: "ocean_booking_container", - name: "集装箱明细", - view: "ocean_booking_container", - save: "ocean_booking_container", - key: "b_id", - type: "table", - enabled: true, - }, - { - id: 3, - domainId: 3, - code: "base_customer", - name: "客户档案", - view: "base_customer", - save: "base_customer", - key: "b_id", - type: "table", - enabled: true, - }, -]; -const initialFields: Field[] = [ - { - id: 1, - entityId: 1, - code: "b_ywno", - name: "业务单号", - type: "input", - nullable: false, - enabled: true, - }, - { - id: 2, - entityId: 1, - code: "b_customer_id", - name: "委托客户", - type: "select", - nullable: false, - enabled: true, - }, - { - id: 3, - entityId: 1, - code: "b_ywtype", - name: "业务类型", - type: "select", - nullable: false, - enabled: true, - }, - { - id: 4, - entityId: 1, - code: "b_etd", - name: "预计开船日", - type: "date", - nullable: true, - enabled: true, - }, - { - id: 5, - entityId: 1, - code: "b_state", - name: "单据状态", - type: "select", - nullable: false, - enabled: true, - }, - { - id: 6, - entityId: 3, - code: "b_code", - name: "客户编码", - type: "input", - nullable: false, - enabled: true, - }, - { - id: 7, - entityId: 3, - code: "b_name", - name: "客户名称", - type: "input", - nullable: false, - enabled: true, - }, - { - id: 8, - entityId: 2, - code: "b_booking_id", - name: "订舱单", - type: "number", - nullable: false, - enabled: true, - }, -]; -const initialRelations: Relation[] = [ - { - id: 1, - entityId: 1, - targetEntityId: 2, - relationType: "one-to-many", - foreignField: "b_booking_id", - linkField: "b_id", - ownership: "owned", - deletePolicy: "cascade", - enabled: true, - }, - { - id: 2, - entityId: 1, - targetEntityId: 3, - relationType: "many-to-one", - foreignField: "b_customer_id", - linkField: "b_id", - ownership: "reference", - deletePolicy: "restrict", - enabled: true, - }, -]; -const initialMenus: Menu[] = [ - { - id: 1, - parentId: null, - code: "ocean", - name: "海运业务", - type: "directory", - route: "", - entityId: null, - domainId: 1, - enabled: true, - visible: true, - }, - { - id: 2, - parentId: 1, - code: "booking", - name: "订舱管理", - type: "directory", - route: "", - entityId: null, - domainId: 2, - enabled: true, - visible: true, - }, - { - id: 3, - parentId: 2, - code: "booking-list", - name: "订舱列表", - type: "data", - route: "/ocean/booking", - entityId: 1, - domainId: 2, - enabled: true, - visible: true, - }, - { - id: 4, - parentId: 2, - code: "booking-audit", - name: "订舱审核", - type: "page", - route: "/ocean/booking/audit", - entityId: null, - domainId: 2, - enabled: true, - visible: true, - }, - { - id: 5, - parentId: null, - code: "master-data", - name: "基础资料", - type: "directory", - route: "", - entityId: null, - domainId: 3, - enabled: true, - visible: true, - }, - { - id: 6, - parentId: 5, - code: "customer", - name: "客户档案", - type: "data", - route: "/base/customer", - entityId: 3, - domainId: 3, - enabled: true, - visible: true, - }, -]; -const initialRoles: Role[] = [ - { id: 1, code: "ops", name: "运营专员", members: 18 }, - { id: 2, code: "manager", name: "业务经理", members: 6 }, - { id: 3, code: "admin", name: "系统管理员", members: 2 }, -]; -const actionNames = ["view", "create", "edit", "delete", "export"]; -const actionLabels: Record = { - view: "查看", - create: "新增", - edit: "编辑", - delete: "删除", - export: "导出", -}; -const fieldTypes = [ - "input", - "select", - "date", - "datetime", - "number", - "textarea", -]; - -export default function App() { - const [workspace, setWorkspace] = useState("overview"); - const [domains, setDomains] = useState(initialDomains); - const [entities, setEntities] = useState(initialEntities); - const [fields, setFields] = useState(initialFields); - const [relations, setRelations] = useState(initialRelations); - const [menus, setMenus] = useState(initialMenus); - const [roles] = useState(initialRoles); - const [powers, setPowers] = useState(() => - initialMenus - .filter((menu) => menu.type !== "directory") - .flatMap((menu) => - actionNames.map((action, index) => ({ - id: menu.id * 10 + index, - menuId: menu.id, - code: `${menu.code}.${action}`, - name: actionLabels[action], - enabled: action !== "delete", - })), - ), - ); - const [selectedDomainId, setSelectedDomainId] = useState(2); - const [selectedEntityId, setSelectedEntityId] = useState(1); - const [selectedMenuId, setSelectedMenuId] = useState(3); - const [selectedRoleId, setSelectedRoleId] = useState(1); - const [menuTab, setMenuTab] = useState<"basic" | "powers" | "scope">("basic"); - const [dirty, setDirty] = useState(false); - const [toast, setToast] = useState(""); - const selectedDomain = - domains.find((item) => item.id === selectedDomainId) ?? domains[0]; - const selectedEntity = - entities.find( - (item) => - item.id === selectedEntityId && item.domainId === selectedDomain?.id, - ) ?? entities.find((item) => item.domainId === selectedDomain?.id); - const selectedMenu = - menus.find((item) => item.id === selectedMenuId) ?? menus[0]; - const selectedRole = - roles.find((item) => item.id === selectedRoleId) ?? roles[0]; - const selectDomain = (id: number) => { - setSelectedDomainId(id); - setSelectedEntityId(0); - }; - const selectEntity = (id: number) => { - const entity = entities.find((item) => item.id === id); - if (!entity) return; - setSelectedDomainId(entity.domainId); - setSelectedEntityId(id); - }; - const markDirty = () => setDirty(true); - const save = () => { - setDirty(false); - setToast("配置已保存到当前工作区"); - window.setTimeout(() => setToast(""), 2600); - }; - const addDomain = (parentId: number | null) => { - const id = Math.max(...domains.map((item) => item.id), 0) + 1; - setDomains((items) => [ - ...items, - { - id, - code: `new-domain-${id}`, - name: "新业务域", - parentId, - enabled: true, - description: "请补充业务域说明", - }, - ]); - setSelectedDomainId(id); - setWorkspace("domainEntities"); - markDirty(); - }; - const addEntity = () => { - const id = Math.max(...entities.map((item) => item.id), 0) + 1; - setEntities((items) => [ - ...items, - { - id, - domainId: selectedDomain.id, - code: `new_entity_${id}`, - name: "新实体", - view: "", - save: "", - key: "b_id", - type: "table", - enabled: true, - }, - ]); - setSelectedEntityId(id); - setWorkspace("domainEntities"); - markDirty(); - }; - const addMenu = (type: Menu["type"], parentId: number | null) => { - const id = Math.max(...menus.map((item) => item.id), 0) + 1; - const item: Menu = { - id, - parentId, - code: `new-menu-${id}`, - name: - type === "directory" - ? "新目录" - : type === "data" - ? "新数据页面" - : "新页面", - type, - route: type === "directory" ? "" : "/new-route", - entityId: type === "data" ? (selectedEntity?.id ?? null) : null, - domainId: selectedDomain.id, - enabled: true, - visible: true, - }; - setMenus((items) => [...items, item]); - setSelectedMenuId(id); - setWorkspace("menuPermissions"); - setMenuTab("basic"); - if (type !== "directory") - setPowers((items) => [ - ...items, - ...actionNames.map((action, index) => ({ - id: id * 10 + index, - menuId: id, - code: `${item.code}.${action}`, - name: actionLabels[action], - enabled: action !== "delete", - })), - ]); - markDirty(); - }; - return ( -
-
-
- - - -
- FMS 配置中心 - 业务域与实体 · 菜单与权限 -
-
-
- - 生产环境 -
-
- - - {dirty ? "有未保存修改" : "配置已同步"} - - - 林 -
-
-
- -
- {workspace === "overview" && ( - - )} - {workspace === "domainEntities" && ( - { - setDomains((items) => - items.map((item) => - item.id === selectedDomain.id - ? { ...item, ...patch } - : item, - ), - ); - markDirty(); - }} - onEntityChange={(patch) => { - if (!selectedEntity) return; - setEntities((items) => - items.map((item) => - item.id === selectedEntity.id - ? { ...item, ...patch } - : item, - ), - ); - markDirty(); - }} - onFieldChange={(id, patch) => { - setFields((items) => - items.map((item) => - item.id === id ? { ...item, ...patch } : item, - ), - ); - markDirty(); - }} - onRelationChange={(id, patch) => { - setRelations((items) => - items.map((item) => - item.id === id ? { ...item, ...patch } : item, - ), - ); - markDirty(); - }} - onAddField={() => { - if (!selectedEntity) return; - const id = Math.max(...fields.map((item) => item.id), 0) + 1; - setFields((items) => [ - ...items, - { - id, - entityId: selectedEntity.id, - code: `b_field_${id}`, - name: "新字段", - type: "input", - nullable: true, - enabled: true, - }, - ]); - markDirty(); - }} - /> - )} - {workspace === "menuPermissions" && ( - { - setMenus((items) => - items.map((item) => - item.id === selectedMenu.id ? { ...item, ...patch } : item, - ), - ); - markDirty(); - }} - onToggle={(id) => { - setPowers((items) => - items.map((item) => - item.id === id ? { ...item, enabled: !item.enabled } : item, - ), - ); - markDirty(); - }} - onPublish={() => { - setDirty(false); - setToast("菜单权限已发布"); - window.setTimeout(() => setToast(""), 2600); - }} - /> - )} - {workspace === "roles" && } -
-
- {toast && ( -
- ✓ - {toast} -
- )} -
- ); -} - -function SideNav({ - icon, - label, - caption, - active, - onClick, -}: { - icon: ReactNode; - label: string; - caption?: string; - active: boolean; - onClick: () => void; -}) { - return ( - - ); -} -function PageHeader({ - eyebrow, - title, - description, - action, -}: { - eyebrow: string; - title: string; - description: string; - action?: ReactNode; -}) { - return ( -
-
-
{eyebrow}
-

{title}

-

{description}

-
- {action} -
- ); -} -function StatCard({ - icon, - label, - value, - note, - tone, -}: { - icon: ReactNode; - label: string; - value: string; - note: string; - tone: string; -}) { - return ( -
- {icon} -
- {label} - {value} - {note} -
-
- ); -} -function Overview({ - domains, - entities, - menus, - roles, - onNavigate, -}: { - domains: Domain[]; - entities: Entity[]; - menus: Menu[]; - roles: Role[]; - onNavigate: (workspace: Workspace) => void; -}) { - return ( -
- onNavigate("domainEntities")} - > - - 开始配置 - - } - /> -
- } - label="业务域" - value={String(domains.length)} - note="业务归属分组" - tone="blue" - /> - } - label="实体" - value={String(entities.length)} - note="可查询 / 可保存数据对象" - tone="teal" - /> - } - label="菜单入口" - value={String( - menus.filter((item) => item.type !== "directory").length, - )} - note="页面与数据菜单" - tone="amber" - /> - } - label="角色" - value={String(roles.length)} - note="授权主体" - tone="violet" - /> -
-
-
-
-
-

推荐维护方式

-

每个工作区都把高关联对象放在同一屏幕。

-
- 2 WORKSPACES -
- } - title="业务域与实体" - description="先选业务域,再在右侧维护实体、字段和页面配置。" - onClick={() => onNavigate("domainEntities")} - /> - } - title="菜单与权限" - description="选中菜单后,在同一页面配置入口、动作、角色和数据范围。" - onClick={() => onNavigate("menuPermissions")} - /> - } - title="角色与用户" - description="维护角色和人员归属,授权动作在菜单工作区完成。" - onClick={() => onNavigate("roles")} - /> -
-
-
-
-

底层职责仍然分离

-

页面聚合维护,数据模型保持清晰。

-
-
-
- } - label="业务域" - detail="s_module" - tone="blue" - /> - - } - label="实体" - detail="s_entity" - tone="teal" - /> - - } - label="菜单" - detail="s_menu" - tone="amber" - /> - - } - label="权限" - detail="s_power" - tone="violet" - /> -
-
- - - 管理界面按操作关联度合并,底层仍由实体、菜单、权限表分别持久化。 - -
-
-
-
- ); -} -function WorkflowStep({ - number, - icon, - title, - description, - onClick, -}: { - number: string; - icon: ReactNode; - title: string; - description: string; - onClick: () => void; -}) { - return ( - - ); -} -function ModelNode({ - icon, - label, - detail, - tone, -}: { - icon: ReactNode; - label: string; - detail: string; - tone: string; -}) { - return ( -
- {icon} - {label} - {detail} -
- ); -} -function DetailTitle({ - icon, - eyebrow, - title, - badge, -}: { - icon: ReactNode; - eyebrow: string; - title: string; - badge: string; -}) { - return ( -
- {icon} -
-
{eyebrow}
-

{title}

-
- {badge} -
- ); -} -function LabeledInput({ - label, - value, - onChange, - readOnly = false, -}: { - label: string; - value: string; - onChange?: (value: string) => void; - readOnly?: boolean; -}) { - return ( - - ); -} -function Toggle({ value, onChange }: { value: boolean; onChange: () => void }) { - return ( - - ); -} -function DomainEntityWorkspace({ - domains, - entities, - fields, - relations, - selectedDomain, - selectedEntity, - onSelectDomain, - onSelectEntity, - onAddDomain, - onAddEntity, - onDomainChange, - onEntityChange, - onFieldChange, - onRelationChange, - onAddField, -}: { - domains: Domain[]; - entities: Entity[]; - fields: Field[]; - relations: Relation[]; - selectedDomain: Domain; - selectedEntity?: Entity; - onSelectDomain: (id: number) => void; - onSelectEntity: (id: number) => void; - onAddDomain: (parentId: number | null) => void; - onAddEntity: () => void; - onDomainChange: (patch: Partial) => void; - onEntityChange: (patch: Partial) => void; - onFieldChange: (id: number, patch: Partial) => void; - onRelationChange: (id: number, patch: Partial) => void; - onAddField: () => void; -}) { - const visibleEntities = entities.filter( - (item) => item.domainId === selectedDomain.id, - ); - const entityFields = selectedEntity - ? fields.filter((item) => item.entityId === selectedEntity.id) - : []; - const entityRelations = selectedEntity - ? relations.filter((item) => item.entityId === selectedEntity.id) - : []; - return ( -
- - - -
- } - /> -
-
-
-
-

业务模型树

-

- {domains.length} 个业务域 · {entities.length} 个实体 -

-
- -
-
- - -
-
- {renderBusinessTree( - domains, - entities, - relations, - null, - 0, - selectedDomain.id, - selectedEntity?.id ?? 0, - onSelectDomain, - onSelectEntity, - )} -
-
- {selectedDomain.name} - {selectedDomain.description} - -
-
-
-
-
-

- {selectedEntity ? selectedEntity.name : selectedDomain.name} -

-

- {selectedEntity - ? "实体数据边界、字段与关系配置" - : `${visibleEntities.length} 个直接归属实体`} -

-
- - {selectedEntity ? "S_ENTITY" : "S_MODULE"} - -
- {!selectedEntity && ( - <> - } - eyebrow="S_MODULE" - title={selectedDomain.name} - badge={selectedDomain.enabled ? "启用中" : "已停用"} - /> -
- onDomainChange({ code: value })} - /> - onDomainChange({ name: value })} - /> -