feat:接入mcp,为模型提供图表信息
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"docs-langchain": {
|
||||
"type": "http",
|
||||
"url": "https://docs.langchain.com/mcp"
|
||||
},
|
||||
"reference-langchain": {
|
||||
"type": "http",
|
||||
"url": "https://reference.langchain.com/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -165,9 +165,9 @@ def plan_materials(state: QueryState) -> list[dict]:
|
||||
if not types:
|
||||
return []
|
||||
|
||||
# 按类型提取全部匹配物料,使用协议别名输出 schema 等字段
|
||||
# 按类型提取全部匹配物料,使用协议别名输出 schema 等字段;字段定义由查询工具按需提供
|
||||
return [
|
||||
item.model_dump(mode="json", by_alias=True)
|
||||
item.model_dump(mode="json", by_alias=True, exclude={"field_groups"})
|
||||
for item in state["component_resources"].components
|
||||
if item.type in types
|
||||
]
|
||||
|
||||
+35
-15
@@ -3,9 +3,37 @@
|
||||
from copy import deepcopy
|
||||
|
||||
from app.actions.base import BaseActionHandler
|
||||
from app.resources.material_fields import editable_fields, known_prop_keys
|
||||
from app.schemas.actions import UpdateAction
|
||||
from app.schemas.screen import Screen
|
||||
from app.schemas.screen import Screen, ScreenNode
|
||||
|
||||
|
||||
def fit_existing_path(node: ScreenNode, action: UpdateAction) -> UpdateAction:
|
||||
"""字段定义允许的路径在组件中可能还没有中间对象(例如未开启过的数值标签)
|
||||
|
||||
前端只按已有路径赋值,这里把缺失的部分折叠进值里:改为更新最近的已有对象,
|
||||
值为补齐的嵌套对象;缺失的若是数组元素则无法补齐,保持原样交给执行时报错
|
||||
"""
|
||||
if action.section == "name":
|
||||
return action
|
||||
current = getattr(node, action.section) or {}
|
||||
for index, segment in enumerate(action.path[:-1]):
|
||||
if isinstance(current, dict) and isinstance(segment, str) and segment not in current:
|
||||
rest = action.path[index + 1 :]
|
||||
if not all(isinstance(item, str) for item in rest):
|
||||
return action
|
||||
value = action.value
|
||||
for item in reversed(rest):
|
||||
value = {item: value}
|
||||
return action.model_copy(
|
||||
update={"path": action.path[: index + 1], "value": value}
|
||||
)
|
||||
if isinstance(current, dict) and isinstance(segment, str):
|
||||
current = current[segment]
|
||||
elif isinstance(current, list) and type(segment) is int and segment < len(current):
|
||||
current = current[segment]
|
||||
else:
|
||||
return action
|
||||
return action
|
||||
|
||||
|
||||
class UpdateHandler(BaseActionHandler[UpdateAction]):
|
||||
@@ -13,23 +41,15 @@ class UpdateHandler(BaseActionHandler[UpdateAction]):
|
||||
# 确认目标存在,后续路径访问和赋值均在大屏副本中进行
|
||||
result, target = self.copy_target(screen, action.target_id)
|
||||
|
||||
# 组件名称是节点顶层字段,没有后续路径
|
||||
if action.section == "name":
|
||||
target.name = action.value
|
||||
return result
|
||||
|
||||
# 未设置的 style 视为空对象,只允许直接添加末级字段
|
||||
if action.section == "style" and target.style is None:
|
||||
target.style = {}
|
||||
|
||||
# props 第一层不能新造字段:渲染器不会读取约定外的字段,新造只会“成功”却没有效果
|
||||
if action.section == "props":
|
||||
known = known_prop_keys(target)
|
||||
if known is not None and action.path[0] not in known:
|
||||
labels = "、".join(
|
||||
f"{field['label']}={field['section']}.{field['path']}"
|
||||
for field in editable_fields(target.type)
|
||||
)
|
||||
raise ValueError(
|
||||
f"组件 {target.type} 的 props 没有字段 {action.path[0]!r},"
|
||||
f"不能新造组件级属性;可编辑字段:{labels or '无'}"
|
||||
)
|
||||
|
||||
# 获取动作指定的属性区域,作为路径遍历的起点
|
||||
current = getattr(target, action.section)
|
||||
# 逐段访问路径,只有到达末级时才写入新值
|
||||
|
||||
@@ -5,15 +5,15 @@ from fastapi import APIRouter
|
||||
from app.common.response import ApiResponse, success_response
|
||||
from app.core.exceptions import BizException
|
||||
from app.resources.component import get_catalog_cache
|
||||
from app.schemas.component_resource import ComponentCatalog
|
||||
from app.resources.material_fields import frontend_catalog
|
||||
|
||||
router = APIRouter(prefix="/materials", tags=["Material"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def list_materials() -> ApiResponse[ComponentCatalog]:
|
||||
# 直接返回启动时载入的内存缓存,不查库
|
||||
async def list_materials() -> ApiResponse[dict]:
|
||||
# 直接使用启动时载入的内存缓存,不查库;属性面板 setters 由字段定义派生
|
||||
catalog = get_catalog_cache()
|
||||
if catalog is None:
|
||||
raise BizException(503, "物料目录尚未加载")
|
||||
return success_response(catalog)
|
||||
return success_response(frontend_catalog(catalog))
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
"""物料字段 MCP 客户端:把字段查询工具交给模型使用
|
||||
|
||||
服务只监听本机,由应用启动时拉起;不可用时直接报错,不退回其他查询方式
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from langchain_core.tools import BaseTool
|
||||
from langchain_mcp_adapters.client import MultiServerMCPClient
|
||||
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
||||
from loguru import logger
|
||||
from mcp.types import CallToolResult
|
||||
|
||||
from app.config import settings
|
||||
from app.resources.component import get_catalog_cache
|
||||
|
||||
SERVER_NAME = "materials"
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
class MaterialFieldServiceError(RuntimeError):
|
||||
"""物料字段服务不可用,或与主进程的物料目录版本不一致"""
|
||||
|
||||
|
||||
async def _check_version(request: MCPToolCallRequest, handler):
|
||||
"""限制单次查询耗时;返回的目录版本须与主进程一致,否则模型查到的字段和校验依据不同"""
|
||||
try:
|
||||
result = await asyncio.wait_for(
|
||||
handler(request), timeout=settings.mcp_tool_timeout
|
||||
)
|
||||
except TimeoutError as error:
|
||||
raise MaterialFieldServiceError(f"物料字段查询超时: {request.name}") from error
|
||||
if isinstance(result, CallToolResult) and result.structuredContent:
|
||||
served = result.structuredContent.get("catalog_version")
|
||||
catalog = get_catalog_cache()
|
||||
expected = catalog.version if catalog is not None else None
|
||||
if served != expected:
|
||||
raise MaterialFieldServiceError(
|
||||
f"物料字段服务的目录版本 {served} 与主服务 {expected} 不一致,请重启服务"
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
_client = MultiServerMCPClient(
|
||||
{
|
||||
SERVER_NAME: {
|
||||
"transport": "streamable_http",
|
||||
"url": settings.mcp_material_url,
|
||||
}
|
||||
},
|
||||
tool_interceptors=[_check_version],
|
||||
# 未知组件类型、分组等查询错误返回给模型自行修正;连接失败等仍直接抛出
|
||||
handle_tool_errors=True,
|
||||
)
|
||||
_tools: list[BaseTool] | None = None
|
||||
|
||||
|
||||
async def get_material_tools() -> list[BaseTool]:
|
||||
"""字段查询工具;首次使用或此前连接失败时向服务拉取工具清单"""
|
||||
global _tools
|
||||
if _tools is None:
|
||||
try:
|
||||
_tools = await asyncio.wait_for(
|
||||
_client.get_tools(server_name=SERVER_NAME),
|
||||
timeout=settings.mcp_tool_timeout,
|
||||
)
|
||||
except Exception as error:
|
||||
raise MaterialFieldServiceError(
|
||||
f"物料字段服务不可用: {settings.mcp_material_url}"
|
||||
) from error
|
||||
return _tools
|
||||
|
||||
|
||||
def _port_open(port: int) -> bool:
|
||||
with socket.socket() as probe:
|
||||
probe.settimeout(0.2)
|
||||
return probe.connect_ex(("127.0.0.1", port)) == 0
|
||||
|
||||
|
||||
async def start_material_server() -> subprocess.Popen | None:
|
||||
"""本机地址且尚未运行时拉起服务,返回进程供退出时关闭;已运行则直接复用"""
|
||||
target = urlsplit(settings.mcp_material_url)
|
||||
if target.hostname not in {"localhost", "127.0.0.1"}:
|
||||
raise MaterialFieldServiceError("物料字段服务只能部署在本机,不对外暴露")
|
||||
port = target.port or 80
|
||||
if _port_open(port):
|
||||
return None
|
||||
process = subprocess.Popen(
|
||||
[sys.executable, "-X", "utf8", "-m", "mcp_servers.material_server"],
|
||||
cwd=PROJECT_ROOT,
|
||||
env={**os.environ, "PORT": str(port)},
|
||||
)
|
||||
for _ in range(100):
|
||||
if process.poll() is not None:
|
||||
raise MaterialFieldServiceError("物料字段服务启动失败,请查看终端日志")
|
||||
if _port_open(port):
|
||||
logger.info("物料字段服务已启动: {}", settings.mcp_material_url)
|
||||
return process
|
||||
await asyncio.sleep(0.1)
|
||||
await stop_material_server(process)
|
||||
raise MaterialFieldServiceError("物料字段服务启动超时")
|
||||
|
||||
|
||||
async def stop_material_server(process: subprocess.Popen | None) -> None:
|
||||
if process is None or process.poll() is not None:
|
||||
return
|
||||
process.terminate()
|
||||
try:
|
||||
await asyncio.to_thread(process.wait, timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
process.kill()
|
||||
await asyncio.to_thread(process.wait)
|
||||
@@ -58,6 +58,21 @@ class Settings:
|
||||
default_factory=lambda: int(os.getenv("MAX_ACTION_RETRIES", "2"))
|
||||
)
|
||||
|
||||
# 物料字段 MCP 服务:只给模型查询字段定义,只监听本机,随应用启动
|
||||
mcp_material_url: str = field(
|
||||
default_factory=lambda: (
|
||||
os.getenv("MCP_MATERIAL_URL") or "http://127.0.0.1:8201/mcp"
|
||||
)
|
||||
)
|
||||
# 单次字段查询的超时(秒)
|
||||
mcp_tool_timeout: float = field(
|
||||
default_factory=lambda: float(os.getenv("MCP_TOOL_TIMEOUT", "5"))
|
||||
)
|
||||
# 生成动作或修正建议时,最多几轮查询字段,之后必须给出结果
|
||||
max_field_tool_rounds: int = field(
|
||||
default_factory=lambda: int(os.getenv("MAX_FIELD_TOOL_ROUNDS", "4"))
|
||||
)
|
||||
|
||||
# 没有任何对话的空会话保留时长(秒),超时后视为不存在
|
||||
conversation_empty_ttl: int = field(
|
||||
default_factory=lambda: int(os.getenv("CONVERSATION_EMPTY_TTL", "7200"))
|
||||
@@ -113,6 +128,10 @@ class Settings:
|
||||
raise ValueError("CONVERSATION_HISTORY_TURNS 必须是非负整数")
|
||||
if type(self.max_action_retries) is not int or self.max_action_retries < 0:
|
||||
raise ValueError("MAX_ACTION_RETRIES 必须是非负整数")
|
||||
if self.mcp_tool_timeout <= 0:
|
||||
raise ValueError("MCP_TOOL_TIMEOUT 必须是正数")
|
||||
if self.max_field_tool_rounds < 0:
|
||||
raise ValueError("MAX_FIELD_TOOL_ROUNDS 必须是非负整数")
|
||||
if not 0 <= self.intent_min_probability <= 1:
|
||||
raise ValueError("INTENT_MIN_PROBABILITY 必须在 0 到 1 之间")
|
||||
if not 0 <= self.intent_qa_min_probability <= 1:
|
||||
|
||||
+19
-6
@@ -18,6 +18,11 @@ from app.core.logging import setup_logging
|
||||
async def lifespan(application: FastAPI):
|
||||
setup_logging()
|
||||
from app.clients.decision import close_decision_engine
|
||||
from app.clients.material_mcp import (
|
||||
MaterialFieldServiceError,
|
||||
start_material_server,
|
||||
stop_material_server,
|
||||
)
|
||||
from app.clients.user_center import close_user_center
|
||||
from app.observability.tracing import flush_tracing
|
||||
from app.processor.graph import build_graph
|
||||
@@ -28,9 +33,15 @@ async def lifespan(application: FastAPI):
|
||||
# 按配置选择 MongoDB 或进程内存,会话记录与图检查点使用同一种存储
|
||||
persistence = await open_persistence()
|
||||
application.state.conversation_store = persistence.store
|
||||
material_server = None
|
||||
try:
|
||||
# 物料目录启动时载入内存,agent 规划与前端接口共用,避免重复查询数据库
|
||||
await warm_material_cache(persistence.db)
|
||||
# 物料字段服务给模型查询字段;启动失败只记录,需要查字段的修改执行时会报错
|
||||
try:
|
||||
material_server = await start_material_server()
|
||||
except MaterialFieldServiceError as error:
|
||||
logger.error("{},修改组件属性和新增组件将无法执行", error)
|
||||
application.state.agent_service = AgentService(
|
||||
build_graph(persistence.checkpointer), persistence.store
|
||||
)
|
||||
@@ -38,19 +49,21 @@ async def lifespan(application: FastAPI):
|
||||
finally:
|
||||
# 共享客户端只在应用退出时关闭,追踪刷新放到线程避免阻塞事件循环
|
||||
try:
|
||||
await persistence.close()
|
||||
await stop_material_server(material_server)
|
||||
finally:
|
||||
try:
|
||||
await close_decision_engine()
|
||||
await persistence.close()
|
||||
finally:
|
||||
try:
|
||||
await close_user_center()
|
||||
await close_decision_engine()
|
||||
finally:
|
||||
try:
|
||||
await asyncio.to_thread(flush_tracing)
|
||||
await close_user_center()
|
||||
finally:
|
||||
await logger.complete()
|
||||
|
||||
try:
|
||||
await asyncio.to_thread(flush_tracing)
|
||||
finally:
|
||||
await logger.complete()
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
application = FastAPI(title="Screen Agent API", lifespan=lifespan)
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
"""需要物料字段的模型调用:模型按需调用字段查询工具,最后按指定结构输出
|
||||
|
||||
动作生成和修正建议共用;字段查询走物料字段 MCP 服务,服务不可用时直接报错
|
||||
"""
|
||||
|
||||
from typing import TypeVar
|
||||
|
||||
from langchain.agents import create_agent
|
||||
from langchain.agents.middleware import wrap_model_call
|
||||
from langchain.agents.structured_output import ToolStrategy
|
||||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.clients.llm import get_llm
|
||||
from app.clients.material_mcp import get_material_tools
|
||||
from app.config import settings
|
||||
from app.processor.state import QueryState
|
||||
from app.resources.component import get_catalog_cache
|
||||
from app.resources.material_fields import list_field_groups
|
||||
|
||||
OutputModel = TypeVar("OutputModel", bound=BaseModel)
|
||||
|
||||
|
||||
@wrap_model_call
|
||||
async def _limit_field_queries(request, handler):
|
||||
"""查询轮数用尽后只保留输出工具,模型必须给出结果"""
|
||||
rounds = sum(isinstance(message, AIMessage) for message in request.messages)
|
||||
if rounds >= settings.max_field_tool_rounds:
|
||||
request = request.override(tools=[])
|
||||
return await handler(request)
|
||||
|
||||
|
||||
async def invoke_with_field_tools(
|
||||
schema: type[OutputModel], system_prompt: str, content: str
|
||||
) -> OutputModel | None:
|
||||
"""返回结构化结果;模型未给出结果时返回 None
|
||||
|
||||
结果不符合 schema 时抛出 StructuredOutputValidationError,由调用方转换为校验错误
|
||||
"""
|
||||
agent = create_agent(
|
||||
get_llm(),
|
||||
await get_material_tools(),
|
||||
system_prompt=system_prompt,
|
||||
# 不在调用内自动重试,结构错误交给后续校验和修正流程,与不查字段时一致
|
||||
response_format=ToolStrategy(schema, handle_errors=False),
|
||||
middleware=[_limit_field_queries],
|
||||
name=f"{schema.__name__}_with_fields",
|
||||
)
|
||||
result = await agent.ainvoke(
|
||||
{"messages": [HumanMessage(content=content)]},
|
||||
# 每轮模型调用和工具执行各占一步,轮数由中间件限制,这里只防止异常循环
|
||||
config={"recursion_limit": 2 * settings.max_field_tool_rounds + 6},
|
||||
)
|
||||
return result.get("structured_response")
|
||||
|
||||
|
||||
def field_group_directory(state: QueryState) -> dict[str, dict]:
|
||||
"""本次相关组件的字段分组目录,按物料类型列出,省去模型先查目录的一轮调用"""
|
||||
nodes = {node.id: node.type for node in state["input_context"].screen.nodes}
|
||||
plan = state.get("screen_plan")
|
||||
if plan is None:
|
||||
types = [
|
||||
nodes[target]
|
||||
for change in state["requirement"].changes
|
||||
if change.target_scope == "nodes"
|
||||
for target in change.target_ids
|
||||
if target in nodes
|
||||
]
|
||||
else:
|
||||
types = [
|
||||
item.component_type
|
||||
if item.disposition in ("add", "replace")
|
||||
else nodes.get(item.target_id)
|
||||
for item in plan.components
|
||||
if item.disposition in ("add", "replace", "modify")
|
||||
]
|
||||
catalog = get_catalog_cache()
|
||||
directory = {}
|
||||
for component_type in dict.fromkeys(item for item in types if item):
|
||||
try:
|
||||
if catalog is None:
|
||||
raise ValueError("物料目录未载入")
|
||||
directory[component_type] = {
|
||||
key: value
|
||||
for key, value in list_field_groups(catalog, component_type).items()
|
||||
if key not in ("component_type", "catalog_version")
|
||||
}
|
||||
except ValueError as error:
|
||||
# 没有物料定义的组件不能修改属性,告诉模型原因
|
||||
directory[component_type] = {"error": str(error)}
|
||||
return directory
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
import json
|
||||
|
||||
from langchain.agents.structured_output import (
|
||||
StructuredOutputError,
|
||||
StructuredOutputValidationError,
|
||||
)
|
||||
from langchain_core.exceptions import OutputParserException
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
from pydantic import ValidationError
|
||||
@@ -9,13 +13,18 @@ from pydantic import ValidationError
|
||||
from app.actions.plan import assemble_plan_actions, plan_block_reason, plan_materials
|
||||
from app.clients.llm import get_llm
|
||||
from app.processor.base import BaseNode
|
||||
from app.processor.material_agent import field_group_directory, invoke_with_field_tools
|
||||
from app.processor.state import QueryState
|
||||
from app.prompt.action import build_action_prompt
|
||||
from app.resources.material_fields import editable_fields
|
||||
from app.prompt.action import build_action_prompt, uses_material_fields
|
||||
from app.schemas.action_validation import ActionValidationError, schema_errors
|
||||
from app.schemas.actions import ActionBatch, AddAction
|
||||
from app.schemas.operations import is_direct_operation
|
||||
|
||||
GENERATION_ERROR = ActionValidationError(
|
||||
code="generation_error",
|
||||
message="模型输出无法解析为 ActionBatch,请按协议重新生成",
|
||||
)
|
||||
|
||||
|
||||
def can_generate_actions(state: QueryState) -> bool:
|
||||
# 没有阻塞原因时才允许生成动作,路由和节点入口复用同一套能力检查
|
||||
@@ -59,28 +68,6 @@ def action_block_reason(state: QueryState) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
def update_fields(state: QueryState) -> dict[str, list[dict]]:
|
||||
"""按组件 ID 汇总可能被属性更新的已有组件的可编辑字段,没有字段的组件省略"""
|
||||
plan = state.get("screen_plan")
|
||||
if plan is None:
|
||||
target_ids = [
|
||||
target
|
||||
for change in state["requirement"].changes
|
||||
if change.target_scope == "nodes"
|
||||
for target in change.target_ids
|
||||
]
|
||||
else:
|
||||
target_ids = [
|
||||
item.target_id for item in plan.components if item.disposition == "modify"
|
||||
]
|
||||
nodes = {node.id: node for node in state["input_context"].screen.nodes}
|
||||
result = {}
|
||||
for target in dict.fromkeys(target_ids):
|
||||
if target in nodes and (fields := editable_fields(nodes[target].type)):
|
||||
result[target] = fields
|
||||
return result
|
||||
|
||||
|
||||
class ActionNode(BaseNode):
|
||||
name = "action_node"
|
||||
|
||||
@@ -115,10 +102,6 @@ class ActionNode(BaseNode):
|
||||
payload["screen_plan"] = state["screen_plan"].model_dump(mode="json")
|
||||
payload["component_materials"] = plan_materials(state)
|
||||
|
||||
# 提供待修改组件的属性面板字段,让模型把用户说的“标题”“颜色”等对应到真实路径
|
||||
if fields := update_fields(state):
|
||||
payload["editable_fields"] = fields
|
||||
|
||||
# 如果本轮是动作修正,提供修正建议、上一轮动作和校验错误供模型参考
|
||||
if state.get("repair_plan") is not None:
|
||||
payload.update(
|
||||
@@ -133,7 +116,17 @@ class ActionNode(BaseNode):
|
||||
],
|
||||
)
|
||||
|
||||
llm_client = get_llm(ActionBatch)
|
||||
system_prompt = build_action_prompt(
|
||||
state["requirement"],
|
||||
state.get("screen_plan"),
|
||||
repairing=state.get("repair_plan") is not None,
|
||||
)
|
||||
# 需要写组件属性时提供相关组件的字段分组,模型再按需查询字段定义
|
||||
with_fields = uses_material_fields(state["requirement"], state.get("screen_plan"))
|
||||
if with_fields:
|
||||
payload["field_groups"] = field_group_directory(state)
|
||||
# 将本次具体资料放入用户消息,保留中文以便阅读和排查
|
||||
content = json.dumps(payload, ensure_ascii=False)
|
||||
|
||||
# 旧动作及错误已放入模型输入,现在清空输出状态,避免本轮失败后残留旧结果
|
||||
updated_state["actions"] = None
|
||||
@@ -146,19 +139,12 @@ class ActionNode(BaseNode):
|
||||
# 捕获输出结构和解析错误,转换成统一校验结果供后续修正流程使用
|
||||
try:
|
||||
# 异步调用模型,根据需求、规划及是否正在修正选择对应的系统规则
|
||||
result = await llm_client.ainvoke(
|
||||
[
|
||||
SystemMessage(
|
||||
content=build_action_prompt(
|
||||
state["requirement"],
|
||||
state.get("screen_plan"),
|
||||
repairing=state.get("repair_plan") is not None,
|
||||
)
|
||||
),
|
||||
# 将本次具体资料放入用户消息,保留中文以便阅读和排查
|
||||
HumanMessage(content=json.dumps(payload, ensure_ascii=False)),
|
||||
]
|
||||
)
|
||||
if with_fields:
|
||||
result = await invoke_with_field_tools(ActionBatch, system_prompt, content)
|
||||
else:
|
||||
result = await get_llm(ActionBatch).ainvoke(
|
||||
[SystemMessage(content=system_prompt), HumanMessage(content=content)]
|
||||
)
|
||||
|
||||
# 响应中没有工具调用时解析器会返回 None
|
||||
if result is None:
|
||||
@@ -184,15 +170,19 @@ class ActionNode(BaseNode):
|
||||
updated_state["validation_passed"] = False
|
||||
updated_state["validation_errors"] = schema_errors(error)
|
||||
return updated_state
|
||||
except OutputParserException:
|
||||
except StructuredOutputValidationError as error:
|
||||
# 查询字段后的输出不符合结构,与直接输出时的处理一致
|
||||
updated_state["validation_passed"] = False
|
||||
updated_state["validation_errors"] = (
|
||||
schema_errors(error.source)
|
||||
if isinstance(error.source, ValidationError)
|
||||
else [GENERATION_ERROR]
|
||||
)
|
||||
return updated_state
|
||||
except (OutputParserException, StructuredOutputError):
|
||||
# 如果模型输出无法解析,记录生成错误,提示后续按 ActionBatch 协议重新生成
|
||||
updated_state["validation_passed"] = False
|
||||
updated_state["validation_errors"] = [
|
||||
ActionValidationError(
|
||||
code="generation_error",
|
||||
message="模型输出无法解析为 ActionBatch,请按协议重新生成",
|
||||
)
|
||||
]
|
||||
updated_state["validation_errors"] = [GENERATION_ERROR]
|
||||
return updated_state
|
||||
|
||||
# 保存生成的动作,实际目标、规划一致性及模拟执行结果仍由后续校验节点检查
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import json
|
||||
|
||||
from langchain.agents.structured_output import StructuredOutputError
|
||||
from langchain_core.exceptions import OutputParserException
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
from pydantic import ValidationError
|
||||
@@ -9,7 +10,9 @@ from pydantic import ValidationError
|
||||
from app.actions.plan import plan_materials
|
||||
from app.clients.llm import get_llm
|
||||
from app.processor.base import BaseNode
|
||||
from app.processor.material_agent import field_group_directory, invoke_with_field_tools
|
||||
from app.processor.state import QueryState
|
||||
from app.prompt.action import FIELD_QUERY_PROMPT, uses_material_fields
|
||||
from app.schemas.capabilities import USER_FAILURE_MESSAGE
|
||||
from app.prompt.reflection import REFLECTION_SYSTEM_PROMPT
|
||||
from app.schemas.action_repair import ActionRepairPlan
|
||||
@@ -22,7 +25,6 @@ class ReflectionNode(BaseNode):
|
||||
# 浅拷贝状态
|
||||
updated_state: QueryState = state.copy()
|
||||
|
||||
llm_client = get_llm(ActionRepairPlan)
|
||||
# 汇总原始上下文、需求和失败信息,让模型基于实际错误提出修正建议
|
||||
payload = {
|
||||
"input_context": state["input_context"].model_dump(mode="json"),
|
||||
@@ -46,21 +48,30 @@ class ReflectionNode(BaseNode):
|
||||
payload["screen_plan"] = state["screen_plan"].model_dump(mode="json")
|
||||
payload["component_materials"] = plan_materials(state)
|
||||
|
||||
# 涉及组件属性时,修正建议须基于查询到的字段定义,与动作生成使用同一组工具
|
||||
with_fields = uses_material_fields(state["requirement"], state.get("screen_plan"))
|
||||
if with_fields:
|
||||
payload["field_groups"] = field_group_directory(state)
|
||||
# 用户消息承载本轮待分析的具体资料,序列化时保留中文
|
||||
content = json.dumps(payload, ensure_ascii=False)
|
||||
|
||||
# 只捕获输出结构和解析错误,配置、网络等异常继续向上抛出
|
||||
try:
|
||||
# 异步生成修正建议,本节点不直接修改动作
|
||||
plan = await llm_client.ainvoke(
|
||||
[
|
||||
# 系统消息提供稳定的失败分析和修正规则
|
||||
SystemMessage(content=REFLECTION_SYSTEM_PROMPT),
|
||||
# 用户消息承载本轮待分析的具体资料,序列化时保留中文
|
||||
HumanMessage(content=json.dumps(payload, ensure_ascii=False)),
|
||||
]
|
||||
)
|
||||
if with_fields:
|
||||
plan = await invoke_with_field_tools(
|
||||
ActionRepairPlan,
|
||||
REFLECTION_SYSTEM_PROMPT + "\n" + FIELD_QUERY_PROMPT,
|
||||
content,
|
||||
)
|
||||
else:
|
||||
plan = await get_llm(ActionRepairPlan).ainvoke(
|
||||
[SystemMessage(content=REFLECTION_SYSTEM_PROMPT), HumanMessage(content=content)]
|
||||
)
|
||||
# 响应中没有工具调用时解析器会返回 None
|
||||
if plan is None:
|
||||
raise OutputParserException("模型未返回结构化结果")
|
||||
except (ValidationError, OutputParserException):
|
||||
except (ValidationError, OutputParserException, StructuredOutputError):
|
||||
# 如果未能得到合法建议,清空旧修正计划,避免再次使用已失效的建议
|
||||
updated_state["repair_plan"] = None
|
||||
# 记录无法继续修正的原因,交给后续路由和失败处理流程
|
||||
|
||||
@@ -4,10 +4,18 @@ from pydantic import ValidationError
|
||||
|
||||
from app.actions.plan import validate_plan_actions, validate_plan_result
|
||||
from app.actions.registry import apply_action
|
||||
from app.actions.update import fit_existing_path
|
||||
from app.processor.base import BaseNode
|
||||
from app.processor.state import QueryState
|
||||
from app.resources.component import get_catalog_cache
|
||||
from app.resources.material_fields import check_update_field
|
||||
from app.schemas.action_validation import ActionValidationError, schema_errors
|
||||
from app.schemas.actions import ActionBatch, AddAction, UpdateCanvasAction
|
||||
from app.schemas.actions import (
|
||||
ActionBatch,
|
||||
AddAction,
|
||||
UpdateAction,
|
||||
UpdateCanvasAction,
|
||||
)
|
||||
from app.schemas.operations import is_canvas_operation
|
||||
|
||||
|
||||
@@ -121,8 +129,32 @@ class ValidatorNode(BaseNode):
|
||||
# 在副本上试执行,不改变用户传入的大屏,也不操作前端画布
|
||||
screen = state["input_context"].screen.model_copy(deep=True)
|
||||
|
||||
catalog = get_catalog_cache()
|
||||
# 保存补齐路径后的动作,前端按它执行
|
||||
actions = list(batch.actions)
|
||||
|
||||
# 按动作顺序逐项执行,每一步都使用上一步更新后的大屏副本
|
||||
for index, action in enumerate(batch.actions):
|
||||
for index, action in enumerate(actions):
|
||||
# 属性更新先按物料字段定义检查,目标不存在时交给处理器报错
|
||||
node = (
|
||||
next((item for item in screen.nodes if item.id == action.target_id), None)
|
||||
if isinstance(action, UpdateAction)
|
||||
else None
|
||||
)
|
||||
if node is not None:
|
||||
try:
|
||||
check_update_field(catalog, node.type, action)
|
||||
except ValueError as error:
|
||||
updated_state["validation_passed"] = False
|
||||
updated_state["validation_errors"] = [
|
||||
ActionValidationError(
|
||||
action_index=index, code="field_error", message=str(error)
|
||||
)
|
||||
]
|
||||
updated_state["simulated_screen"] = None
|
||||
return updated_state
|
||||
# 字段定义允许、但组件中还没有的中间对象,折叠进值里再执行
|
||||
action = actions[index] = fit_existing_path(node, action)
|
||||
try:
|
||||
# 根据动作类型调用对应处理逻辑,检查目标和参数并返回更新后的大屏
|
||||
screen = apply_action(screen, action)
|
||||
@@ -147,8 +179,8 @@ class ValidatorNode(BaseNode):
|
||||
updated_state["simulated_screen"] = None
|
||||
return updated_state
|
||||
|
||||
# 全部检查通过后,保存重新校验过的动作对象,统一后续读取的数据结构
|
||||
updated_state["actions"] = batch.actions
|
||||
# 全部检查通过后,保存重新校验并补齐路径的动作对象,统一后续读取的数据结构
|
||||
updated_state["actions"] = actions
|
||||
# 标记整批动作校验通过,并清空之前可能残留的错误
|
||||
updated_state["validation_passed"] = True
|
||||
updated_state["validation_errors"] = []
|
||||
|
||||
+48
-21
@@ -53,6 +53,46 @@ REPAIR_TASK_PROMPT = """# 当前阶段:修正重试
|
||||
"""
|
||||
|
||||
|
||||
FIELD_QUERY_PROMPT = """# 查询组件字段
|
||||
field_groups 按物料类型列出本次相关组件的字段分组,节点的 type 就是物料类型
|
||||
确定要改的字段:用用户原话中对属性的说法(input_context 中的提问,不用改写后的需求)调用 search_fields;
|
||||
返回多个字段时,依据字段说明判断用户指的是哪一个;用户看的是大屏画面,没有提到图层列表、属性面板等编辑器位置时,按画面上看得到的内容理解
|
||||
需要了解一组相关字段时用 get_fields,一次可查多个分组
|
||||
只能使用查询到的字段路径,值须符合字段的类型、可选值和取值范围;查不到对应字段说明不支持,不自行编造路径
|
||||
"""
|
||||
|
||||
# 这些动作会写组件属性,需要先查物料字段
|
||||
FIELD_ACTIONS = frozenset({"update", "add"})
|
||||
|
||||
|
||||
def action_types(requirement: Requirement, screen_plan: ScreenPlan | None) -> set[str]:
|
||||
"""本次需要的动作类型:简单修改按需求变更,规划按各组件的处理方式"""
|
||||
if screen_plan is None:
|
||||
return {
|
||||
"update_canvas" if change.target_scope == "canvas" else change.operation
|
||||
for change in requirement.changes
|
||||
}
|
||||
types = set()
|
||||
if screen_plan.canvas_changes:
|
||||
types.add("update_canvas")
|
||||
for item in screen_plan.components:
|
||||
if item.disposition in ("add", "replace"):
|
||||
types.add("add")
|
||||
elif item.disposition == "remove":
|
||||
types.add("delete")
|
||||
elif item.disposition == "modify":
|
||||
types.update(("move", "resize"))
|
||||
if item.design:
|
||||
types.add("update")
|
||||
return types
|
||||
|
||||
|
||||
def uses_material_fields(
|
||||
requirement: Requirement, screen_plan: ScreenPlan | None
|
||||
) -> bool:
|
||||
return bool(action_types(requirement, screen_plan) & FIELD_ACTIONS)
|
||||
|
||||
|
||||
def build_action_prompt(
|
||||
requirement: Requirement,
|
||||
screen_plan: ScreenPlan | None = None,
|
||||
@@ -60,40 +100,27 @@ def build_action_prompt(
|
||||
repairing: bool = False,
|
||||
) -> str:
|
||||
"""只组合本次任务需要的规则,不改变 Schema 或后端校验范围"""
|
||||
types = action_types(requirement, screen_plan)
|
||||
sections = [ACTION_SYSTEM_PROMPT]
|
||||
if screen_plan is None:
|
||||
sections.append(SIMPLE_TASK_PROMPT)
|
||||
action_types = {
|
||||
"update_canvas" if change.target_scope == "canvas" else change.operation
|
||||
for change in requirement.changes
|
||||
}
|
||||
else:
|
||||
sections.append(PLAN_TASK_PROMPT)
|
||||
action_types = set()
|
||||
dispositions = {item.disposition for item in screen_plan.components}
|
||||
if screen_plan.canvas_changes:
|
||||
sections.append(
|
||||
"## 调整画布\n将 canvas_changes 中的最终属性值转换为 update_canvas,完整覆盖且不添加其他画布字段"
|
||||
)
|
||||
action_types.add("update_canvas")
|
||||
if any(item.disposition == "add" for item in screen_plan.components):
|
||||
action_types.add("add")
|
||||
if any(item.disposition == "replace" for item in screen_plan.components):
|
||||
if "replace" in dispositions:
|
||||
sections.append(REPLACE_PLAN_PROMPT)
|
||||
action_types.add("add")
|
||||
if any(item.disposition == "remove" for item in screen_plan.components):
|
||||
action_types.add("delete")
|
||||
modifications = [
|
||||
item for item in screen_plan.components if item.disposition == "modify"
|
||||
]
|
||||
if modifications:
|
||||
if "modify" in dispositions:
|
||||
sections.append(MODIFY_PLAN_PROMPT)
|
||||
action_types.update(("move", "resize"))
|
||||
if any(item.design for item in modifications):
|
||||
action_types.add("update")
|
||||
if types & FIELD_ACTIONS:
|
||||
sections.append(FIELD_QUERY_PROMPT)
|
||||
|
||||
# 排序保证提示词顺序稳定,缺少动作说明时直接报错,避免静默遗漏
|
||||
sections.append("# 本次可用动作\n" + "、".join(sorted(action_types)))
|
||||
sections.extend(ACTION_RULES[name] for name in sorted(action_types))
|
||||
sections.append("# 本次可用动作\n" + "、".join(sorted(types)))
|
||||
sections.extend(ACTION_RULES[name] for name in sorted(types))
|
||||
if repairing:
|
||||
sections.append(REPAIR_TASK_PROMPT)
|
||||
return "\n\n".join(section.strip() for section in sections)
|
||||
|
||||
@@ -21,13 +21,11 @@ properties 只包含需要修改的画布顶层字段,宽高为最终绝对值
|
||||
不需要改变的尺寸省略,不改变组件位置
|
||||
""",
|
||||
"update": """## update:更新已有组件属性
|
||||
依据快照选择 props / style 下的字段路径,不猜测不存在的嵌套结构
|
||||
path 中字符串是对象键,整数是数组下标;中间路径必须存在,数组下标不能越界
|
||||
只替换指定字段,不做深度合并;null 表示赋值,不表示删除
|
||||
提供 editable_fields 时,它是该组件属性面板的字段:用户说的名称(如名字、标题、颜色)优先对应 label 相符的字段,使用其 section 和 path
|
||||
props 第一层只能使用组件已有或物料默认配置中的字段,不新造组件级属性;更深层的配置可以按需新增
|
||||
字段路径的第一段写入 section(name / props / style),其余各段写入 path,数字段写成整数下标;name 的 path 为空列表
|
||||
例如字段 props.option.title.text 写成 section=props、path=["option", "title", "text"]
|
||||
layout 字段不用 update:位置用 move,尺寸用 resize
|
||||
只替换指定字段,不做深度合并;组件中还没有的中间对象由后端补齐
|
||||
不通过修改属性改变组件类型(如把 series 的 type 改成其他图表类型),组件类型由节点 type 和物料决定
|
||||
style 为 null 时可用单层路径添加属性,保留未要求修改的配置
|
||||
""",
|
||||
"add": """## add:按物料新增组件
|
||||
每个 add 规划对应一个新增动作,用 plan_id 关联规划,component_key 选择 component_materials 中的物料
|
||||
|
||||
@@ -15,6 +15,7 @@ REFLECTION_SYSTEM_PROMPT = f"""## 任务
|
||||
需要用户补充、外部资源或尚未支持的能力时,retryable=false,说明缺少什么
|
||||
{DATA_BINDING_GUIDE}
|
||||
因数据绑定校验失败时,去掉 dataId 并保留物料示例数据即可修正,retryable=true
|
||||
字段错误(field_error)时,查询字段定义,建议改用查到的字段路径或合法取值;物料没有能满足需求的字段时,retryable=false
|
||||
|
||||
## 边界
|
||||
保持需求和规划范围,不通过遗漏需求、猜测字段或替换用户意图来绕过错误
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""查询前端组件目录:目录只来自启动时从 MongoDB 载入的进程内存缓存,没有文件回退"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from app.schemas.component_resource import (
|
||||
@@ -21,14 +23,44 @@ def get_catalog_cache() -> ComponentCatalog | None:
|
||||
return _cached_catalog
|
||||
|
||||
|
||||
def load_catalog_file(path: str | Path) -> ComponentCatalog:
|
||||
"""读取导出的目录文件,只供导入脚本使用,运行时不读取文件"""
|
||||
# 如果传入的是相对路径,以项目根目录为基准,避免受启动时工作目录影响
|
||||
target = Path(path)
|
||||
# 手写的物料定义目录,只供导入脚本读取后写入 MongoDB,运行时不读取
|
||||
MATERIALS_DIR = Path(__file__).resolve().parent / "materials"
|
||||
FIELD_GROUPS_FILE = "field_groups.json"
|
||||
|
||||
|
||||
def load_material_definitions(directory: str | Path = MATERIALS_DIR) -> ComponentCatalog:
|
||||
"""读取物料定义目录:共享字段分组一个文件,每个物料一个文件;不合法直接报错
|
||||
|
||||
version 为全部文件内容的摘要,定义有任何改动都会得到新版本
|
||||
"""
|
||||
target = Path(directory)
|
||||
if not target.is_absolute():
|
||||
target = Path(__file__).resolve().parents[2] / target
|
||||
# utf-8-sig 同时兼容带 BOM 和不带 BOM 的 UTF-8 文件;损坏或不合法直接报错
|
||||
return ComponentCatalog.model_validate_json(target.read_text(encoding="utf-8-sig"))
|
||||
files = sorted(target.glob("*.json"))
|
||||
if not any(path.name == FIELD_GROUPS_FILE for path in files):
|
||||
raise FileNotFoundError(f"物料定义目录缺少 {FIELD_GROUPS_FILE}: {target}")
|
||||
digest = hashlib.sha256()
|
||||
components, field_groups = [], []
|
||||
for path in files:
|
||||
# utf-8-sig 同时兼容带 BOM 和不带 BOM 的 UTF-8 文件
|
||||
text = path.read_text(encoding="utf-8-sig")
|
||||
digest.update(path.name.encode() + b"\0" + text.encode())
|
||||
if path.name == FIELD_GROUPS_FILE:
|
||||
field_groups = json.loads(text)
|
||||
else:
|
||||
components.append(json.loads(text))
|
||||
# 文件名排序与展示顺序无关,物料按定义中的 order 排列,未写时排在最后
|
||||
components.sort(key=lambda item: item.get("order", len(files)))
|
||||
return ComponentCatalog.model_validate(
|
||||
{
|
||||
"version": f"sha256:{digest.hexdigest()}",
|
||||
"components": [
|
||||
{key: value for key, value in item.items() if key != "order"}
|
||||
for item in components
|
||||
],
|
||||
"field_groups": field_groups,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ComponentProvider:
|
||||
|
||||
@@ -1,50 +1,206 @@
|
||||
"""从物料目录读取组件的可编辑字段,供动作生成理解字段含义,并供校验约束属性结构"""
|
||||
"""按物料展开字段定义:解析共享分组引用、取字段默认值、派生前端属性面板 setters"""
|
||||
|
||||
from app.resources.component import ComponentProvider
|
||||
from app.schemas.component_resource import ComponentDefinition, ComponentQuery
|
||||
from app.schemas.screen import ScreenNode
|
||||
from pydantic import JsonValue
|
||||
|
||||
# 属性面板的 key 以区域开头,只有这两个区域可以被 update 修改
|
||||
EDITABLE_SECTIONS = ("props", "style")
|
||||
from app.schemas.component_resource import ComponentCatalog, ComponentDefinition
|
||||
from app.schemas.material_field import (
|
||||
MISSING,
|
||||
PANEL_CONTROLS,
|
||||
FieldGroup,
|
||||
MaterialField,
|
||||
lookup,
|
||||
)
|
||||
|
||||
|
||||
def _materials(node_type: str) -> list[ComponentDefinition]:
|
||||
# 多个物料预设可以共用同一前端 type,按 type 取全部预设
|
||||
result = ComponentProvider().query(ComponentQuery(type=node_type))
|
||||
return result.components if result.status == "resolved" else []
|
||||
def resolve_field_groups(
|
||||
catalog: ComponentCatalog, component: ComponentDefinition
|
||||
) -> list[FieldGroup]:
|
||||
"""按物料声明的顺序展开字段分组,共享分组取目录中的定义;返回副本,不污染目录"""
|
||||
shared = {group.key: group for group in catalog.field_groups}
|
||||
return [
|
||||
(shared[group] if isinstance(group, str) else group).model_copy(deep=True)
|
||||
for group in component.field_groups
|
||||
]
|
||||
|
||||
|
||||
def _split_key(key: str) -> tuple[str, list[str | int]] | None:
|
||||
# 前端点路径中的纯数字段是数组下标,转换为与 UpdateAction.path 一致的整数
|
||||
section, *path = key.split(".")
|
||||
if section not in EDITABLE_SECTIONS or not path:
|
||||
return None
|
||||
return section, [int(part) if part.isdigit() else part for part in path]
|
||||
def field_default(component: ComponentDefinition, field: MaterialField) -> JsonValue:
|
||||
"""物料默认配置中有该路径时取默认配置的值,否则取字段声明的 default"""
|
||||
value = lookup(component.template(), field.segments)
|
||||
return field.default if value is MISSING else value
|
||||
|
||||
|
||||
def editable_fields(node_type: str) -> list[dict]:
|
||||
"""返回组件属性面板中的字段:用户可见名称、区域、路径及可选值,按出现顺序去重"""
|
||||
fields: dict[str, dict] = {}
|
||||
for material in _materials(node_type):
|
||||
for setter in material.setters:
|
||||
parsed = _split_key(setter.key)
|
||||
if parsed is None or setter.key in fields:
|
||||
def panel_setters(groups: list[FieldGroup]) -> list[dict]:
|
||||
"""派生前端属性面板的 setters,格式与前端 SetterSchema 一致"""
|
||||
setters = []
|
||||
for group in groups:
|
||||
for field in group.fields:
|
||||
if not field.panel:
|
||||
continue
|
||||
section, path = parsed
|
||||
field = {"label": setter.label, "section": section, "path": path}
|
||||
if options := setter.props.get("options"):
|
||||
field["options"] = options
|
||||
fields[setter.key] = field
|
||||
return list(fields.values())
|
||||
props = {}
|
||||
if field.options:
|
||||
props["options"] = [
|
||||
{"label": option.label, "value": option.value} for option in field.options
|
||||
]
|
||||
setter = {
|
||||
"type": PANEL_CONTROLS[field.value_type],
|
||||
"label": field.label,
|
||||
"key": field.path,
|
||||
"props": props,
|
||||
}
|
||||
if field.span is not None:
|
||||
setter["span"] = field.span
|
||||
setters.append(setter)
|
||||
return setters
|
||||
|
||||
|
||||
def known_prop_keys(node: ScreenNode) -> set[str] | None:
|
||||
"""props 第一层是组件与渲染器的约定,只能是节点已有或物料默认配置中的字段;
|
||||
目录中找不到该类型时约定未知,返回 None 表示不做限制"""
|
||||
materials = _materials(node.type)
|
||||
if not materials:
|
||||
return None
|
||||
keys = set(node.props)
|
||||
for material in materials:
|
||||
keys.update(material.schema_.props)
|
||||
return keys
|
||||
def frontend_catalog(catalog: ComponentCatalog) -> dict:
|
||||
"""前端物料接口的数据:在保存的定义上附加由字段定义派生的 setters"""
|
||||
data = catalog.model_dump(mode="json", by_alias=True)
|
||||
for item, component in zip(data["components"], catalog.components, strict=True):
|
||||
item["setters"] = panel_setters(resolve_field_groups(catalog, component))
|
||||
return data
|
||||
|
||||
|
||||
# ---- 字段查询:MCP 工具、动作提示词和动作校验共用同一套逻辑 ----
|
||||
|
||||
|
||||
def find_material(catalog: ComponentCatalog, component_type: str) -> ComponentDefinition:
|
||||
"""按节点 type 找物料;找不到或对应多个物料时报错,不猜测"""
|
||||
matches = [item for item in catalog.components if item.type == component_type]
|
||||
if len(matches) != 1:
|
||||
known = "、".join(item.type for item in catalog.components)
|
||||
reason = "没有对应的物料" if not matches else "对应多个物料"
|
||||
raise ValueError(f"组件类型 {component_type} {reason},可用类型:{known}")
|
||||
return matches[0]
|
||||
|
||||
|
||||
def describe_field(
|
||||
component: ComponentDefinition, group: FieldGroup, field: MaterialField
|
||||
) -> dict:
|
||||
"""给模型看的字段说明:省略空值和属性面板专用的信息"""
|
||||
data = field.model_dump(
|
||||
mode="json",
|
||||
exclude={"default", "panel", "span", "editable"},
|
||||
exclude_none=True,
|
||||
exclude_defaults=True,
|
||||
)
|
||||
data["default"] = field_default(component, field)
|
||||
if not field.editable:
|
||||
data["editable"] = False
|
||||
data["group"] = group.key
|
||||
return data
|
||||
|
||||
|
||||
def list_field_groups(catalog: ComponentCatalog, component_type: str) -> dict:
|
||||
"""物料的字段分组目录:每组的说明和字段名称,模型据此决定查看哪几组"""
|
||||
component = find_material(catalog, component_type)
|
||||
return {
|
||||
"component_type": component.type,
|
||||
"name": component.name,
|
||||
"catalog_version": catalog.version,
|
||||
"groups": [
|
||||
{
|
||||
"key": group.key,
|
||||
"label": group.label,
|
||||
"description": group.description,
|
||||
"fields": [field.label for field in group.fields],
|
||||
}
|
||||
for group in resolve_field_groups(catalog, component)
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def get_fields(
|
||||
catalog: ComponentCatalog, component_type: str, group_keys: list[str]
|
||||
) -> dict:
|
||||
"""指定分组的完整字段定义"""
|
||||
component = find_material(catalog, component_type)
|
||||
groups = {group.key: group for group in resolve_field_groups(catalog, component)}
|
||||
if unknown := [key for key in group_keys if key not in groups]:
|
||||
raise ValueError(
|
||||
f"{component.type} 没有字段分组 {unknown},可用分组:{list(groups)}"
|
||||
)
|
||||
return {
|
||||
"component_type": component.type,
|
||||
"catalog_version": catalog.version,
|
||||
"fields": [
|
||||
describe_field(component, groups[key], field)
|
||||
for key in dict.fromkeys(group_keys)
|
||||
for field in groups[key].fields
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def _match_score(field: MaterialField, query: str) -> int:
|
||||
"""名称、别名完全一致最相关,其次是互相包含、路径末段一致,最后是说明中出现"""
|
||||
names = [name.casefold() for name in (field.label, *field.aliases)]
|
||||
if query in names:
|
||||
return 4
|
||||
if any(query in name or name in query for name in names):
|
||||
return 3
|
||||
if query == field.path.rsplit(".", 1)[-1].casefold():
|
||||
return 2
|
||||
if query in field.description.casefold() or query in field.path.casefold():
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def search_fields(
|
||||
catalog: ComponentCatalog, component_type: str, query: str, limit: int = 8
|
||||
) -> dict:
|
||||
"""按名称、别名、路径和说明搜索字段,按相关度返回"""
|
||||
component = find_material(catalog, component_type)
|
||||
keyword = query.strip().casefold()
|
||||
if not keyword:
|
||||
raise ValueError("搜索内容不能为空")
|
||||
scored = [
|
||||
(score, index, group, field)
|
||||
for index, (group, field) in enumerate(
|
||||
(group, field)
|
||||
for group in resolve_field_groups(catalog, component)
|
||||
for field in group.fields
|
||||
)
|
||||
if (score := _match_score(field, keyword))
|
||||
]
|
||||
scored.sort(key=lambda item: (-item[0], item[1]))
|
||||
return {
|
||||
"component_type": component.type,
|
||||
"catalog_version": catalog.version,
|
||||
"query": query,
|
||||
"fields": [
|
||||
describe_field(component, group, field)
|
||||
for _, _, group, field in scored[:limit]
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def check_update_field(catalog: ComponentCatalog | None, node_type: str, action) -> None:
|
||||
"""update 只能修改字段定义中的可编辑字段,值须符合字段类型和取值约束
|
||||
|
||||
不合法时抛 ValueError,路径不存在时附上可能对应的字段供修正参考
|
||||
"""
|
||||
if catalog is None:
|
||||
raise ValueError("物料目录未载入,无法确认组件有哪些字段")
|
||||
component = find_material(catalog, node_type)
|
||||
fields = {
|
||||
field.path: field
|
||||
for group in resolve_field_groups(catalog, component)
|
||||
for field in group.fields
|
||||
}
|
||||
path = action.field_path
|
||||
field = fields.get(path)
|
||||
if field is None:
|
||||
message = f"{node_type} 没有字段 {path},只能修改字段定义中的路径"
|
||||
keyword = next(
|
||||
(str(item) for item in reversed(action.path) if isinstance(item, str)),
|
||||
action.section,
|
||||
)
|
||||
if similar := search_fields(catalog, node_type, keyword, limit=3)["fields"]:
|
||||
message += ";可能是:" + "、".join(
|
||||
f"{item['label']}({item['path']})" for item in similar
|
||||
)
|
||||
raise ValueError(message)
|
||||
if not field.editable:
|
||||
raise ValueError(f"字段 {path}({field.label})不允许修改")
|
||||
if error := field.value_error(action.value):
|
||||
raise ValueError(f"字段 {path}({field.label}){error}")
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"order": 2,
|
||||
"key": "area-chart",
|
||||
"type": "area-chart",
|
||||
"name": "面积图",
|
||||
"description": "折线下方填充面积,展示数值随时间的变化趋势并突出总量",
|
||||
"tags": [
|
||||
"charts",
|
||||
"面积图",
|
||||
"area-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:graph-new-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
"chart-axis",
|
||||
"chart-line-series",
|
||||
{
|
||||
"key": "area-fill",
|
||||
"label": "面积",
|
||||
"description": "折线下方填充区域",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.areaStyle.color",
|
||||
"label": "面积色",
|
||||
"description": "折线下方填充区域的颜色,通常带透明度,例如 rgba(64, 158, 255, 0.25)",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"填充色",
|
||||
"面积颜色",
|
||||
"阴影颜色"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-xy"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "area-chart",
|
||||
"name": "面积图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "成交额趋势",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "axis"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"date": "周一",
|
||||
"revenue": 120
|
||||
},
|
||||
{
|
||||
"date": "周二",
|
||||
"revenue": 200
|
||||
},
|
||||
{
|
||||
"date": "周三",
|
||||
"revenue": 150
|
||||
},
|
||||
{
|
||||
"date": "周四",
|
||||
"revenue": 260
|
||||
},
|
||||
{
|
||||
"date": "周五",
|
||||
"revenue": 330
|
||||
},
|
||||
{
|
||||
"date": "周六",
|
||||
"revenue": 420
|
||||
},
|
||||
{
|
||||
"date": "周日",
|
||||
"revenue": 510
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 24,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"boundaryGap": false,
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "成交额",
|
||||
"type": "line",
|
||||
"smooth": true,
|
||||
"symbolSize": 8,
|
||||
"encode": {
|
||||
"x": "date",
|
||||
"y": "revenue"
|
||||
},
|
||||
"lineStyle": {
|
||||
"width": 3,
|
||||
"color": "#409eff"
|
||||
},
|
||||
"itemStyle": {
|
||||
"color": "#409eff"
|
||||
},
|
||||
"areaStyle": {
|
||||
"color": "rgba(64, 158, 255, 0.25)"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
{
|
||||
"order": 0,
|
||||
"key": "bar-chart",
|
||||
"type": "bar-chart",
|
||||
"name": "柱状图",
|
||||
"description": "按类目对比数值大小,适合月度、地区、产品等分类数据的对比",
|
||||
"tags": [
|
||||
"charts",
|
||||
"柱状图",
|
||||
"bar-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:chart-2-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
"chart-axis",
|
||||
{
|
||||
"key": "bar-series",
|
||||
"label": "柱形",
|
||||
"description": "柱子的颜色、宽度、圆角、系列名称和数值标签",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.color",
|
||||
"label": "柱颜色",
|
||||
"description": "柱子的填充颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"柱子颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列名称",
|
||||
"description": "这组柱子的名称,显示在图例和鼠标悬停提示中;不是图表标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称",
|
||||
"系列名",
|
||||
"数据名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.barWidth",
|
||||
"label": "柱宽",
|
||||
"description": "柱子宽度,百分比表示占每个类目宽度的比例,例如 45%",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"柱子宽度",
|
||||
"柱子粗细"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.borderRadius",
|
||||
"label": "柱圆角",
|
||||
"description": "柱子四个角的圆角半径,顺序为左上、右上、右下、左下",
|
||||
"value_type": "array",
|
||||
"item_type": "number",
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"圆角"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.show",
|
||||
"label": "数值标签",
|
||||
"description": "是否在每根柱子上显示数值",
|
||||
"value_type": "boolean",
|
||||
"default": false,
|
||||
"aliases": [
|
||||
"显示数值",
|
||||
"数据标签",
|
||||
"标签"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.position",
|
||||
"label": "标签位置",
|
||||
"description": "数值标签相对柱子的位置,开启数值标签后生效",
|
||||
"value_type": "enum",
|
||||
"default": "inside",
|
||||
"options": [
|
||||
{
|
||||
"value": "top",
|
||||
"label": "柱顶上方"
|
||||
},
|
||||
{
|
||||
"value": "inside",
|
||||
"label": "柱内居中"
|
||||
},
|
||||
{
|
||||
"value": "insideTop",
|
||||
"label": "柱内顶端"
|
||||
},
|
||||
{
|
||||
"value": "insideBottom",
|
||||
"label": "柱内底端"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"数值位置"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-xy"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "bar-chart",
|
||||
"name": "柱状图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "月度销售额",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"month": "一月",
|
||||
"sales": 120
|
||||
},
|
||||
{
|
||||
"month": "二月",
|
||||
"sales": 200
|
||||
},
|
||||
{
|
||||
"month": "三月",
|
||||
"sales": 150
|
||||
},
|
||||
{
|
||||
"month": "四月",
|
||||
"sales": 80
|
||||
},
|
||||
{
|
||||
"month": "五月",
|
||||
"sales": 170
|
||||
},
|
||||
{
|
||||
"month": "六月",
|
||||
"sales": 240
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 24,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "销售额",
|
||||
"type": "bar",
|
||||
"barWidth": "45%",
|
||||
"encode": {
|
||||
"x": "month",
|
||||
"y": "sales"
|
||||
},
|
||||
"itemStyle": {
|
||||
"color": "#409eff",
|
||||
"borderRadius": [
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
{
|
||||
"order": 11,
|
||||
"key": "bar-line-chart",
|
||||
"type": "bar-line-chart",
|
||||
"name": "柱线混合图",
|
||||
"description": "柱子展示数量、折线展示比率,左右两个纵轴分别对应两种数值",
|
||||
"tags": [
|
||||
"charts",
|
||||
"柱线混合图",
|
||||
"bar-line-chart",
|
||||
"双轴",
|
||||
"混合",
|
||||
"增长率"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:chart-2-linear",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作",
|
||||
"柱系列使用左轴,折线系列 yAxisIndex=1 使用右轴",
|
||||
"两个系列 encode.x 需保持一致"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
"chart-palette",
|
||||
{
|
||||
"key": "bar-line-series",
|
||||
"label": "系列",
|
||||
"description": "柱系列和折线系列的颜色、名称和样式",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.color.0",
|
||||
"label": "柱颜色",
|
||||
"description": "柱子的颜色",
|
||||
"value_type": "color",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.color.1",
|
||||
"label": "线颜色",
|
||||
"description": "折线的颜色",
|
||||
"value_type": "color",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"折线颜色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.smooth",
|
||||
"label": "平滑曲线",
|
||||
"description": "开启后折线为平滑曲线,关闭后为折角直线",
|
||||
"value_type": "boolean",
|
||||
"aliases": [
|
||||
"曲线",
|
||||
"平滑"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "柱系列名称",
|
||||
"description": "柱子系列的名称,显示在图例和鼠标悬停提示中",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"柱子名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.name",
|
||||
"label": "线系列名称",
|
||||
"description": "折线系列的名称,显示在图例和鼠标悬停提示中",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"折线名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.barWidth",
|
||||
"label": "柱宽",
|
||||
"description": "柱子宽度,百分比表示占每个类目宽度的比例,例如 40%",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"柱子宽度"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "bar-line-axis",
|
||||
"label": "坐标轴",
|
||||
"description": "左纵轴对应柱子数值,右纵轴对应折线数值",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.yAxis.0.name",
|
||||
"label": "左轴名称",
|
||||
"description": "左侧纵轴(柱子数值)顶部显示的名称",
|
||||
"value_type": "string",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"左轴标题"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.1.name",
|
||||
"label": "右轴名称",
|
||||
"description": "右侧纵轴(折线数值)顶部显示的名称",
|
||||
"value_type": "string",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"右轴标题"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.1.axisLabel.formatter",
|
||||
"label": "右轴格式",
|
||||
"description": "右侧纵轴刻度的显示格式,{value} 代表刻度值,例如 {value}%",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"右轴单位"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.xAxis.axisLabel.color",
|
||||
"label": "X轴文字色",
|
||||
"description": "横轴类目文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"横轴文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "bar-line-data",
|
||||
"label": "数据映射",
|
||||
"description": "柱线混合图从数据集(dataset.source)中取哪些列",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.encode.x",
|
||||
"label": "X字段",
|
||||
"description": "横轴类目使用数据集中的哪一列;两个系列必须相同,修改时同时修改折线的X字段",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"横轴字段",
|
||||
"类目字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.encode.x",
|
||||
"label": "折线X字段",
|
||||
"description": "须与X字段保持一致,修改X字段时同步修改",
|
||||
"value_type": "string",
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.encode.y",
|
||||
"label": "柱数值字段",
|
||||
"description": "柱子高度使用数据集中的哪一列",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"柱子字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.encode.y",
|
||||
"label": "线数值字段",
|
||||
"description": "折线数值使用数据集中的哪一列",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"折线字段"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "bar-line-chart",
|
||||
"name": "柱线混合图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#e6a23c"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "销售额与增长率",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "axis"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"month": "一月",
|
||||
"sales": 120,
|
||||
"growth": 12.5
|
||||
},
|
||||
{
|
||||
"month": "二月",
|
||||
"sales": 200,
|
||||
"growth": 18.2
|
||||
},
|
||||
{
|
||||
"month": "三月",
|
||||
"sales": 150,
|
||||
"growth": -4.3
|
||||
},
|
||||
{
|
||||
"month": "四月",
|
||||
"sales": 80,
|
||||
"growth": -20.1
|
||||
},
|
||||
{
|
||||
"month": "五月",
|
||||
"sales": 170,
|
||||
"growth": 9.6
|
||||
},
|
||||
{
|
||||
"month": "六月",
|
||||
"sales": 240,
|
||||
"growth": 21.4
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 48,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"yAxis": [
|
||||
{
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
},
|
||||
"name": "销售额",
|
||||
"nameTextStyle": {
|
||||
"color": "#a3a6ad"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc",
|
||||
"formatter": "{value}%"
|
||||
},
|
||||
"splitLine": {
|
||||
"show": false
|
||||
},
|
||||
"name": "增长率",
|
||||
"nameTextStyle": {
|
||||
"color": "#a3a6ad"
|
||||
}
|
||||
}
|
||||
],
|
||||
"series": [
|
||||
{
|
||||
"name": "销售额",
|
||||
"type": "bar",
|
||||
"barWidth": "40%",
|
||||
"encode": {
|
||||
"x": "month",
|
||||
"y": "sales"
|
||||
},
|
||||
"itemStyle": {
|
||||
"borderRadius": [
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "增长率",
|
||||
"type": "line",
|
||||
"yAxisIndex": 1,
|
||||
"smooth": true,
|
||||
"symbolSize": 6,
|
||||
"encode": {
|
||||
"x": "month",
|
||||
"y": "growth"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,566 @@
|
||||
[
|
||||
{
|
||||
"key": "node-base",
|
||||
"label": "基础",
|
||||
"description": "所有组件共有的名称、位置和尺寸",
|
||||
"fields": [
|
||||
{
|
||||
"path": "name",
|
||||
"label": "组件名称",
|
||||
"description": "组件在编辑器图层列表和属性面板标题栏中的名称,用于编辑时识别组件,不显示在大屏画面上;图表画面上显示的名字是标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"组件名",
|
||||
"图层名",
|
||||
"图层名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "layout.x",
|
||||
"label": "X",
|
||||
"description": "组件左上角距画布左边缘的水平距离",
|
||||
"value_type": "number",
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"横坐标",
|
||||
"水平位置",
|
||||
"左边距离"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "layout.y",
|
||||
"label": "Y",
|
||||
"description": "组件左上角距画布上边缘的垂直距离",
|
||||
"value_type": "number",
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"纵坐标",
|
||||
"垂直位置",
|
||||
"上边距离"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "layout.width",
|
||||
"label": "宽度",
|
||||
"description": "组件的宽度",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"宽",
|
||||
"横向尺寸"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "layout.height",
|
||||
"label": "高度",
|
||||
"description": "组件的高度",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"高",
|
||||
"纵向尺寸"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-title",
|
||||
"label": "标题",
|
||||
"description": "图表上方显示的标题文字及其颜色、字号、对齐",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.title.text",
|
||||
"label": "标题",
|
||||
"description": "显示在图表上方的标题文字,是用户在大屏上看到的图表名字",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"名字",
|
||||
"名称",
|
||||
"图表名称",
|
||||
"图表标题",
|
||||
"标题文字"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.title.textStyle.color",
|
||||
"label": "标题色",
|
||||
"description": "标题文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"标题颜色",
|
||||
"标题文字颜色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.title.left",
|
||||
"label": "对齐",
|
||||
"description": "标题在组件内的水平位置",
|
||||
"value_type": "enum",
|
||||
"options": [
|
||||
{
|
||||
"value": "left",
|
||||
"label": "左对齐"
|
||||
},
|
||||
{
|
||||
"value": "center",
|
||||
"label": "居中"
|
||||
},
|
||||
{
|
||||
"value": "right",
|
||||
"label": "右对齐"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"标题对齐",
|
||||
"标题位置"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.title.textStyle.fontSize",
|
||||
"label": "标题字号",
|
||||
"description": "标题文字的大小",
|
||||
"value_type": "number",
|
||||
"minimum": 8,
|
||||
"maximum": 72,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"标题大小",
|
||||
"标题字体大小"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.title.show",
|
||||
"label": "显示标题",
|
||||
"description": "是否显示标题,关闭后整个标题隐藏",
|
||||
"value_type": "boolean",
|
||||
"default": true,
|
||||
"aliases": [
|
||||
"隐藏标题",
|
||||
"去掉标题"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-legend",
|
||||
"label": "图例",
|
||||
"description": "标题下方列出各系列名称和颜色的图例",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.legend.show",
|
||||
"label": "图例显示",
|
||||
"description": "是否显示图例;图例列出各系列的名称和颜色",
|
||||
"value_type": "boolean",
|
||||
"aliases": [
|
||||
"图例",
|
||||
"显示图例",
|
||||
"隐藏图例"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.legend.textStyle.color",
|
||||
"label": "图例文字色",
|
||||
"description": "图例中系列名称文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"图例颜色",
|
||||
"图例文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-grid",
|
||||
"label": "边距",
|
||||
"description": "绘图区(坐标轴所在区域)与组件四边的距离",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.grid.top",
|
||||
"label": "上边距",
|
||||
"description": "绘图区距组件上边缘的距离;默认为标题和图例留出位置,调小可能与它们重叠",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"unit": "px",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.grid.right",
|
||||
"label": "右边距",
|
||||
"description": "绘图区距组件右边缘的距离",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"unit": "px",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.grid.bottom",
|
||||
"label": "下边距",
|
||||
"description": "绘图区距组件下边缘的距离,横轴文字显示在这里",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"unit": "px",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.grid.left",
|
||||
"label": "左边距",
|
||||
"description": "绘图区距组件左边缘的距离,纵轴文字显示在这里",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"unit": "px",
|
||||
"span": 12
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-axis",
|
||||
"label": "坐标轴",
|
||||
"description": "直角坐标图表的横轴、纵轴和网格线颜色",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.xAxis.axisLabel.color",
|
||||
"label": "X轴文字色",
|
||||
"description": "横轴刻度文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"横轴文字颜色",
|
||||
"X轴标签颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.xAxis.axisLine.lineStyle.color",
|
||||
"label": "X轴线颜色",
|
||||
"description": "横轴轴线的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"横轴颜色",
|
||||
"坐标轴颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.axisLabel.color",
|
||||
"label": "Y轴文字色",
|
||||
"description": "纵轴刻度文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"纵轴文字颜色",
|
||||
"Y轴标签颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.splitLine.lineStyle.color",
|
||||
"label": "网格线颜色",
|
||||
"description": "绘图区内横向分隔线的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"分隔线颜色",
|
||||
"背景线颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-palette",
|
||||
"label": "配色",
|
||||
"description": "各系列或数据项按顺序依次取用的颜色列表",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.color",
|
||||
"label": "调色盘",
|
||||
"description": "颜色列表,第 1 个系列或数据项用第 1 个颜色,依次类推;整体换一套配色时修改它,只改某一项时用对应的单项颜色字段",
|
||||
"value_type": "array",
|
||||
"item_type": "color",
|
||||
"aliases": [
|
||||
"配色",
|
||||
"配色方案",
|
||||
"整体颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-encode-xy",
|
||||
"label": "数据映射",
|
||||
"description": "图表从数据集(dataset.source)中取哪一列作为横轴和纵轴",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.encode.x",
|
||||
"label": "X字段",
|
||||
"description": "横轴使用数据集中的哪一列,必须是 dataset.source 中存在的字段名",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"横轴字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.encode.y",
|
||||
"label": "Y字段",
|
||||
"description": "纵轴使用数据集中的哪一列,必须是 dataset.source 中存在的字段名",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"纵轴字段"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-encode-item",
|
||||
"label": "数据映射",
|
||||
"description": "图表从数据集(dataset.source)中取哪一列作为数据项名称和数值",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.encode.itemName",
|
||||
"label": "名称字段",
|
||||
"description": "每个数据项(扇区、层级等)的名称使用数据集中的哪一列,必须是 dataset.source 中存在的字段名",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"类目字段",
|
||||
"分类字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.encode.value",
|
||||
"label": "数值字段",
|
||||
"description": "每个数据项的数值使用数据集中的哪一列,必须是 dataset.source 中存在的字段名",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"值字段"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-line-series",
|
||||
"label": "线条",
|
||||
"description": "折线的颜色、粗细、平滑度、数据点和数值标签",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.lineStyle.color",
|
||||
"label": "线颜色",
|
||||
"description": "折线的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"折线颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列名称",
|
||||
"description": "这条折线的名称,显示在图例和鼠标悬停提示中;不是图表标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称",
|
||||
"系列名",
|
||||
"数据名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.smooth",
|
||||
"label": "平滑曲线",
|
||||
"description": "开启后折线为平滑曲线,关闭后为折角直线",
|
||||
"value_type": "boolean",
|
||||
"aliases": [
|
||||
"曲线",
|
||||
"平滑"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.lineStyle.width",
|
||||
"label": "线宽",
|
||||
"description": "折线的粗细",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 12,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"线条粗细",
|
||||
"线粗细"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.color",
|
||||
"label": "数据点颜色",
|
||||
"description": "折线上每个数据点(拐点)的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"拐点颜色",
|
||||
"圆点颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbolSize",
|
||||
"label": "数据点大小",
|
||||
"description": "折线上数据点(拐点)的直径",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 30,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"拐点大小",
|
||||
"圆点大小"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.show",
|
||||
"label": "数值标签",
|
||||
"description": "是否在每个数据点上方显示数值",
|
||||
"value_type": "boolean",
|
||||
"default": false,
|
||||
"aliases": [
|
||||
"显示数值",
|
||||
"数据标签",
|
||||
"标签"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-item-series",
|
||||
"label": "数据项",
|
||||
"description": "饼图、漏斗图等按数据项着色的图表的主色、系列名称和数据项标签",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.color.0",
|
||||
"label": "主色",
|
||||
"description": "调色盘的第一个颜色,用于第一个数据项(扇区或层级);其余数据项依次取调色盘后面的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"第一个颜色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列名称",
|
||||
"description": "这组数据的名称,显示在鼠标悬停提示中;不是图表标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"系列名",
|
||||
"数据名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.show",
|
||||
"label": "数据项标签",
|
||||
"description": "是否在每个数据项旁显示名称标签",
|
||||
"value_type": "boolean",
|
||||
"default": true,
|
||||
"aliases": [
|
||||
"标签",
|
||||
"显示标签",
|
||||
"扇区标签"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.color",
|
||||
"label": "标签文字色",
|
||||
"description": "数据项名称标签的文字颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"标签颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "chart-gauge-value",
|
||||
"label": "数值",
|
||||
"description": "仪表类图表的量程、进度颜色和中心数值显示",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.progress.itemStyle.color",
|
||||
"label": "进度色",
|
||||
"description": "进度弧的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"主色",
|
||||
"进度条颜色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.min",
|
||||
"label": "最小值",
|
||||
"description": "量程起点,进度从这个值开始计算",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"量程最小值",
|
||||
"起始值"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.max",
|
||||
"label": "最大值",
|
||||
"description": "量程终点,数值达到它时进度为满",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"量程最大值",
|
||||
"目标值",
|
||||
"满值"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.detail.formatter",
|
||||
"label": "数值格式",
|
||||
"description": "中心数值的显示格式,{value} 代表当前值,例如 {value}%",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"数值单位",
|
||||
"显示格式"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.detail.color",
|
||||
"label": "数值颜色",
|
||||
"description": "中心数值文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"数字颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.detail.fontSize",
|
||||
"label": "数值字号",
|
||||
"description": "中心数值文字的大小",
|
||||
"value_type": "number",
|
||||
"minimum": 8,
|
||||
"maximum": 96,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"数字大小"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"order": 8,
|
||||
"key": "funnel-chart",
|
||||
"type": "funnel-chart",
|
||||
"name": "漏斗图",
|
||||
"description": "展示流程各阶段的数量和逐级转化情况",
|
||||
"tags": [
|
||||
"charts",
|
||||
"漏斗图",
|
||||
"funnel-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:filter-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-palette",
|
||||
"chart-item-series",
|
||||
{
|
||||
"key": "funnel-shape",
|
||||
"label": "漏斗",
|
||||
"description": "漏斗的排序和层间距",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.sort",
|
||||
"label": "排序",
|
||||
"description": "各层按数值排列的方向",
|
||||
"value_type": "enum",
|
||||
"options": [
|
||||
{
|
||||
"value": "descending",
|
||||
"label": "从大到小(正漏斗)"
|
||||
},
|
||||
{
|
||||
"value": "ascending",
|
||||
"label": "从小到大(倒漏斗)"
|
||||
},
|
||||
{
|
||||
"value": "none",
|
||||
"label": "按数据顺序"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"方向",
|
||||
"顺序"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.gap",
|
||||
"label": "层间距",
|
||||
"description": "相邻两层之间的间隔",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 40,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"间隔",
|
||||
"间距"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-item"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "funnel-chart",
|
||||
"name": "漏斗图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 280
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#67c23a",
|
||||
"#e6a23c",
|
||||
"#f56c6c",
|
||||
"#909399"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "转化漏斗",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"stage": "访问",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"stage": "咨询",
|
||||
"value": 72
|
||||
},
|
||||
{
|
||||
"stage": "下单",
|
||||
"value": 48
|
||||
},
|
||||
{
|
||||
"stage": "成交",
|
||||
"value": 26
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "转化",
|
||||
"type": "funnel",
|
||||
"top": 72,
|
||||
"bottom": 16,
|
||||
"left": "12%",
|
||||
"width": "76%",
|
||||
"minSize": "16%",
|
||||
"maxSize": "100%",
|
||||
"sort": "descending",
|
||||
"gap": 4,
|
||||
"label": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"itemStyle": {
|
||||
"borderColor": "transparent"
|
||||
},
|
||||
"encode": {
|
||||
"itemName": "stage",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"order": 9,
|
||||
"key": "gauge-chart",
|
||||
"type": "gauge-chart",
|
||||
"name": "仪表盘",
|
||||
"description": "用指针和进度弧展示单个指标的当前值或完成率",
|
||||
"tags": [
|
||||
"charts",
|
||||
"仪表盘",
|
||||
"gauge-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:speedometer-middle-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-gauge-value",
|
||||
{
|
||||
"key": "gauge-dial",
|
||||
"label": "表盘",
|
||||
"description": "仪表盘的指针、刻度和表盘宽度",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.pointer.show",
|
||||
"label": "显示指针",
|
||||
"description": "是否显示指针",
|
||||
"value_type": "boolean",
|
||||
"default": true,
|
||||
"aliases": [
|
||||
"指针"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.pointer.itemStyle.color",
|
||||
"label": "指针颜色",
|
||||
"description": "指针的颜色",
|
||||
"value_type": "color",
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.axisLabel.color",
|
||||
"label": "刻度文字色",
|
||||
"description": "表盘刻度数字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"刻度颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.axisLine.lineStyle.width",
|
||||
"label": "表盘宽度",
|
||||
"description": "表盘底弧的粗细",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 60,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"底弧宽度"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.progress.width",
|
||||
"label": "进度宽度",
|
||||
"description": "进度弧的粗细",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 60,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"进度条宽度"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-item"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "gauge-chart",
|
||||
"name": "仪表盘",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 320,
|
||||
"height": 280
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"title": {
|
||||
"text": "销售目标完成率",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"name": "销售目标完成率",
|
||||
"value": 72
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"type": "gauge",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"startAngle": 210,
|
||||
"endAngle": -30,
|
||||
"center": [
|
||||
"50%",
|
||||
"58%"
|
||||
],
|
||||
"radius": "80%",
|
||||
"progress": {
|
||||
"show": true,
|
||||
"width": 12,
|
||||
"itemStyle": {
|
||||
"color": "#409eff"
|
||||
}
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"width": 12,
|
||||
"color": [
|
||||
[
|
||||
1,
|
||||
"rgba(255, 255, 255, 0.1)"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false
|
||||
},
|
||||
"splitLine": {
|
||||
"length": 8,
|
||||
"lineStyle": {
|
||||
"width": 1,
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc",
|
||||
"distance": 16
|
||||
},
|
||||
"pointer": {
|
||||
"itemStyle": {
|
||||
"color": "#e5eaf3"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"offsetCenter": [
|
||||
0,
|
||||
"72%"
|
||||
],
|
||||
"color": "#cfd3dc",
|
||||
"fontSize": 13
|
||||
},
|
||||
"detail": {
|
||||
"valueAnimation": true,
|
||||
"offsetCenter": [
|
||||
0,
|
||||
"46%"
|
||||
],
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 28,
|
||||
"formatter": "{value}%"
|
||||
},
|
||||
"encode": {
|
||||
"itemName": "name",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
{
|
||||
"order": 1,
|
||||
"key": "hbar-chart",
|
||||
"type": "hbar-chart",
|
||||
"name": "条形图",
|
||||
"description": "横向条形对比各类目数值,类目名称较长或类目较多时比柱状图更易读",
|
||||
"tags": [
|
||||
"charts",
|
||||
"条形图",
|
||||
"hbar-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:align-left-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
{
|
||||
"key": "hbar-axis",
|
||||
"label": "坐标轴",
|
||||
"description": "条形图的横轴为数值轴、纵轴为类目轴",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.xAxis.axisLabel.color",
|
||||
"label": "X轴文字色",
|
||||
"description": "横轴(数值)刻度文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"横轴文字颜色",
|
||||
"数值轴文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.xAxis.splitLine.lineStyle.color",
|
||||
"label": "网格线颜色",
|
||||
"description": "绘图区内纵向分隔线的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"分隔线颜色",
|
||||
"背景线颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.axisLabel.color",
|
||||
"label": "Y轴文字色",
|
||||
"description": "纵轴类目名称文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"纵轴文字颜色",
|
||||
"类目文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.axisLine.lineStyle.color",
|
||||
"label": "Y轴线颜色",
|
||||
"description": "纵轴轴线的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"纵轴颜色",
|
||||
"坐标轴颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "hbar-series",
|
||||
"label": "条形",
|
||||
"description": "条形的颜色、粗细、圆角、系列名称和数值标签",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.color",
|
||||
"label": "条颜色",
|
||||
"description": "条形的填充颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"条形颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列名称",
|
||||
"description": "这组条形的名称,显示在图例和鼠标悬停提示中;不是图表标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称",
|
||||
"系列名",
|
||||
"数据名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.barWidth",
|
||||
"label": "条宽",
|
||||
"description": "条形粗细,百分比表示占每个类目高度的比例,例如 45%",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"条形宽度",
|
||||
"条形粗细"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.borderRadius",
|
||||
"label": "条圆角",
|
||||
"description": "条形四个角的圆角半径,顺序为左上、右上、右下、左下,默认只有右端圆角",
|
||||
"value_type": "array",
|
||||
"item_type": "number",
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"圆角"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.show",
|
||||
"label": "数值标签",
|
||||
"description": "是否在每个条形上显示数值",
|
||||
"value_type": "boolean",
|
||||
"default": false,
|
||||
"aliases": [
|
||||
"显示数值",
|
||||
"数据标签",
|
||||
"标签"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.position",
|
||||
"label": "标签位置",
|
||||
"description": "数值标签相对条形的位置,开启数值标签后生效",
|
||||
"value_type": "enum",
|
||||
"default": "inside",
|
||||
"options": [
|
||||
{
|
||||
"value": "right",
|
||||
"label": "条形右侧"
|
||||
},
|
||||
{
|
||||
"value": "inside",
|
||||
"label": "条内居中"
|
||||
},
|
||||
{
|
||||
"value": "insideRight",
|
||||
"label": "条内右端"
|
||||
},
|
||||
{
|
||||
"value": "insideLeft",
|
||||
"label": "条内左端"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"数值位置"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-xy"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "hbar-chart",
|
||||
"name": "条形图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "地区销售额",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"region": "华东",
|
||||
"sales": 320
|
||||
},
|
||||
{
|
||||
"region": "华南",
|
||||
"sales": 240
|
||||
},
|
||||
{
|
||||
"region": "华北",
|
||||
"sales": 210
|
||||
},
|
||||
{
|
||||
"region": "西南",
|
||||
"sales": 180
|
||||
},
|
||||
{
|
||||
"region": "西北",
|
||||
"sales": 130
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 24,
|
||||
"bottom": 24,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "销售额",
|
||||
"type": "bar",
|
||||
"barWidth": "45%",
|
||||
"encode": {
|
||||
"x": "sales",
|
||||
"y": "region"
|
||||
},
|
||||
"itemStyle": {
|
||||
"color": "#409eff",
|
||||
"borderRadius": [
|
||||
0,
|
||||
4,
|
||||
4,
|
||||
0
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
{
|
||||
"order": 14,
|
||||
"key": "heatmap-chart",
|
||||
"type": "heatmap-chart",
|
||||
"name": "热力图",
|
||||
"description": "用格子颜色深浅展示两个类目维度交叉处的数值大小",
|
||||
"tags": [
|
||||
"charts",
|
||||
"热力图",
|
||||
"heatmap-chart",
|
||||
"热力",
|
||||
"分布",
|
||||
"时段"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:widget-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作",
|
||||
"数据源每行一个格子,三列分别对应 X、Y、数值,数值列需放在最后一列(visualMap 默认映射最后一个维度)",
|
||||
"visualMap.min / max 需按实际数据范围调整",
|
||||
"label.formatter 用 {@字段名} 引用数值列,修改数值字段时需同步修改"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-grid",
|
||||
{
|
||||
"key": "heatmap-axis",
|
||||
"label": "坐标轴",
|
||||
"description": "热力图的横轴和纵轴都是类目轴",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.xAxis.axisLabel.color",
|
||||
"label": "X轴文字色",
|
||||
"description": "横轴类目文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"横轴文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.yAxis.axisLabel.color",
|
||||
"label": "Y轴文字色",
|
||||
"description": "纵轴类目文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"纵轴文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "heatmap-visual",
|
||||
"label": "色阶",
|
||||
"description": "数值到格子颜色的映射,数值越大颜色越接近高值颜色",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.visualMap.min",
|
||||
"label": "最小值",
|
||||
"description": "色阶的最小值,需按实际数据范围调整",
|
||||
"value_type": "number",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.visualMap.max",
|
||||
"label": "最大值",
|
||||
"description": "色阶的最大值,需按实际数据范围调整",
|
||||
"value_type": "number",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.visualMap.inRange.color.0",
|
||||
"label": "低值颜色",
|
||||
"description": "最小值对应的格子颜色",
|
||||
"value_type": "color",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.visualMap.inRange.color.4",
|
||||
"label": "高值颜色",
|
||||
"description": "最大值对应的格子颜色",
|
||||
"value_type": "color",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.visualMap.inRange.color",
|
||||
"label": "色阶颜色",
|
||||
"description": "从低到高的 5 个颜色,整体换配色时修改它",
|
||||
"value_type": "array",
|
||||
"item_type": "color",
|
||||
"aliases": [
|
||||
"配色",
|
||||
"渐变色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "heatmap-label",
|
||||
"label": "数值标签",
|
||||
"description": "格子内显示的数值",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.label.show",
|
||||
"label": "显示数值",
|
||||
"description": "是否在每个格子内显示数值",
|
||||
"value_type": "boolean",
|
||||
"aliases": [
|
||||
"数值标签",
|
||||
"标签"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.formatter",
|
||||
"label": "数值格式",
|
||||
"description": "格子内数值的显示格式,用 {@字段名} 引用数值列,例如 {@value};修改数值字段时需同步修改",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"标签格式"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.label.color",
|
||||
"label": "数值文字色",
|
||||
"description": "格子内数值文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"标签颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-xy",
|
||||
{
|
||||
"key": "heatmap-value",
|
||||
"label": "数值映射",
|
||||
"description": "格子颜色使用的数值列",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.encode.value",
|
||||
"label": "数值字段",
|
||||
"description": "格子数值使用数据集中的哪一列,必须是 dataset.source 中的最后一列;修改后同步修改数值格式",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"值字段"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "heatmap-chart",
|
||||
"name": "热力图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 480,
|
||||
"height": 300
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"title": {
|
||||
"text": "访问时段分布",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"position": "top"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周一",
|
||||
"value": 8
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周一",
|
||||
"value": 7
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周一",
|
||||
"value": 46
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周一",
|
||||
"value": 62
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周一",
|
||||
"value": 76
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周一",
|
||||
"value": 84
|
||||
},
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周二",
|
||||
"value": 15
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周二",
|
||||
"value": 14
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周二",
|
||||
"value": 42
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周二",
|
||||
"value": 58
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周二",
|
||||
"value": 72
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周二",
|
||||
"value": 80
|
||||
},
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周三",
|
||||
"value": 11
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周三",
|
||||
"value": 10
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周三",
|
||||
"value": 49
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周三",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周三",
|
||||
"value": 68
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周三",
|
||||
"value": 76
|
||||
},
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周四",
|
||||
"value": 18
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周四",
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周四",
|
||||
"value": 45
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周四",
|
||||
"value": 61
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周四",
|
||||
"value": 75
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周四",
|
||||
"value": 83
|
||||
},
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周五",
|
||||
"value": 14
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周五",
|
||||
"value": 13
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周五",
|
||||
"value": 52
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周五",
|
||||
"value": 57
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周五",
|
||||
"value": 71
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周五",
|
||||
"value": 79
|
||||
},
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周六",
|
||||
"value": 12
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周六",
|
||||
"value": 11
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周六",
|
||||
"value": 61
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周六",
|
||||
"value": 81
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周六",
|
||||
"value": 98
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周六",
|
||||
"value": 97
|
||||
},
|
||||
{
|
||||
"slot": "0-4点",
|
||||
"day": "周日",
|
||||
"value": 19
|
||||
},
|
||||
{
|
||||
"slot": "4-8点",
|
||||
"day": "周日",
|
||||
"value": 7
|
||||
},
|
||||
{
|
||||
"slot": "8-12点",
|
||||
"day": "周日",
|
||||
"value": 57
|
||||
},
|
||||
{
|
||||
"slot": "12-16点",
|
||||
"day": "周日",
|
||||
"value": 77
|
||||
},
|
||||
{
|
||||
"slot": "16-20点",
|
||||
"day": "周日",
|
||||
"value": 94
|
||||
},
|
||||
{
|
||||
"slot": "20-24点",
|
||||
"day": "周日",
|
||||
"value": 104
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 48,
|
||||
"right": 24,
|
||||
"bottom": 64,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitArea": {
|
||||
"show": true
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"inverse": true,
|
||||
"splitArea": {
|
||||
"show": true
|
||||
}
|
||||
},
|
||||
"visualMap": {
|
||||
"min": 0,
|
||||
"max": 120,
|
||||
"calculable": true,
|
||||
"orient": "horizontal",
|
||||
"left": "center",
|
||||
"bottom": 4,
|
||||
"itemHeight": 120,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"inRange": {
|
||||
"color": [
|
||||
"#1d2b44",
|
||||
"#337ecc",
|
||||
"#79bbff",
|
||||
"#e6a23c",
|
||||
"#f56c6c"
|
||||
]
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "访问量",
|
||||
"type": "heatmap",
|
||||
"label": {
|
||||
"show": true,
|
||||
"formatter": "{@value}",
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 11
|
||||
},
|
||||
"itemStyle": {
|
||||
"borderColor": "#141414",
|
||||
"borderWidth": 2
|
||||
},
|
||||
"encode": {
|
||||
"x": "slot",
|
||||
"y": "day",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
{
|
||||
"order": 3,
|
||||
"key": "line-chart",
|
||||
"type": "line-chart",
|
||||
"name": "折线图",
|
||||
"description": "展示数值随时间或有序类目的变化趋势",
|
||||
"tags": [
|
||||
"charts",
|
||||
"折线图",
|
||||
"line-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:graph-up-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
"chart-axis",
|
||||
"chart-line-series",
|
||||
"chart-encode-xy"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "line-chart",
|
||||
"name": "折线图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "访问量趋势",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "axis"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"date": "周一",
|
||||
"visits": 820
|
||||
},
|
||||
{
|
||||
"date": "周二",
|
||||
"visits": 932
|
||||
},
|
||||
{
|
||||
"date": "周三",
|
||||
"visits": 901
|
||||
},
|
||||
{
|
||||
"date": "周四",
|
||||
"visits": 934
|
||||
},
|
||||
{
|
||||
"date": "周五",
|
||||
"visits": 1290
|
||||
},
|
||||
{
|
||||
"date": "周六",
|
||||
"visits": 1330
|
||||
},
|
||||
{
|
||||
"date": "周日",
|
||||
"visits": 1320
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 24,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"boundaryGap": false,
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "访问量",
|
||||
"type": "line",
|
||||
"smooth": true,
|
||||
"symbolSize": 8,
|
||||
"encode": {
|
||||
"x": "date",
|
||||
"y": "visits"
|
||||
},
|
||||
"lineStyle": {
|
||||
"width": 3,
|
||||
"color": "#409eff"
|
||||
},
|
||||
"itemStyle": {
|
||||
"color": "#409eff"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
{
|
||||
"order": 13,
|
||||
"key": "pictorial-bar-chart",
|
||||
"type": "pictorial-bar-chart",
|
||||
"name": "象形柱图",
|
||||
"description": "用重复的图形堆叠成柱子对比各类目数值,视觉上更形象",
|
||||
"tags": [
|
||||
"charts",
|
||||
"象形柱图",
|
||||
"pictorial-bar-chart",
|
||||
"象形",
|
||||
"分段",
|
||||
"装饰"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:battery-charge-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-grid",
|
||||
"chart-axis",
|
||||
{
|
||||
"key": "pictorial-series",
|
||||
"label": "图形",
|
||||
"description": "组成柱子的图形样式",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.color",
|
||||
"label": "图形颜色",
|
||||
"description": "图形的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbol",
|
||||
"label": "图形",
|
||||
"description": "组成柱子的图形形状",
|
||||
"value_type": "enum",
|
||||
"options": [
|
||||
{
|
||||
"value": "rect",
|
||||
"label": "矩形"
|
||||
},
|
||||
{
|
||||
"value": "roundRect",
|
||||
"label": "圆角矩形"
|
||||
},
|
||||
{
|
||||
"value": "circle",
|
||||
"label": "圆形"
|
||||
},
|
||||
{
|
||||
"value": "triangle",
|
||||
"label": "三角形"
|
||||
},
|
||||
{
|
||||
"value": "diamond",
|
||||
"label": "菱形"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"形状"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbolSize.0",
|
||||
"label": "图形宽度",
|
||||
"description": "单个图形的宽度",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"minimum": 1,
|
||||
"unit": "px"
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbolSize.1",
|
||||
"label": "图形高度",
|
||||
"description": "单个图形的高度",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"minimum": 1,
|
||||
"unit": "px"
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbolMargin",
|
||||
"label": "图形间距",
|
||||
"description": "重复图形之间的间隔",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"minimum": 0,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"间距"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbolRepeat",
|
||||
"label": "重复图形",
|
||||
"description": "开启后用多个小图形重复堆叠成柱子,关闭后用一个拉伸的图形",
|
||||
"value_type": "boolean",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"重复"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列名称",
|
||||
"description": "这组柱子的名称,显示在鼠标悬停提示中;不是图表标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"系列名",
|
||||
"数据名称"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-xy"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "pictorial-bar-chart",
|
||||
"name": "象形柱图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"title": {
|
||||
"text": "各仓库库存量",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "axis",
|
||||
"axisPointer": {
|
||||
"type": "none"
|
||||
}
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"warehouse": "上海仓",
|
||||
"stock": 86
|
||||
},
|
||||
{
|
||||
"warehouse": "广州仓",
|
||||
"stock": 72
|
||||
},
|
||||
{
|
||||
"warehouse": "北京仓",
|
||||
"stock": 64
|
||||
},
|
||||
{
|
||||
"warehouse": "成都仓",
|
||||
"stock": 45
|
||||
},
|
||||
{
|
||||
"warehouse": "武汉仓",
|
||||
"stock": 38
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 48,
|
||||
"right": 24,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "库存",
|
||||
"type": "pictorialBar",
|
||||
"symbol": "rect",
|
||||
"symbolRepeat": true,
|
||||
"symbolSize": [
|
||||
24,
|
||||
6
|
||||
],
|
||||
"symbolMargin": 2,
|
||||
"symbolClip": true,
|
||||
"itemStyle": {
|
||||
"color": "#409eff"
|
||||
},
|
||||
"encode": {
|
||||
"x": "warehouse",
|
||||
"y": "stock"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
{
|
||||
"order": 4,
|
||||
"key": "pie-chart",
|
||||
"type": "pie-chart",
|
||||
"name": "饼图",
|
||||
"description": "展示各部分占整体的比例,适合类目不多的占比数据",
|
||||
"tags": [
|
||||
"charts",
|
||||
"饼图",
|
||||
"pie-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:pie-chart-2-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-palette",
|
||||
"chart-item-series",
|
||||
"chart-encode-item"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "pie-chart",
|
||||
"name": "饼图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#67c23a",
|
||||
"#e6a23c",
|
||||
"#f56c6c",
|
||||
"#909399"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "访问来源占比",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"channel": "搜索引擎",
|
||||
"value": 1048
|
||||
},
|
||||
{
|
||||
"channel": "直接访问",
|
||||
"value": 735
|
||||
},
|
||||
{
|
||||
"channel": "社交媒体",
|
||||
"value": 484
|
||||
},
|
||||
{
|
||||
"channel": "广告投放",
|
||||
"value": 300
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "访问来源",
|
||||
"type": "pie",
|
||||
"center": [
|
||||
"50%",
|
||||
"62%"
|
||||
],
|
||||
"avoidLabelOverlap": true,
|
||||
"label": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"labelLine": {
|
||||
"lineStyle": {
|
||||
"color": "#a3a6ad"
|
||||
}
|
||||
},
|
||||
"encode": {
|
||||
"itemName": "channel",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
{
|
||||
"order": 15,
|
||||
"key": "progress-ring-chart",
|
||||
"type": "progress-ring-chart",
|
||||
"name": "进度环",
|
||||
"description": "用环形进度条展示单个指标的完成百分比",
|
||||
"tags": [
|
||||
"charts",
|
||||
"进度环",
|
||||
"progress-ring-chart",
|
||||
"进度",
|
||||
"完成率",
|
||||
"百分比"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:pie-chart-3-linear",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作",
|
||||
"基于 gauge 系列,数据源取第一行,前端按 encode 转成 series.data"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-gauge-value",
|
||||
{
|
||||
"key": "progress-ring-shape",
|
||||
"label": "环形",
|
||||
"description": "进度环和底环的粗细与端点",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.progress.width",
|
||||
"label": "环宽度",
|
||||
"description": "进度环的粗细",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"minimum": 1,
|
||||
"maximum": 60,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"进度环宽度",
|
||||
"环的粗细"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.axisLine.lineStyle.width",
|
||||
"label": "底环宽度",
|
||||
"description": "进度环下方灰色底环的粗细,通常与环宽度相同",
|
||||
"value_type": "number",
|
||||
"span": 12,
|
||||
"minimum": 1,
|
||||
"maximum": 60,
|
||||
"unit": "px"
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.progress.roundCap",
|
||||
"label": "圆角端点",
|
||||
"description": "开启后进度环两端为圆角",
|
||||
"value_type": "boolean",
|
||||
"aliases": [
|
||||
"圆角"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-item"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "progress-ring-chart",
|
||||
"name": "进度环",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 260,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"title": {
|
||||
"text": "年度目标完成率",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item",
|
||||
"formatter": "{b}: {c}%"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"name": "完成率",
|
||||
"value": 68
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"type": "gauge",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"startAngle": 90,
|
||||
"endAngle": -270,
|
||||
"center": [
|
||||
"50%",
|
||||
"56%"
|
||||
],
|
||||
"radius": "72%",
|
||||
"pointer": {
|
||||
"show": false
|
||||
},
|
||||
"progress": {
|
||||
"show": true,
|
||||
"roundCap": true,
|
||||
"width": 14,
|
||||
"itemStyle": {
|
||||
"color": "#409eff"
|
||||
}
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"width": 14,
|
||||
"color": [
|
||||
[
|
||||
1,
|
||||
"rgba(255, 255, 255, 0.1)"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"axisTick": {
|
||||
"show": false
|
||||
},
|
||||
"splitLine": {
|
||||
"show": false
|
||||
},
|
||||
"axisLabel": {
|
||||
"show": false
|
||||
},
|
||||
"title": {
|
||||
"offsetCenter": [
|
||||
0,
|
||||
"28%"
|
||||
],
|
||||
"color": "#cfd3dc",
|
||||
"fontSize": 13
|
||||
},
|
||||
"detail": {
|
||||
"valueAnimation": true,
|
||||
"offsetCenter": [
|
||||
0,
|
||||
"-8%"
|
||||
],
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 30,
|
||||
"fontWeight": "bold",
|
||||
"formatter": "{value}%"
|
||||
},
|
||||
"encode": {
|
||||
"itemName": "name",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
{
|
||||
"order": 7,
|
||||
"key": "radar-chart",
|
||||
"type": "radar-chart",
|
||||
"name": "雷达图",
|
||||
"description": "在多个维度上对比一个或多个对象的得分",
|
||||
"tags": [
|
||||
"charts",
|
||||
"雷达图",
|
||||
"radar-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:radar-2-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-palette",
|
||||
{
|
||||
"key": "radar-series",
|
||||
"label": "线条",
|
||||
"description": "各对象雷达线的颜色和填充",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.color.0",
|
||||
"label": "第一条线颜色",
|
||||
"description": "第一个对象(数据集第一行)的雷达线颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.color.1",
|
||||
"label": "第二条线颜色",
|
||||
"description": "第二个对象(数据集第二行)的雷达线颜色",
|
||||
"value_type": "color"
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.lineStyle.width",
|
||||
"label": "线宽",
|
||||
"description": "雷达线的粗细",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 12,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"线条粗细"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.areaStyle.opacity",
|
||||
"label": "填充透明度",
|
||||
"description": "雷达线围成区域的填充透明度,0 为不填充,1 为不透明",
|
||||
"value_type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"aliases": [
|
||||
"填充",
|
||||
"透明度"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "radar-axis",
|
||||
"label": "维度",
|
||||
"description": "雷达图的各个维度及其文字样式",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.radar.indicator",
|
||||
"label": "维度",
|
||||
"description": "雷达图的维度列表,每项为 {name: 维度名称, max: 满分},顺序与数值字段一一对应",
|
||||
"value_type": "array",
|
||||
"item_type": "object",
|
||||
"aliases": [
|
||||
"指标",
|
||||
"维度名称",
|
||||
"满分"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.radar.axisName.color",
|
||||
"label": "维度文字色",
|
||||
"description": "维度名称文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"维度颜色",
|
||||
"指标文字颜色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "radar-data",
|
||||
"label": "数据映射",
|
||||
"description": "雷达图从数据集(dataset.source)中取哪些列",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.encode.itemName",
|
||||
"label": "名称字段",
|
||||
"description": "每个对象(每条雷达线)的名称使用数据集中的哪一列",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"对象字段",
|
||||
"类目字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.encode.value",
|
||||
"label": "数值字段",
|
||||
"description": "各维度的得分依次使用数据集中的哪些列,顺序与维度列表一一对应",
|
||||
"value_type": "array",
|
||||
"item_type": "string",
|
||||
"aliases": [
|
||||
"维度字段",
|
||||
"得分字段"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "radar-chart",
|
||||
"name": "雷达图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 280
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#67c23a",
|
||||
"#e6a23c",
|
||||
"#f56c6c",
|
||||
"#909399"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "店铺服务评分",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {},
|
||||
"radar": {
|
||||
"center": [
|
||||
"50%",
|
||||
"62%"
|
||||
],
|
||||
"radius": "58%",
|
||||
"indicator": [
|
||||
{
|
||||
"name": "商品质量",
|
||||
"max": 100
|
||||
},
|
||||
{
|
||||
"name": "物流速度",
|
||||
"max": 100
|
||||
},
|
||||
{
|
||||
"name": "服务态度",
|
||||
"max": 100
|
||||
},
|
||||
{
|
||||
"name": "描述相符",
|
||||
"max": 100
|
||||
},
|
||||
{
|
||||
"name": "售后保障",
|
||||
"max": 100
|
||||
}
|
||||
],
|
||||
"axisName": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.12)"
|
||||
}
|
||||
},
|
||||
"splitArea": {
|
||||
"areaStyle": {
|
||||
"color": [
|
||||
"rgba(255, 255, 255, 0.03)",
|
||||
"rgba(255, 255, 255, 0.06)"
|
||||
]
|
||||
}
|
||||
},
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.16)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"name": "店铺A",
|
||||
"sales": 80,
|
||||
"market": 70,
|
||||
"develop": 90,
|
||||
"support": 85,
|
||||
"tech": 75
|
||||
},
|
||||
{
|
||||
"name": "店铺B",
|
||||
"sales": 65,
|
||||
"market": 88,
|
||||
"develop": 72,
|
||||
"support": 78,
|
||||
"tech": 92
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "评分",
|
||||
"type": "radar",
|
||||
"encode": {
|
||||
"itemName": "name",
|
||||
"value": [
|
||||
"sales",
|
||||
"market",
|
||||
"develop",
|
||||
"support",
|
||||
"tech"
|
||||
]
|
||||
},
|
||||
"lineStyle": {
|
||||
"width": 2
|
||||
},
|
||||
"areaStyle": {
|
||||
"opacity": 0.18
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"order": 5,
|
||||
"key": "ring-chart",
|
||||
"type": "ring-chart",
|
||||
"name": "环形图",
|
||||
"description": "中间留空的饼图,展示各部分占整体的比例",
|
||||
"tags": [
|
||||
"charts",
|
||||
"环形图",
|
||||
"ring-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:pie-chart-3-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-palette",
|
||||
"chart-item-series",
|
||||
{
|
||||
"key": "ring-shape",
|
||||
"label": "环形",
|
||||
"description": "环形的内外半径",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.radius",
|
||||
"label": "内外半径",
|
||||
"description": "两个百分比依次为内半径和外半径,相对组件较短边的一半,例如 [\"42%\", \"68%\"];内半径越大环越细",
|
||||
"value_type": "array",
|
||||
"item_type": "string",
|
||||
"aliases": [
|
||||
"环宽",
|
||||
"半径",
|
||||
"环的粗细"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-item"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "ring-chart",
|
||||
"name": "环形图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#67c23a",
|
||||
"#e6a23c",
|
||||
"#f56c6c",
|
||||
"#909399"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "设备占比",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"device": "桌面端",
|
||||
"value": 1048
|
||||
},
|
||||
{
|
||||
"device": "移动端",
|
||||
"value": 735
|
||||
},
|
||||
{
|
||||
"device": "平板",
|
||||
"value": 380
|
||||
},
|
||||
{
|
||||
"device": "其他",
|
||||
"value": 184
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "设备",
|
||||
"type": "pie",
|
||||
"radius": [
|
||||
"42%",
|
||||
"68%"
|
||||
],
|
||||
"center": [
|
||||
"50%",
|
||||
"62%"
|
||||
],
|
||||
"avoidLabelOverlap": true,
|
||||
"label": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"labelLine": {
|
||||
"lineStyle": {
|
||||
"color": "#a3a6ad"
|
||||
}
|
||||
},
|
||||
"encode": {
|
||||
"itemName": "device",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"order": 12,
|
||||
"key": "rose-chart",
|
||||
"type": "rose-chart",
|
||||
"name": "玫瑰图",
|
||||
"description": "用扇区半径展示各类目数值大小的饼图变体,差异比普通饼图更醒目",
|
||||
"tags": [
|
||||
"charts",
|
||||
"玫瑰图",
|
||||
"rose-chart",
|
||||
"南丁格尔",
|
||||
"占比"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:pie-chart-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-palette",
|
||||
"chart-item-series",
|
||||
{
|
||||
"key": "rose-shape",
|
||||
"label": "玫瑰",
|
||||
"description": "玫瑰图的类型和半径",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.roseType",
|
||||
"label": "玫瑰类型",
|
||||
"description": "扇区如何体现数值",
|
||||
"value_type": "enum",
|
||||
"options": [
|
||||
{
|
||||
"value": "area",
|
||||
"label": "面积模式",
|
||||
"description": "各扇区圆心角相同,半径体现数值"
|
||||
},
|
||||
{
|
||||
"value": "radius",
|
||||
"label": "半径模式",
|
||||
"description": "圆心角和半径都体现数值"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"模式"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.radius",
|
||||
"label": "内外半径",
|
||||
"description": "两个百分比依次为内半径和外半径,相对组件较短边的一半,例如 [\"12%\", \"62%\"]",
|
||||
"value_type": "array",
|
||||
"item_type": "string",
|
||||
"aliases": [
|
||||
"半径"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-item"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "rose-chart",
|
||||
"name": "玫瑰图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#67c23a",
|
||||
"#e6a23c",
|
||||
"#f56c6c",
|
||||
"#909399",
|
||||
"#b37feb"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "区域销售分布",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"region": "华东",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"region": "华南",
|
||||
"value": 33
|
||||
},
|
||||
{
|
||||
"region": "华北",
|
||||
"value": 28
|
||||
},
|
||||
{
|
||||
"region": "西南",
|
||||
"value": 22
|
||||
},
|
||||
{
|
||||
"region": "华中",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"region": "西北",
|
||||
"value": 15
|
||||
}
|
||||
]
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "区域",
|
||||
"type": "pie",
|
||||
"roseType": "area",
|
||||
"radius": [
|
||||
"12%",
|
||||
"62%"
|
||||
],
|
||||
"center": [
|
||||
"50%",
|
||||
"62%"
|
||||
],
|
||||
"itemStyle": {
|
||||
"borderRadius": 4
|
||||
},
|
||||
"label": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"labelLine": {
|
||||
"lineStyle": {
|
||||
"color": "#a3a6ad"
|
||||
}
|
||||
},
|
||||
"encode": {
|
||||
"itemName": "region",
|
||||
"value": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"order": 6,
|
||||
"key": "scatter-chart",
|
||||
"type": "scatter-chart",
|
||||
"name": "散点图",
|
||||
"description": "用点的横纵位置展示两个数值指标之间的关系和分布",
|
||||
"tags": [
|
||||
"charts",
|
||||
"散点图",
|
||||
"scatter-chart"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:chart-square-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
"chart-axis",
|
||||
{
|
||||
"key": "scatter-series",
|
||||
"label": "散点",
|
||||
"description": "散点的颜色、大小和系列名称",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.itemStyle.color",
|
||||
"label": "点颜色",
|
||||
"description": "散点的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"散点颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.symbolSize",
|
||||
"label": "点大小",
|
||||
"description": "散点的直径",
|
||||
"value_type": "number",
|
||||
"minimum": 1,
|
||||
"maximum": 60,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"散点大小",
|
||||
"点的大小"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列名称",
|
||||
"description": "这组散点的名称,显示在图例和鼠标悬停提示中;不是图表标题",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称",
|
||||
"系列名",
|
||||
"数据名称"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"chart-encode-xy"
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "scatter-chart",
|
||||
"name": "散点图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "访客数与销售额",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "item"
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"users": 12,
|
||||
"sales": 32
|
||||
},
|
||||
{
|
||||
"users": 28,
|
||||
"sales": 48
|
||||
},
|
||||
{
|
||||
"users": 35,
|
||||
"sales": 41
|
||||
},
|
||||
{
|
||||
"users": 47,
|
||||
"sales": 72
|
||||
},
|
||||
{
|
||||
"users": 58,
|
||||
"sales": 66
|
||||
},
|
||||
{
|
||||
"users": 69,
|
||||
"sales": 88
|
||||
},
|
||||
{
|
||||
"users": 81,
|
||||
"sales": 94
|
||||
},
|
||||
{
|
||||
"users": 90,
|
||||
"sales": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 24,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "value",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "店铺",
|
||||
"type": "scatter",
|
||||
"symbolSize": 12,
|
||||
"encode": {
|
||||
"x": "users",
|
||||
"y": "sales"
|
||||
},
|
||||
"itemStyle": {
|
||||
"color": "#409eff"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
{
|
||||
"order": 10,
|
||||
"key": "stacked-bar-chart",
|
||||
"type": "stacked-bar-chart",
|
||||
"name": "堆叠柱状图",
|
||||
"description": "多个系列在同一柱子上堆叠,同时展示总量和各部分构成",
|
||||
"tags": [
|
||||
"charts",
|
||||
"堆叠柱状图",
|
||||
"stacked-bar-chart",
|
||||
"堆叠",
|
||||
"构成"
|
||||
],
|
||||
"renderer": "echarts",
|
||||
"group": "charts",
|
||||
"icon": "solar:chart-bold",
|
||||
"sample_data": true,
|
||||
"usage_notes": [
|
||||
"默认图表数据仅用于演示,不是真实业务数据",
|
||||
"通过顶层 dataId 关联已有数据源,当前后端尚未实现绑定操作",
|
||||
"三个系列共用 stack: total,X 字段需在三个系列的 encode.x 中保持一致"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
"chart-title",
|
||||
"chart-legend",
|
||||
"chart-grid",
|
||||
"chart-axis",
|
||||
"chart-palette",
|
||||
{
|
||||
"key": "stacked-series",
|
||||
"label": "系列",
|
||||
"description": "三个堆叠系列的颜色和名称,从下往上依次为系列1、2、3",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.color.0",
|
||||
"label": "系列1颜色",
|
||||
"description": "第 1 个系列(从下往上第 1 段)的颜色",
|
||||
"value_type": "color",
|
||||
"span": 12,
|
||||
"aliases": [
|
||||
"颜色",
|
||||
"主色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.color.1",
|
||||
"label": "系列2颜色",
|
||||
"description": "第 2 个系列(从下往上第 2 段)的颜色",
|
||||
"value_type": "color",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.color.2",
|
||||
"label": "系列3颜色",
|
||||
"description": "第 3 个系列(从下往上第 3 段)的颜色",
|
||||
"value_type": "color",
|
||||
"span": 12
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.name",
|
||||
"label": "系列1名称",
|
||||
"description": "第 1 个系列的名称,显示在图例和鼠标悬停提示中",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.name",
|
||||
"label": "系列2名称",
|
||||
"description": "第 2 个系列的名称,显示在图例和鼠标悬停提示中",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.2.name",
|
||||
"label": "系列3名称",
|
||||
"description": "第 3 个系列的名称,显示在图例和鼠标悬停提示中",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"图例名称"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "stacked-data",
|
||||
"label": "数据映射",
|
||||
"description": "堆叠柱状图从数据集(dataset.source)中取哪些列",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.option.series.0.encode.x",
|
||||
"label": "X字段",
|
||||
"description": "横轴类目使用数据集中的哪一列;三个系列必须相同,修改时同时修改系列2、系列3的X字段",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"横轴字段",
|
||||
"类目字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.encode.x",
|
||||
"label": "系列2X字段",
|
||||
"description": "须与X字段保持一致,修改X字段时同步修改",
|
||||
"value_type": "string",
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.2.encode.x",
|
||||
"label": "系列3X字段",
|
||||
"description": "须与X字段保持一致,修改X字段时同步修改",
|
||||
"value_type": "string",
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.0.encode.y",
|
||||
"label": "系列1字段",
|
||||
"description": "第 1 个系列的数值使用数据集中的哪一列",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"系列1数值字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.1.encode.y",
|
||||
"label": "系列2字段",
|
||||
"description": "第 2 个系列的数值使用数据集中的哪一列",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"系列2数值字段"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "props.option.series.2.encode.y",
|
||||
"label": "系列3字段",
|
||||
"description": "第 3 个系列的数值使用数据集中的哪一列",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"系列3数值字段"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "stacked-bar-chart",
|
||||
"name": "堆叠柱状图",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 400,
|
||||
"height": 260
|
||||
},
|
||||
"props": {
|
||||
"option": {
|
||||
"color": [
|
||||
"#409eff",
|
||||
"#67c23a",
|
||||
"#e6a23c",
|
||||
"#f56c6c",
|
||||
"#909399"
|
||||
],
|
||||
"legend": {
|
||||
"top": 38,
|
||||
"left": "center",
|
||||
"itemWidth": 12,
|
||||
"itemHeight": 8,
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"text": "各渠道月度销售额",
|
||||
"top": 8,
|
||||
"left": "center",
|
||||
"textStyle": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"trigger": "axis",
|
||||
"axisPointer": {
|
||||
"type": "shadow"
|
||||
}
|
||||
},
|
||||
"dataset": {
|
||||
"source": [
|
||||
{
|
||||
"month": "一月",
|
||||
"online": 120,
|
||||
"offline": 220,
|
||||
"agent": 150
|
||||
},
|
||||
{
|
||||
"month": "二月",
|
||||
"online": 132,
|
||||
"offline": 182,
|
||||
"agent": 212
|
||||
},
|
||||
{
|
||||
"month": "三月",
|
||||
"online": 101,
|
||||
"offline": 191,
|
||||
"agent": 201
|
||||
},
|
||||
{
|
||||
"month": "四月",
|
||||
"online": 134,
|
||||
"offline": 234,
|
||||
"agent": 154
|
||||
},
|
||||
{
|
||||
"month": "五月",
|
||||
"online": 90,
|
||||
"offline": 290,
|
||||
"agent": 190
|
||||
},
|
||||
{
|
||||
"month": "六月",
|
||||
"online": 230,
|
||||
"offline": 330,
|
||||
"agent": 330
|
||||
}
|
||||
]
|
||||
},
|
||||
"grid": {
|
||||
"top": 86,
|
||||
"right": 24,
|
||||
"bottom": 32,
|
||||
"left": 48,
|
||||
"containLabel": true
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"axisLine": {
|
||||
"lineStyle": {
|
||||
"color": "#4c4d4f"
|
||||
}
|
||||
},
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
}
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"color": "#cfd3dc"
|
||||
},
|
||||
"splitLine": {
|
||||
"lineStyle": {
|
||||
"color": "rgba(255, 255, 255, 0.08)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "线上",
|
||||
"type": "bar",
|
||||
"stack": "total",
|
||||
"barWidth": "45%",
|
||||
"encode": {
|
||||
"x": "month",
|
||||
"y": "online"
|
||||
},
|
||||
"itemStyle": {}
|
||||
},
|
||||
{
|
||||
"name": "门店",
|
||||
"type": "bar",
|
||||
"stack": "total",
|
||||
"barWidth": "45%",
|
||||
"encode": {
|
||||
"x": "month",
|
||||
"y": "offline"
|
||||
},
|
||||
"itemStyle": {}
|
||||
},
|
||||
{
|
||||
"name": "代理",
|
||||
"type": "bar",
|
||||
"stack": "total",
|
||||
"barWidth": "45%",
|
||||
"encode": {
|
||||
"x": "month",
|
||||
"y": "agent"
|
||||
},
|
||||
"itemStyle": {
|
||||
"borderRadius": [
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"style": null,
|
||||
"events": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
{
|
||||
"order": 16,
|
||||
"key": "text",
|
||||
"type": "text",
|
||||
"name": "文本",
|
||||
"description": "显示一段文字,常用作大屏标题、说明或标签",
|
||||
"tags": [
|
||||
"info",
|
||||
"文本",
|
||||
"text"
|
||||
],
|
||||
"renderer": "text",
|
||||
"group": "info",
|
||||
"icon": "solar:text-bold",
|
||||
"sample_data": false,
|
||||
"usage_notes": [
|
||||
"events 中代码只作为资料保存,不由后端执行"
|
||||
],
|
||||
"field_groups": [
|
||||
"node-base",
|
||||
{
|
||||
"key": "text-content",
|
||||
"label": "内容",
|
||||
"description": "文本组件显示的文字",
|
||||
"fields": [
|
||||
{
|
||||
"path": "props.content",
|
||||
"label": "内容",
|
||||
"description": "文本组件显示的文字",
|
||||
"value_type": "string",
|
||||
"aliases": [
|
||||
"文字",
|
||||
"文本内容",
|
||||
"标题文字",
|
||||
"名字"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "text-style",
|
||||
"label": "文字样式",
|
||||
"description": "文字的颜色、大小、粗细和对齐",
|
||||
"fields": [
|
||||
{
|
||||
"path": "style.color",
|
||||
"label": "颜色",
|
||||
"description": "文字的颜色",
|
||||
"value_type": "color",
|
||||
"aliases": [
|
||||
"文字颜色",
|
||||
"字体颜色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "style.fontSize",
|
||||
"label": "字号",
|
||||
"description": "文字的大小",
|
||||
"value_type": "number",
|
||||
"minimum": 8,
|
||||
"maximum": 200,
|
||||
"unit": "px",
|
||||
"aliases": [
|
||||
"字体大小",
|
||||
"文字大小"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "style.textAlign",
|
||||
"label": "水平对齐",
|
||||
"description": "文字在组件内的水平位置",
|
||||
"value_type": "enum",
|
||||
"options": [
|
||||
{
|
||||
"value": "left",
|
||||
"label": "左对齐"
|
||||
},
|
||||
{
|
||||
"value": "center",
|
||||
"label": "居中"
|
||||
},
|
||||
{
|
||||
"value": "right",
|
||||
"label": "右对齐"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"对齐"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "style.alignItems",
|
||||
"label": "垂直对齐",
|
||||
"description": "文字在组件内的垂直位置",
|
||||
"value_type": "enum",
|
||||
"options": [
|
||||
{
|
||||
"value": "flex-start",
|
||||
"label": "顶部"
|
||||
},
|
||||
{
|
||||
"value": "center",
|
||||
"label": "居中"
|
||||
},
|
||||
{
|
||||
"value": "flex-end",
|
||||
"label": "底部"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "style.fontWeight",
|
||||
"label": "字重",
|
||||
"description": "文字粗细",
|
||||
"value_type": "enum",
|
||||
"default": "normal",
|
||||
"options": [
|
||||
{
|
||||
"value": "normal",
|
||||
"label": "常规"
|
||||
},
|
||||
{
|
||||
"value": "bold",
|
||||
"label": "加粗"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
"加粗",
|
||||
"粗细"
|
||||
],
|
||||
"panel": false
|
||||
},
|
||||
{
|
||||
"path": "style.backgroundColor",
|
||||
"label": "背景色",
|
||||
"description": "文本组件的背景颜色,默认透明",
|
||||
"value_type": "color",
|
||||
"default": "transparent",
|
||||
"aliases": [
|
||||
"背景颜色",
|
||||
"底色"
|
||||
],
|
||||
"panel": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"eventOptions": [
|
||||
{
|
||||
"label": "点击事件",
|
||||
"value": "click"
|
||||
},
|
||||
{
|
||||
"label": "双击事件",
|
||||
"value": "dblclick"
|
||||
},
|
||||
{
|
||||
"label": "鼠标进入事件",
|
||||
"value": "mouseenter"
|
||||
},
|
||||
{
|
||||
"label": "鼠标离开事件",
|
||||
"value": "mouseleave"
|
||||
},
|
||||
{
|
||||
"label": "鼠标按下事件",
|
||||
"value": "mousedown"
|
||||
},
|
||||
{
|
||||
"label": "鼠标抬起事件",
|
||||
"value": "mouseup"
|
||||
},
|
||||
{
|
||||
"label": "鼠标移动事件",
|
||||
"value": "mousemove"
|
||||
},
|
||||
{
|
||||
"label": "鼠标滚轮事件",
|
||||
"value": "mousewheel"
|
||||
},
|
||||
{
|
||||
"label": "生命周期事件",
|
||||
"value": "vnodeMounted"
|
||||
}
|
||||
],
|
||||
"schema": {
|
||||
"type": "text",
|
||||
"name": "文本",
|
||||
"layout": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 200,
|
||||
"height": 50
|
||||
},
|
||||
"props": {
|
||||
"content": "电商运营数据看板"
|
||||
},
|
||||
"style": {
|
||||
"color": "#e5eaf3",
|
||||
"fontSize": 16,
|
||||
"textAlign": "center",
|
||||
"alignItems": "center"
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"type": "click",
|
||||
"title": "点击事件",
|
||||
"name": "fn",
|
||||
"code": "console.log(123)"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,9 @@ class ActionValidationError(BaseModel):
|
||||
action_index: int | None = Field(
|
||||
default=None, ge=0, description="失败动作的下标,从 0 开始,整批错误为 null"
|
||||
)
|
||||
code: Literal["schema_error", "generation_error", "scope_error", "execution_error"]
|
||||
code: Literal[
|
||||
"schema_error", "generation_error", "scope_error", "field_error", "execution_error"
|
||||
]
|
||||
message: str
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""精确更新组件 props 或 style 下的一个字段"""
|
||||
"""精确更新组件名称,或 props / style 下的一个字段"""
|
||||
|
||||
from typing import Annotated, Literal
|
||||
from typing import Annotated, Literal, Self
|
||||
|
||||
from pydantic import Field, JsonValue
|
||||
from pydantic import Field, JsonValue, model_validator
|
||||
|
||||
from app.schemas.base import NonBlankString
|
||||
|
||||
@@ -13,10 +13,21 @@ PathSegment = NonBlankString | Annotated[int, Field(ge=0)]
|
||||
|
||||
class UpdateAction(BaseAction):
|
||||
type: Literal["update"] = "update"
|
||||
section: Literal["props", "style"] = Field(description="允许更新的组件属性区域")
|
||||
section: Literal["name", "props", "style"] = Field(
|
||||
description="字段路径的第一段:name 为组件名称,props / style 为组件属性区域"
|
||||
)
|
||||
path: list[PathSegment] = Field(
|
||||
min_length=1, description="区域内的字段路径,字符串为对象键,整数为数组下标"
|
||||
)
|
||||
value: JsonValue = Field(
|
||||
description="替换该路径的值,支持任意 JSON;null 是赋值,不表示删除"
|
||||
description="字段路径第一段之后的各段,字符串为对象键,整数为数组下标;name 没有后续路径,传空列表"
|
||||
)
|
||||
value: JsonValue = Field(description="替换该字段的值,必须符合字段定义的类型和取值")
|
||||
|
||||
@model_validator(mode="after")
|
||||
def path_matches_section(self) -> Self:
|
||||
if (self.section == "name") != (not self.path):
|
||||
raise ValueError("section 为 name 时 path 为空,props / style 至少一段路径")
|
||||
return self
|
||||
|
||||
@property
|
||||
def field_path(self) -> str:
|
||||
"""与物料字段定义一致的点路径,例如 props.option.title.text"""
|
||||
return ".".join([self.section, *map(str, self.path)])
|
||||
|
||||
@@ -5,6 +5,7 @@ from typing import Literal, Self
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
|
||||
from app.schemas.base import ExtensibleModel, JsonObject, NonBlankString
|
||||
from app.schemas.material_field import MISSING, FieldGroup, lookup
|
||||
from app.schemas.screen import Layout, PositiveNumber
|
||||
|
||||
|
||||
@@ -26,15 +27,6 @@ class MaterialTemplate(ExtensibleModel):
|
||||
events: list[JsonObject] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MaterialSetter(ExtensibleModel):
|
||||
type: NonBlankString = Field(description="前端属性控件类型,不是完整的值类型约束")
|
||||
label: NonBlankString
|
||||
key: NonBlankString = Field(
|
||||
description="前端原始点路径,例如 props.option.series.0.itemStyle.color"
|
||||
)
|
||||
props: JsonObject = Field(default_factory=dict)
|
||||
|
||||
|
||||
class ComponentDefinition(ExtensibleModel):
|
||||
model_config = ConfigDict(serialize_by_alias=True)
|
||||
key: NonBlankString = Field(description="目录中的唯一编号,不是 Screen 节点 ID")
|
||||
@@ -52,22 +44,26 @@ class ComponentDefinition(ExtensibleModel):
|
||||
schema_: MaterialTemplate = Field(
|
||||
alias="schema", description="完整默认物料配置,不包含实例 ID"
|
||||
)
|
||||
setters: list[MaterialSetter] = Field(default_factory=list)
|
||||
field_groups: list[NonBlankString | FieldGroup] = Field(
|
||||
default_factory=list,
|
||||
description="字段分组:字符串引用目录的共享分组,对象为本物料独有的分组;"
|
||||
"前端属性面板的 setters 由它派生,不单独保存",
|
||||
)
|
||||
eventOptions: list[JsonObject] = Field(default_factory=list)
|
||||
sample_data: bool = Field(
|
||||
default=False, description="默认配置是否含示例数据,不能视为真实业务数据"
|
||||
)
|
||||
props_schema: JsonObject | None = Field(
|
||||
default=None,
|
||||
description="可选的 props JSON Schema,未提供表示未知,不表示无限制",
|
||||
)
|
||||
style_schema: JsonObject | None = Field(
|
||||
default=None, description="可选的 style JSON Schema,仅保存定义,当前不执行校验"
|
||||
)
|
||||
usage_notes: list[NonBlankString] = Field(
|
||||
default_factory=list, description="配置、数据绑定及使用限制说明"
|
||||
)
|
||||
|
||||
def template(self) -> JsonObject:
|
||||
"""默认配置的 JSON;style 为 null 表示未设置,字段默认值按路径不存在处理"""
|
||||
data = self.schema_.model_dump(mode="json")
|
||||
if data.get("style") is None:
|
||||
data.pop("style", None)
|
||||
return data
|
||||
|
||||
@model_validator(mode="after")
|
||||
def consistent_type(self) -> Self:
|
||||
if self.type != self.schema_.type:
|
||||
@@ -77,17 +73,73 @@ class ComponentDefinition(ExtensibleModel):
|
||||
return self
|
||||
|
||||
|
||||
def _default_problem(field, template: JsonObject) -> str | None:
|
||||
"""默认值只有一个来源:默认配置有该路径时取它,没有时字段必须声明 default"""
|
||||
try:
|
||||
current = lookup(template, field.segments)
|
||||
except ValueError:
|
||||
return "的路径与默认配置结构冲突"
|
||||
if current is MISSING:
|
||||
if field.default is None:
|
||||
return "在默认配置中不存在,需要声明 default"
|
||||
error = field.value_error(field.default)
|
||||
return f"的 default {error}" if error else None
|
||||
if field.default is not None:
|
||||
return "在默认配置中已有值,不能再声明 default"
|
||||
error = field.value_error(current)
|
||||
return f"的默认配置值 {error}" if error else None
|
||||
|
||||
|
||||
class ComponentCatalog(ExtensibleModel):
|
||||
version: NonBlankString = Field(
|
||||
description="前端组件目录版本,后续用于检查是否与前端匹配"
|
||||
)
|
||||
components: list[ComponentDefinition]
|
||||
field_groups: list[FieldGroup] = Field(
|
||||
default_factory=list, description="多个物料共用的字段分组,物料按 key 引用"
|
||||
)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def unique_keys(self) -> Self:
|
||||
keys = [component.key for component in self.components]
|
||||
if len(keys) != len(set(keys)):
|
||||
raise ValueError("组件目录 key 不能重复")
|
||||
shared = [group.key for group in self.field_groups]
|
||||
if len(shared) != len(set(shared)):
|
||||
raise ValueError("共享字段分组 key 不能重复")
|
||||
for component in self.components:
|
||||
groups = [
|
||||
group.key if isinstance(group, FieldGroup) else group
|
||||
for group in component.field_groups
|
||||
]
|
||||
if len(groups) != len(set(groups)):
|
||||
raise ValueError(f"物料 {component.key} 的字段分组 key 重复")
|
||||
if missing := [
|
||||
group
|
||||
for group in component.field_groups
|
||||
if isinstance(group, str) and group not in shared
|
||||
]:
|
||||
raise ValueError(f"物料 {component.key} 引用了不存在的共享分组: {missing}")
|
||||
if shadowed := [
|
||||
group.key
|
||||
for group in component.field_groups
|
||||
if isinstance(group, FieldGroup) and group.key in shared
|
||||
]:
|
||||
raise ValueError(f"物料 {component.key} 的独有分组与共享分组重名: {shadowed}")
|
||||
by_key = {group.key: group for group in self.field_groups}
|
||||
fields = [
|
||||
field
|
||||
for group in component.field_groups
|
||||
for field in (by_key[group] if isinstance(group, str) else group).fields
|
||||
]
|
||||
paths = [field.path for field in fields]
|
||||
if duplicated := sorted({path for path in paths if paths.count(path) > 1}):
|
||||
raise ValueError(f"物料 {component.key} 的字段路径重复: {duplicated}")
|
||||
template = component.template()
|
||||
for field in fields:
|
||||
problem = _default_problem(field, template)
|
||||
if problem:
|
||||
raise ValueError(f"物料 {component.key} 字段 {field.path} {problem}")
|
||||
return self
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
"""物料字段定义:分组 → 字段,每个字段带路径、含义、值类型和取值约束
|
||||
|
||||
字段定义是“组件有哪些可改属性”的唯一来源:前端属性面板的 setters、
|
||||
agent 查询字段、动作校验都由它派生,不再各自维护一份
|
||||
"""
|
||||
|
||||
from typing import Literal, Self
|
||||
|
||||
from pydantic import Field, JsonValue, model_validator
|
||||
|
||||
from app.schemas.base import ExtensibleModel, NonBlankString
|
||||
|
||||
# 字段路径的第一段:节点名称、布局、组件属性、组件样式
|
||||
FIELD_ROOTS = ("name", "layout", "props", "style")
|
||||
|
||||
ValueType = Literal[
|
||||
"string", "number", "integer", "boolean", "color", "enum", "array", "object"
|
||||
]
|
||||
# 数组元素只用基础类型,枚举和嵌套数组没有需要的场景
|
||||
ItemType = Literal["string", "number", "integer", "boolean", "color", "object"]
|
||||
|
||||
# 值类型对应的前端属性控件;array / object 没有通用控件,只能不在面板显示
|
||||
PANEL_CONTROLS: dict[str, str] = {
|
||||
"string": "input",
|
||||
"number": "number",
|
||||
"integer": "number",
|
||||
"boolean": "checkbox",
|
||||
"color": "color",
|
||||
"enum": "select",
|
||||
}
|
||||
|
||||
|
||||
# 默认配置中没有该路径时的标记,区别于值为 null
|
||||
MISSING = object()
|
||||
|
||||
# 值类型对应的 JSON 类型,用于检查默认配置里的现值
|
||||
_JSON_TYPES: dict[str, type | tuple[type, ...]] = {
|
||||
"string": str,
|
||||
"color": str,
|
||||
"number": (int, float),
|
||||
"integer": int,
|
||||
"boolean": bool,
|
||||
"array": list,
|
||||
"object": dict,
|
||||
}
|
||||
|
||||
|
||||
def _type_error(value_type: str, value: JsonValue) -> str | None:
|
||||
# bool 是 int 的子类,数值类型需要单独排除
|
||||
if not isinstance(value, _JSON_TYPES[value_type]) or (
|
||||
value_type in ("number", "integer") and isinstance(value, bool)
|
||||
):
|
||||
return f"类型必须是 {value_type}"
|
||||
return None
|
||||
|
||||
|
||||
def lookup(value: JsonValue, segments: list[str | int]):
|
||||
"""按路径取值;路径不存在返回 MISSING,路径中途遇到标量时抛 ValueError"""
|
||||
for segment in segments:
|
||||
if isinstance(value, dict) and isinstance(segment, str):
|
||||
if segment not in value:
|
||||
return MISSING
|
||||
value = value[segment]
|
||||
elif isinstance(value, list) and isinstance(segment, int):
|
||||
if segment >= len(value):
|
||||
return MISSING
|
||||
value = value[segment]
|
||||
else:
|
||||
raise ValueError(f"路径无法继续访问: {segments}")
|
||||
return value
|
||||
|
||||
|
||||
class FieldOption(ExtensibleModel):
|
||||
value: JsonValue
|
||||
label: NonBlankString
|
||||
description: NonBlankString | None = None
|
||||
|
||||
|
||||
class MaterialField(ExtensibleModel):
|
||||
path: NonBlankString = Field(
|
||||
description="点路径,与前端 setter key 一致,数字段为数组下标,例如 props.option.series.0.itemStyle.color"
|
||||
)
|
||||
label: NonBlankString = Field(description="字段名称,属性面板显示的文字")
|
||||
description: NonBlankString = Field(
|
||||
description="字段含义、在画面上的效果,以及用户通常怎么称呼它"
|
||||
)
|
||||
value_type: ValueType
|
||||
options: list[FieldOption] = Field(
|
||||
default_factory=list, description="enum 的可选值,每个值可带说明"
|
||||
)
|
||||
item_type: ItemType | None = Field(
|
||||
default=None, description="array 的元素类型"
|
||||
)
|
||||
minimum: int | float | None = None
|
||||
maximum: int | float | None = None
|
||||
unit: NonBlankString | None = Field(default=None, description="数值单位,例如 px")
|
||||
default: JsonValue = Field(
|
||||
default=None,
|
||||
description="物料默认配置中没有该路径时的默认值;有该路径时以默认配置为准,不在这里重复",
|
||||
)
|
||||
aliases: list[NonBlankString] = Field(
|
||||
default_factory=list, description="用户可能的叫法,供字段搜索使用"
|
||||
)
|
||||
editable: bool = Field(default=True, description="是否允许修改")
|
||||
panel: bool = Field(default=True, description="是否显示在前端属性面板")
|
||||
span: int | None = Field(default=None, description="属性面板栅格宽度,24 为整行")
|
||||
|
||||
@model_validator(mode="after")
|
||||
def consistent(self) -> Self:
|
||||
if self.path.split(".")[0] not in FIELD_ROOTS:
|
||||
raise ValueError(f"字段路径必须以 {'/'.join(FIELD_ROOTS)} 开头: {self.path}")
|
||||
if (self.value_type == "enum") != bool(self.options):
|
||||
raise ValueError(f"只有 enum 字段提供 options,且 enum 必须提供: {self.path}")
|
||||
if (self.value_type == "array") != (self.item_type is not None):
|
||||
raise ValueError(f"只有 array 字段提供 item_type,且 array 必须提供: {self.path}")
|
||||
if self.panel and self.value_type not in PANEL_CONTROLS:
|
||||
raise ValueError(f"{self.value_type} 字段没有属性面板控件,panel 必须为 false: {self.path}")
|
||||
return self
|
||||
|
||||
def value_error(self, value: JsonValue) -> str | None:
|
||||
"""检查值是否符合字段类型和取值约束,符合返回 None"""
|
||||
if self.value_type == "enum":
|
||||
allowed = [option.value for option in self.options]
|
||||
return None if value in allowed else f"取值必须是 {allowed} 之一"
|
||||
if error := _type_error(self.value_type, value):
|
||||
return error
|
||||
if self.item_type is not None:
|
||||
for element in value:
|
||||
if error := _type_error(self.item_type, element):
|
||||
return f"数组元素{error}"
|
||||
if self.value_type in ("number", "integer"):
|
||||
if self.minimum is not None and value < self.minimum:
|
||||
return f"不能小于 {self.minimum}"
|
||||
if self.maximum is not None and value > self.maximum:
|
||||
return f"不能大于 {self.maximum}"
|
||||
return None
|
||||
|
||||
@property
|
||||
def segments(self) -> list[str | int]:
|
||||
# 数字段视为数组下标,与前端 setter key 的解析方式一致
|
||||
return [int(part) if part.isdigit() else part for part in self.path.split(".")]
|
||||
|
||||
|
||||
class FieldGroup(ExtensibleModel):
|
||||
key: NonBlankString = Field(description="分组编号,共享分组在整个目录内唯一")
|
||||
label: NonBlankString
|
||||
description: NonBlankString = Field(description="这一组字段管什么,供模型先看目录再查字段")
|
||||
fields: list[MaterialField]
|
||||
|
||||
@model_validator(mode="after")
|
||||
def unique_paths(self) -> Self:
|
||||
paths = [field.path for field in self.fields]
|
||||
if len(paths) != len(set(paths)):
|
||||
raise ValueError(f"分组 {self.key} 中字段路径重复")
|
||||
return self
|
||||
@@ -30,7 +30,7 @@ class RequirementChange(ExtensibleModel):
|
||||
operation: NonBlankString = Field(description=f"需求操作。{OPERATION_GUIDE}")
|
||||
parameters: JsonObject = Field(
|
||||
default_factory=dict,
|
||||
description="需求参数,例如 delta_x=50;保留用户要求的单位与相对变化语义",
|
||||
description="需求参数,例如 delta_x=50;保留用户要求的单位与相对变化语义;属性修改用用户的说法描述改什么、改成什么,例如 {\"名字\": \"月度销售\"},不推断字段路径",
|
||||
)
|
||||
|
||||
@field_validator("operation")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""物料目录的 MongoDB 存储:每个组件一条记录,目录版本放在元数据记录中"""
|
||||
"""物料目录的 MongoDB 存储:每个组件一条记录,目录版本放在元数据记录中,
|
||||
多个物料共用的字段分组单独存放,每个分组一条记录"""
|
||||
|
||||
from loguru import logger
|
||||
from pymongo.asynchronous.database import AsyncDatabase
|
||||
@@ -14,6 +15,7 @@ class MongoMaterialRepository:
|
||||
def __init__(self, db: AsyncDatabase, prefix: str = ""):
|
||||
# 集合名前缀用于测试隔离
|
||||
self._materials = db.get_collection(f"{prefix}materials")
|
||||
self._field_groups = db.get_collection(f"{prefix}material_field_groups")
|
||||
|
||||
async def load_all(self) -> ComponentCatalog | None:
|
||||
# 没有元数据记录视为尚未导入,由调用方决定回退方式
|
||||
@@ -21,33 +23,42 @@ class MongoMaterialRepository:
|
||||
if meta is None:
|
||||
return None
|
||||
documents = await self._materials.find({"_id": {"$ne": META_ID}}).to_list()
|
||||
components = [
|
||||
{key: value for key, value in item.items() if key not in ("_id", "order")}
|
||||
for item in sorted(documents, key=lambda item: item.get("order", 0))
|
||||
]
|
||||
groups = await self._field_groups.find({}).to_list()
|
||||
return ComponentCatalog.model_validate(
|
||||
{
|
||||
"version": meta["version"],
|
||||
"components": components,
|
||||
"components": _ordered(documents),
|
||||
"field_groups": _ordered(groups),
|
||||
}
|
||||
)
|
||||
|
||||
async def replace_all(self, catalog: ComponentCatalog) -> None:
|
||||
# 整体替换目录,供导入脚本使用;order 保持导出文件里的组件顺序
|
||||
documents = [
|
||||
{
|
||||
**component.model_dump(mode="json", by_alias=True),
|
||||
"_id": component.key,
|
||||
"order": index,
|
||||
}
|
||||
for index, component in enumerate(catalog.components)
|
||||
]
|
||||
await self._materials.delete_many({})
|
||||
if documents:
|
||||
await self._materials.insert_many(documents)
|
||||
# 整体替换目录,供导入脚本使用;order 保持源文件中的顺序
|
||||
for collection, items in (
|
||||
(self._materials, catalog.components),
|
||||
(self._field_groups, catalog.field_groups),
|
||||
):
|
||||
await collection.delete_many({})
|
||||
if items:
|
||||
await collection.insert_many(_documents(items))
|
||||
await self._materials.insert_one({"_id": META_ID, "version": catalog.version})
|
||||
|
||||
|
||||
def _documents(items) -> list[dict]:
|
||||
# 记录 _id 为物料或分组的 key
|
||||
return [
|
||||
{**item.model_dump(mode="json", by_alias=True), "_id": item.key, "order": index}
|
||||
for index, item in enumerate(items)
|
||||
]
|
||||
|
||||
|
||||
def _ordered(documents: list[dict]) -> list[dict]:
|
||||
return [
|
||||
{key: value for key, value in item.items() if key not in ("_id", "order")}
|
||||
for item in sorted(documents, key=lambda item: item.get("order", 0))
|
||||
]
|
||||
|
||||
|
||||
async def warm_material_cache(db: AsyncDatabase | None) -> ComponentCatalog | None:
|
||||
"""启动时把物料目录从 MongoDB 载入进程缓存;未启用或尚未导入时目录为空,不回退读文件"""
|
||||
catalog = await MongoMaterialRepository(db).load_all() if db is not None else None
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
"""物料字段 MCP 服务:只给 agent 的模型查询组件有哪些字段、字段含义和可取值
|
||||
|
||||
只监听本机,由应用启动时拉起,不对外暴露;查询逻辑在 app.resources.material_fields,
|
||||
动作校验在主进程直接调用同一套逻辑,这里只是给模型使用的入口
|
||||
|
||||
单独运行:uv run python -X utf8 -m mcp_servers.material_server
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from typing import Annotated, Any
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from loguru import logger
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from pydantic import Field
|
||||
from pymongo import AsyncMongoClient
|
||||
|
||||
from app.config import settings
|
||||
from app.resources import material_fields
|
||||
from app.schemas.component_resource import ComponentCatalog
|
||||
from app.services.material_mongo import MongoMaterialRepository
|
||||
|
||||
_target = urlsplit(settings.mcp_material_url)
|
||||
mcp = FastMCP(
|
||||
"materials",
|
||||
host="127.0.0.1",
|
||||
# 由应用拉起时通过 PORT 传入,单独运行时取配置地址中的端口
|
||||
port=int(os.environ.get("PORT") or _target.port or 8201),
|
||||
streamable_http_path=_target.path or "/mcp",
|
||||
# 工具只读且无会话状态,每次调用独立处理
|
||||
stateless_http=True,
|
||||
)
|
||||
|
||||
# 启动时从 MongoDB 载入,与主进程读取同一份目录;返回结果带版本,主进程据此核对
|
||||
_catalog: ComponentCatalog | None = None
|
||||
|
||||
ComponentType = Annotated[
|
||||
str, Field(description="物料类型,即大屏节点的 type,例如 bar-chart")
|
||||
]
|
||||
|
||||
|
||||
def _require_catalog() -> ComponentCatalog:
|
||||
if _catalog is None:
|
||||
raise RuntimeError("物料目录未载入")
|
||||
return _catalog
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def list_field_groups(component_type: ComponentType) -> dict[str, Any]:
|
||||
"""列出物料的字段分组:每组管什么、包含哪些字段名称
|
||||
|
||||
先看分组目录,再用 get_fields 查看相关分组的完整字段定义
|
||||
"""
|
||||
return material_fields.list_field_groups(_require_catalog(), component_type)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def get_fields(
|
||||
component_type: ComponentType,
|
||||
group_keys: Annotated[
|
||||
list[str], Field(description="要查看的分组 key,可一次传多个", min_length=1)
|
||||
],
|
||||
) -> dict[str, Any]:
|
||||
"""查看分组内的完整字段定义:路径、含义、值类型、可选值、取值范围和默认值
|
||||
|
||||
修改组件属性只能使用这里返回的字段路径,值须符合字段的类型和取值约束
|
||||
"""
|
||||
return material_fields.get_fields(_require_catalog(), component_type, group_keys)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def search_fields(
|
||||
component_type: ComponentType,
|
||||
query: Annotated[
|
||||
str, Field(description="用户对属性的说法,例如“名字”“柱子颜色”“数值标签”")
|
||||
],
|
||||
) -> dict[str, Any]:
|
||||
"""按名称、别名、路径和说明搜索字段,按相关度返回完整字段定义
|
||||
|
||||
用户的说法对不上分组时使用;多个结果时根据字段说明判断用户指的是哪一个
|
||||
"""
|
||||
return material_fields.search_fields(_require_catalog(), component_type, query)
|
||||
|
||||
|
||||
async def _load_catalog() -> ComponentCatalog:
|
||||
if not settings.mongodb_uri:
|
||||
raise SystemExit("未配置 MONGODB_URI,物料字段服务无法载入目录")
|
||||
client = AsyncMongoClient(settings.mongodb_uri, serverSelectionTimeoutMS=5000)
|
||||
try:
|
||||
catalog = await MongoMaterialRepository(client[settings.mongodb_db]).load_all()
|
||||
finally:
|
||||
await client.close()
|
||||
if catalog is None:
|
||||
raise SystemExit("materials 集合尚未导入,物料字段服务无法载入目录")
|
||||
return catalog
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_catalog = asyncio.run(_load_catalog())
|
||||
logger.info(
|
||||
"物料字段服务已载入 {} 个物料,版本 {}",
|
||||
len(_catalog.components),
|
||||
_catalog.version,
|
||||
)
|
||||
mcp.run(transport="streamable-http")
|
||||
@@ -16,4 +16,6 @@ dependencies = [
|
||||
"pymongo>=4.17.0",
|
||||
"langgraph-checkpoint-mongodb>=0.5.0",
|
||||
"httpx>=0.28.1",
|
||||
"mcp>=1.28.1",
|
||||
"langchain-mcp-adapters>=0.3.0",
|
||||
]
|
||||
|
||||
@@ -51,6 +51,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "26.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backoff"
|
||||
version = "2.2.1"
|
||||
@@ -69,6 +78,104 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "2.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/d2/16d99a0c4948febc0ebd133a13b2f688ff7f8cb04da971e1128872ce0c03/cffi-2.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12", size = 183838, upload-time = "2026-08-03T21:19:29.637Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/95/31b535a9f0220ae9f357de4a08d57ce89cb417653c2fd9f075f50822a388/cffi-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1", size = 184168, upload-time = "2026-08-03T21:19:30.764Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/5a/4707a0dc1f203f5dde5a907b0d4e3c25d71120241048bd5bc6f1bb9d4e71/cffi-2.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0", size = 211805, upload-time = "2026-08-03T21:19:31.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/66/c19feabb28485b6e0bbaaafa90837a1ef5d302e90f2178bd33f17a49879b/cffi-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813", size = 218716, upload-time = "2026-08-03T21:19:32.896Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/92/500760486c8baab49a7a8a58ba7fc3355ec3974b454b8a09e528efde9e1d/cffi-2.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990", size = 205569, upload-time = "2026-08-03T21:19:34.142Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/a7/a67c733254d6e7373f7822f8082d8d6beade791e0cf12a7611f376fa61c7/cffi-2.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af", size = 204907, upload-time = "2026-08-03T21:19:35.174Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/a4/4399daaf8f7dfee9d7c3327fdb0426ee041cc63edc358b93911ceb2bfc7a/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632", size = 217807, upload-time = "2026-08-03T21:19:36.286Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/f7/dabe6da2466ecbd82dc62e7342dc6b1065dad990c06f00f0ede9ebf2a0ed/cffi-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd", size = 221252, upload-time = "2026-08-03T21:19:37.416Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/87/616202d8e51342c07d2534c510111c4cc37201775ce8f60802c9335d1edd/cffi-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a", size = 214214, upload-time = "2026-08-03T21:19:38.507Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/c6/ab025d75d2c26c19b087c0124e75ee31cb65032f4fe345d356d8c507ab97/cffi-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa", size = 219408, upload-time = "2026-08-03T21:19:39.809Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/e2/7e8109f65445bdc673a7b54f02c677de462db75674220fd1335efc8eb598/cffi-2.1.1-cp311-cp311-win32.whl", hash = "sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3", size = 174470, upload-time = "2026-08-03T21:19:41.246Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/c0/77ba02423c2f7d7091143c45cd49e0e6575c4c1967394bb542bd923a9b74/cffi-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0", size = 185096, upload-time = "2026-08-03T21:19:42.615Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/47/9f1f85f9672ceda4984dc6c4f8824e8558992a2972c3d3c81fb8eb28d4ba/cffi-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455", size = 179941, upload-time = "2026-08-03T21:19:43.747Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/69/43965eccfdead3b9220015fd1320e117be8c6ed01a62ffab76eeb752f5d5/cffi-2.1.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0", size = 184821, upload-time = "2026-08-03T21:19:44.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/7d/16e5a096677b5e313ca80cd5e5170efa3ea44624a82bb111925522da64b1/cffi-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf", size = 184719, upload-time = "2026-08-03T21:19:46.129Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/e6/8941622732edec876dd17d0453dce07317ae96db34f2ec1436c9d3785986/cffi-2.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a", size = 214799, upload-time = "2026-08-03T21:19:47.218Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/de/f98430906df1545ffde0d543dd124a7a439bc2cd32b36b9c53f805df7333/cffi-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890", size = 222389, upload-time = "2026-08-03T21:19:48.331Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/5b/717f1526b9957b34456313c31645c5b82b8fb5c3fe9e4752999be7128bfc/cffi-2.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50", size = 210249, upload-time = "2026-08-03T21:19:49.543Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/b3/f8aa4f3e34986c7e4ec45072d1b1b9dd295b6b18007b45518d79726dd725/cffi-2.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e", size = 208775, upload-time = "2026-08-03T21:19:50.918Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/db/dceb9dd5b231e1da801793f8acc9f3c52a7e1afe40bb1aae37e02b0faad5/cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf", size = 221822, upload-time = "2026-08-03T21:19:52.054Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/d2/6cd24ae3be000a634109c247d1475d62e5616d0dc78c82770942ec384248/cffi-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517", size = 225232, upload-time = "2026-08-03T21:19:53.109Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/52/3fa190537004dd7f0ab860a6dc7c0175b8667f68d1e618a46f5498d30250/cffi-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735", size = 223597, upload-time = "2026-08-03T21:19:54.515Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/fb/0bb75b7039588c074b37ae99f40d9bfddf990ecb2fbc346ebccd2e56b9be/cffi-2.1.1-cp312-cp312-win32.whl", hash = "sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e", size = 175292, upload-time = "2026-08-03T21:19:55.566Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/79/615cc094e2fb508cade7de88d3b4f6c4ec2bab695c97bce9153dc65aadf5/cffi-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a", size = 185919, upload-time = "2026-08-03T21:19:56.89Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/c6/d0ea84713fe46b243a436a18fcd47d639732747e21635c8a27191b06dc30/cffi-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80", size = 180093, upload-time = "2026-08-03T21:19:58.155Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/7b/d6bbf82b8b96e7391438898c42f5bd96dd02030fd5b64937d248220003e2/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c", size = 194064, upload-time = "2026-08-03T21:20:17.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/e6/bcc91b283be94735e268487a054004f0aa19947b6348fa367db53230abc8/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb", size = 196720, upload-time = "2026-08-03T21:20:18.268Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/99/c4b0c17cacdc9c3b8f280026286a9826d6a208c0f047591a3c3ce99b91fd/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54", size = 184964, upload-time = "2026-08-03T21:20:19.708Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/a9/9db617d05d7367c1ad0ab00b3aa6e6f9281edd689b4ee9ea0e5a84e89c97/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72", size = 184962, upload-time = "2026-08-03T21:20:20.833Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/b8/b42132ca113dc567d37684437b46ca1dafc885902b02a110a02d5b511857/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1", size = 222328, upload-time = "2026-08-03T21:20:22.118Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/10/c5c0cbf0a657aecf59ef511409734230bf556f05a0d6c9eed7aa5c0a0166/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062", size = 209985, upload-time = "2026-08-03T21:20:23.401Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/6c/bfa0b87b03b9238148beca990292843c9396ba069b54496596594173de7b/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03", size = 208530, upload-time = "2026-08-03T21:20:24.628Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/02/4e7d553a7ac4b4238b38b3c1b80d486e9d4436f8d2acbf87a0997fe3f402/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96", size = 221525, upload-time = "2026-08-03T21:20:25.758Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/1d/a4aaf9babd75acb4d5f223bff71533bee748dd770a382619a798960ee9ba/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527", size = 225053, upload-time = "2026-08-03T21:20:26.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/10/5dc0e7bdd18e22107054288283380fc97a06ae3f1656a106908d666a3c88/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13", size = 223213, upload-time = "2026-08-03T21:20:28.277Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/e9/d0061c364cde06ee43168a0d076ac1da512cbc380d44767b844ba34fe2b6/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c", size = 177682, upload-time = "2026-08-03T21:20:44.288Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/06/1c3e01e3ba14c39f6d10bfbac52753b7e22259e38088e5cfe1d704918690/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48", size = 187949, upload-time = "2026-08-03T21:20:45.623Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/5b/da4e39efe18eeb89cf580ea9cfc66b6a7c3eadb808fc0cc1d3a295cb5a5d/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836", size = 182947, upload-time = "2026-08-03T21:20:46.955Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/59/40338bf421c5accea1d45158170c87006ef1cd371b05c077e76476949728/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3", size = 188504, upload-time = "2026-08-03T21:20:29.495Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/47/5ecf1023850036e674c77ec4de86182d309ae344e39e7cba984b7df5d647/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2", size = 188259, upload-time = "2026-08-03T21:20:31.291Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/9c/92934c3bea9f785b23eba304538c0b4d37a2a96d2431eb3a1bc87a11aa19/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94", size = 223864, upload-time = "2026-08-03T21:20:32.571Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/45/ba4c93527bc38616a8bd36488acb69a2212d60486794f0c1f318949bbb76/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc", size = 211538, upload-time = "2026-08-03T21:20:33.808Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/e9/b6ef565e452acb932fb0cb5443f44a78efbd1233e566f02b5a83855e9115/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29", size = 210688, upload-time = "2026-08-03T21:20:34.974Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/95/eff5f0cee78d2eabc7eebffec40d3fc1876b5f3c95582e018bb4b99601f2/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676", size = 223803, upload-time = "2026-08-03T21:20:36.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/01/579d39fb8bef00a335a23d83757b44feb24cd6345a2c451b64cb67b9c362/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e", size = 226763, upload-time = "2026-08-03T21:20:37.816Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/b0/0b44f47c60b01b57b6e2bbd92343f13a85a1d93bc46ccf6e47e244acd99c/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f", size = 225688, upload-time = "2026-08-03T21:20:38.959Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/d2/3b7176cb570a1d3e27faf67b72f591af508036e0d8b2be2ef9af9e8c84bb/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4", size = 182868, upload-time = "2026-08-03T21:20:40.388Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/78/31f00c1bcd97c9bbf55f1bfdf5bc809a5de8887473e90bb9960dca825e80/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e", size = 194104, upload-time = "2026-08-03T21:20:41.725Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/1b/58496f2ed0a35de575250c02a43ab3cc2c04d494a88fed31c1cabc0fd176/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5", size = 186402, upload-time = "2026-08-03T21:20:43.042Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/8f/9ebe220eab48a093d1a5a5e339ab0dc7316eef3bb04d63c42f0251b61f50/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d", size = 194043, upload-time = "2026-08-03T21:20:48.179Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/69/844bad3ece306c4782c2ecb93597035b6690d48704b803914c199da1e8b3/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b", size = 196737, upload-time = "2026-08-03T21:20:49.457Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/8a/af668013284634733f02d683458a0728739c7d6ddb5e14cb0c20832266fe/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4", size = 184933, upload-time = "2026-08-03T21:20:50.639Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8", size = 185002, upload-time = "2026-08-03T21:20:52.173Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/31/9e1313b0a6e30e91b3b3d3fff51ae99c857c07738e3afcce1f7334e1b7ab/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6", size = 222271, upload-time = "2026-08-03T21:20:53.462Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/e3/f6234a833e6e08c7007003074723c406559eecf9b48dfc97471e5a8eb7a0/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80", size = 209919, upload-time = "2026-08-03T21:20:54.783Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/fc/5f74e293fced6edb51af3a46c4ccf6c23c9943774ecb375ddbd522c76add/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779", size = 208529, upload-time = "2026-08-03T21:20:56.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/16/29e6d01b388bef055ecd6ca8244b3f4d336bd09e92d5d892187b9601084e/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399", size = 221630, upload-time = "2026-08-03T21:20:57.336Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/18/fa7f1f6857d5eb88a4ca99ffcbfb7c387a287ccc154c64a73e86314745d7/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688", size = 225134, upload-time = "2026-08-03T21:20:58.675Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/9f/e8e3dfa04a1b4c241f8c91faacad872b4d4efd051d49764ad4e2fd4b9fea/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7", size = 223197, upload-time = "2026-08-03T21:20:59.968Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/7e/8debeb04f1ab9fe2a6963964cd6f1aaf7192627b83926586a6a4e089c9fa/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac", size = 177683, upload-time = "2026-08-03T21:21:14.901Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/31/5158704cc474ab65c1647932e88be78dc0873f47130e253be38bcaf13d01/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960", size = 187897, upload-time = "2026-08-03T21:21:16.108Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/4b/b3a2da8570c704ffc0f9762cdc3ec0f02c8573798e0b5cf7f11c82bbb70f/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1", size = 182935, upload-time = "2026-08-03T21:21:17.271Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/ef/5443574510a1207e6f6bc38ba6e1f1de36cb48fef07b2728bb896a21f430/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc", size = 188464, upload-time = "2026-08-03T21:21:01.163Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/ae/a56fa8c4686ad50e148fcbc8d3ae0d03915ff5c30d795058988c24118cef/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab", size = 188262, upload-time = "2026-08-03T21:21:02.382Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/b2/6187f46f2912276a3ae284076109cc5c8680482f11f766ccf26db4a86427/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e", size = 223779, upload-time = "2026-08-03T21:21:03.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/f6/c3ad28bd19f77047a03084424fbd4cbe997303267c14423737324be0385d/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358", size = 211520, upload-time = "2026-08-03T21:21:04.863Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/cd/ccac9013a5bd9fd764de118674ab9c805b5ca10c19270d90ee273f8b2240/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231", size = 210673, upload-time = "2026-08-03T21:21:06.223Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/86/2976131c639aead931c5bee5aba67e4b09fbeb8018b6f282f70803f923a7/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6", size = 223835, upload-time = "2026-08-03T21:21:07.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/0c/33a7aeab2f9c76918c52e084beb39c570db3588133412929e8ec06fab90b/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94", size = 226705, upload-time = "2026-08-03T21:21:08.774Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/26/2cde30fdde421130bfc18f70395731a6e6b2053c6a1978a5258ff04e72fa/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5", size = 225539, upload-time = "2026-08-03T21:21:09.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/cd/a361394c94b2129d604bb846f624a8e88255a3ee33129c434a00d715e64f/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66", size = 182707, upload-time = "2026-08-03T21:21:11.226Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/b5/ba2b299993c26577d529b6ae29841f9e15b9fcf004d65f423f4fcf94ade9/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3", size = 193772, upload-time = "2026-08-03T21:21:12.39Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/29/35e016098c814cd93de9cd320c66b5bfba14dc6ecedd3cb518fa7c408c69/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692", size = 186360, upload-time = "2026-08-03T21:21:13.636Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.5.1"
|
||||
@@ -234,6 +341,75 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "50.0.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9d/af/182eb91b0df3fe75c4d9f26fe70684569566745f6ba7e5c9c73a862c5252/cryptography-50.0.2.tar.gz", hash = "sha256:7b46165bb56eb4704e2eaaf86f3c940d19154535d9b0ca7d6d590b04060e00d5", size = 880623, upload-time = "2026-09-30T15:30:04.884Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/56/d194340cc4a57535e82e1bee9e89667ac4b7c13b5d3f59686deae3094dd5/cryptography-50.0.2-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:fa8f5efb344d6908a1ce62f4a24e2e5780f825d6f53f5f50ec5ffacac72936cb", size = 3914904, upload-time = "2026-09-30T14:43:44.339Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/69/c9bd862c3bf43d6399c433caf002df16e2dffd4be49bdf515cda38038711/cryptography-50.0.2-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:79def8d059362e7831389ed3be0ecdf58a89386e1271e35dd9f5af84e81bffd0", size = 4731146, upload-time = "2026-09-30T14:43:47.113Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/69/64cef1f702bf6657e0cc186ed1a2891d50d29fb41586b254e1c07adea261/cryptography-50.0.2-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:630ebfea3bf689d075f82316324ff7433dc447fe6bc1bfc76524b74b4a9567d2", size = 4719841, upload-time = "2026-09-30T14:43:49.01Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/6b/61a3f8d8c5e1e49a6cddccafc4015cc1c0021360ab0acb4080e7a423644a/cryptography-50.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f9f6143a8c75945eb960d9eb98905a441394abfa24afaae239d514ffb2586480", size = 4738340, upload-time = "2026-09-30T14:43:50.932Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/2e/7212ca32fd43dc91f2f41db20160b268098874b4c9a0e7be94d6835f5b2e/cryptography-50.0.2-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:a582ab2ae1d34f67112cadc86702774c9ea4374df6bca6afe672817203c99134", size = 5367029, upload-time = "2026-09-30T14:43:52.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/f1/b474e930c4d910328780e3940da76f5aa5cbc48ce1fc14e44d239d9ea9db/cryptography-50.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4061c0079120205fb760c58acab6443e217307dcf05e3702cf970e0689972856", size = 4753050, upload-time = "2026-09-30T14:43:55.272Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/52/9af10e80ac16b0fcc2123f9cbd5e7afbd0fd5075bb7a607c592258a39cda/cryptography-50.0.2-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:ac9ed99d81760c62fe89d5f0815cdfa1ba9a35141cf30f1c2d044f04b4803d2e", size = 4376724, upload-time = "2026-09-30T14:43:57.24Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/37/6202e488cc1eb625ea110c292c6bda92823176e023f427d8d5660ce8d632/cryptography-50.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:87e9ce85beb6b328ba370cc6e6aea483c92617b4c95b1d33a49297eb662bfb04", size = 4737859, upload-time = "2026-09-30T14:43:59.541Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/30/e86d7d518489b0ae2497091a35287abcb1a2ce4037837a34afbe9b1d6964/cryptography-50.0.2-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:f265528741e048bce55c3463ed721fb0aa45a5888d8add8cfeccb3035451bbdc", size = 5324103, upload-time = "2026-09-30T14:44:01.901Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/69/2c833a049475e0a3444e94c7d0aca0aa51d166374a449b09e92ac98138de/cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9dab55f57c74c3cad24c323bacbbd04be4705ba6eb0d92e920b1fc4837ed5079", size = 4752576, upload-time = "2026-09-30T14:44:04.545Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/5d/906970b83bbfc1f5bbfb677a143c181f2801f23b6a7204a3b47c42c97e65/cryptography-50.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25784ce8b9621c90c643efb9e1e2162ab3b0224cae446ad5e70e7fcb1ce18b51", size = 4870819, upload-time = "2026-09-30T14:44:06.884Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/e3/f2298d3bb55e0c4a91841ec4d01b3f020ba8c5fbf15ccdcc6dcf03f97025/cryptography-50.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:85d0d9a31b9098e98534226d5686b47264b95e62ce459dc2e62fdfc809f9fe93", size = 5030152, upload-time = "2026-09-30T14:44:09.443Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/4f/adfc442765721292fff86d314ce385d3249d22db42295c0dd057727b60f3/cryptography-50.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7afa5a6602a9f29af1f3a2965f831bae7c9d5d597b7cbb716d41ab3b7d89879c", size = 3824692, upload-time = "2026-09-30T14:44:11.671Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/cb/52eb3770c0d0be2702a98c6e96065ddc0a2877cf0845aa9c23397c142cd4/cryptography-50.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f785f6161f202ab04d8ca194158968798e480ca058943907972da5f12e2881e8", size = 3892731, upload-time = "2026-09-30T14:44:13.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/8e/aa1fc533d4546b127b45de8aa024eb5933d23eff9debfe25931e56861095/cryptography-50.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0ecbc5652bdb6fc9eaf89a7d196e20941adfe812f43bc4ca05d9150496821047", size = 4710431, upload-time = "2026-09-30T14:44:15.427Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/64/72bc3f75176e7e406b748a3e3830432b8c51297b38368713df04dc04898a/cryptography-50.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ab50ee449bf968271e820086f10a33d101dd060370abc10bcd22279be2656539", size = 4694824, upload-time = "2026-09-30T14:44:17.69Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/c6/62c77550edfa5ca3f14bf44a1e6739b9fa09d6e998a11d97ed8213bccc98/cryptography-50.0.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a9f7355e6fab51f6c369b86fb7571cffa05edee2c2121e0380a37fb9ac1cd5c1", size = 4716967, upload-time = "2026-09-30T14:44:19.661Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/37/cce70f150c432914460157a6ecc161752e053aa5ec0ef3b3f7dc6e31039a/cryptography-50.0.2-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:94e5e9f108ee10471288214d3d233fbfbb492840a8457eb85178d643ddeb32c7", size = 5328676, upload-time = "2026-09-30T14:44:21.744Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/9a/6f2f0304d634ceafdeaf23e84537336664ac419b5d07611675c2ad3f6b7a/cryptography-50.0.2-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:241449bf940a5d27309bd317e6f9a2af6932113818bb2b8f5c59ddc7ef16da18", size = 4727698, upload-time = "2026-09-30T14:44:24.178Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/de/66bcf9244d118663b2e1aaded8990f4640e3d7b7411870a5765f252074d2/cryptography-50.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d8947001be83df1394050758ce0e745dd74fb134eef0a4b5124208dfc3a68c37", size = 4354821, upload-time = "2026-09-30T14:44:26.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/e6/db28a28c7b6c676addce89136de3d8db49ea825a8c863472e36e42ead4ad/cryptography-50.0.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4a20ce1e5cb4284a86692fdcba7cb8754185c6b2e5c56fcef3751cf451d3cdc2", size = 4716748, upload-time = "2026-09-30T14:44:28.447Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/96/01546c7f69ea0e2ab790a2e4f0934a4052fb9b388147fbf83c2fd72f1e57/cryptography-50.0.2-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:84f964e537f916e2cc85199e5a88742e964939b575ac8598b3f9d6cc416cdaf1", size = 5285085, upload-time = "2026-09-30T14:44:30.704Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/01/03263395f74d50b071e9e66daace3f8bef80493e5d410726f2ba8554736b/cryptography-50.0.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:828d49b0ff5a0e3975865571c5d91dbbdd0d38d8289b249a163e9425413a5e05", size = 4727268, upload-time = "2026-09-30T14:44:32.92Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/94/2bfe8f29ec0cc9c0d99359c4161adf32858e4934b72c6d100d2ac0bbe962/cryptography-50.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:deb9fde5c60e437ee4821bc9bc39ff31b42135c27e1dc61ef0a629389c1de62e", size = 4849503, upload-time = "2026-09-30T14:44:34.969Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/44/e80651ecbf0e42b62e2bb5f5768916e07eea72e1297338956a61df361f88/cryptography-50.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8c71ba2cd31fc93748c38e1b613200ff1c2665cbfd5341fe3a61cfde35a1430e", size = 5004057, upload-time = "2026-09-30T14:44:37.064Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/cc/1d33befb3cd7ea7e77d2d73f43f2066471da1b21f24a6156efcaabf6d2e8/cryptography-50.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:78198641e5be9521beea5aa782bb551a58068d10e6eb04c9c680c1b69f2e7d45", size = 3795868, upload-time = "2026-09-30T14:44:39.71Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/49/93f6a6e7a87c9aa68d44d3e1cdb5fe8f60c90d5d2f46acae9a56892816b8/cryptography-50.0.2-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:edc3342adf8f697fc5f59c887a304356f147b397809440ed64e2fa6af2f50f37", size = 4133708, upload-time = "2026-09-30T14:44:41.807Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/75/32ac2a56243d778805c16ca6a32b8f74fb757df7e28d7ecb560afafb59cf/cryptography-50.0.2-cp315-abi3.abi3t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d370b8d1dfcdf7130178137f6fbee6140774a1acc6cacefc4b42643ec11d0a3a", size = 4956267, upload-time = "2026-09-30T14:44:43.693Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/a4/2c8d734e43d97f0842ee9f1b7b4bfb3d0cf5e19edebf43c2afe6675c2320/cryptography-50.0.2-cp315-abi3.abi3t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f2f9bd7f90c64fe89253f0a2c05e3c4856072660429ce8831b4235bf29403a67", size = 4966465, upload-time = "2026-09-30T14:44:45.769Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/58/ee288c829a6f41f6235ae9dd33d82fd19b45442b65b4c8a3da36963d9f7a/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_aarch64.whl", hash = "sha256:e275096ea1e60cc595cda2836fd4a6c725d1125108b868be17f53684d164e2cc", size = 4959356, upload-time = "2026-09-30T14:44:48.211Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/20/9ded6d51ddd9897f6b6e81fb9ebea7951d7cc5d6c890b0ed8abf77a51a80/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_ppc64le.whl", hash = "sha256:b13478603dcd0a2479ff8e87e2c19a7d525734686fe3c49542472293a204212d", size = 5548822, upload-time = "2026-09-30T14:44:50.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/a8/8df951850d6b31d2a00218f19e2b3f999523437ed7a819df7fa427942fca/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_x86_64.whl", hash = "sha256:58a0c478eeca76fe5e07993c5a0703def34a6dc6a0cda4f5564639b33112ffe7", size = 5001199, upload-time = "2026-09-30T14:44:53.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/f9/36b3022218ce75b7cdf068fb95f809f9bd0d820e4955ef43b90c255cc7ac/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_31_armv7l.whl", hash = "sha256:d38cdff612d06fa6a32840d5e1b1f7a27cee4a349aa9085d94a67789d6bfd408", size = 4629333, upload-time = "2026-09-30T14:44:55.635Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/72/20f99a219f6af47cdd1cbd978c243b92d71496e168a746138af44ded4f29/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_aarch64.whl", hash = "sha256:fdd28f912fccfec1846a94e2e1e8f9b0012f557f0c46fe4f3eb0d7a87afcf90b", size = 4958822, upload-time = "2026-09-30T14:44:59.639Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/20/196f112617fb08eb4d608a2a6c422373d46f9cc2857f38fc0667033c0899/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_ppc64le.whl", hash = "sha256:cbc8738fd8526d80f35cb3a40d41f41a2e7030bb3b18b09a6778ef63d291c2fd", size = 5506351, upload-time = "2026-09-30T14:45:02.267Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/95/83378121ef3eaaaf71d4b781577ff794acb39b9e1b87a3f156898c8497ed/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_x86_64.whl", hash = "sha256:e105ab60406787da31fccc883fc0f733af1efd78f0136a4599692c4083a73d0c", size = 5000859, upload-time = "2026-09-30T14:45:05.009Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/f7/70fd7ae4d1dbfa7ba29b02e1b9068771519a86027756510b700ce81086a8/cryptography-50.0.2-cp315-abi3.abi3t-musllinux_1_2_aarch64.whl", hash = "sha256:6f8700550aa1474a91e5dc07049c46f98b423b5b1ddd0483e0b51362eeeaf5be", size = 5092151, upload-time = "2026-09-30T15:29:15.932Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/be/688367b74de86984bd58d8efacfc7c9e68b89a6a22ced0fb4f38db50254a/cryptography-50.0.2-cp315-abi3.abi3t-musllinux_1_2_x86_64.whl", hash = "sha256:c71be1cbfa5cd9a41ee452acf1eccd82b2c05950358b106ec8ceb83411d1a020", size = 5286120, upload-time = "2026-09-30T15:29:18.309Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/d1/55f8a3f2ef5d1529e16835ef10cf0fe3d559ce237b46dddc440c0bba3649/cryptography-50.0.2-cp315-abi3.abi3t-win_amd64.whl", hash = "sha256:c423ab384a46c4dff7217b2ea5ba2e11cffdeab6441acd04cf65a369caf0366c", size = 4111557, upload-time = "2026-09-30T15:29:20.155Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/ad/ac987755d00e1e64273760228d2635ae38dae2be83e3c6e0d3289d91dec3/cryptography-50.0.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:0ec5f09541743261e66e291b4a0cbf0fb2997aeaab6d9e9c740b9dba1b58d1c2", size = 3943588, upload-time = "2026-09-30T15:29:22.265Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/8d/6d585339bedf85d45044c85d8412dac53f2bb6f918e8b7777efba1787844/cryptography-50.0.2-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c5e67125c7dca78d199ec4e116aa93dbb83494808ecbb8211a2cb09b1bf41dbd", size = 4756166, upload-time = "2026-09-30T15:29:24.58Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/f1/1c1f6874e8550cfddd4b688ceb38cefb6ed15ceed224d56f133f3d88c214/cryptography-50.0.2-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee247f5c245c9a2fe7c8e2214e295918838e44e00a45a6718451e4004219e767", size = 4749145, upload-time = "2026-09-30T15:29:26.807Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/63/61b15dc1a8de03fe0adbe3fd7608b3ad5c73bf50993bbcb1faaa930afe33/cryptography-50.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dfe9763530994147d9af1def057a5b9658b00e8f8fe8743d144d1e0911c2e454", size = 4763638, upload-time = "2026-09-30T15:29:28.588Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/35/b345bdfa40c9126df1a9d33236aa98418367931b8725f84fc3ae2b98dc59/cryptography-50.0.2-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:58ddb5a8e3179d12f19e4ea34d2d32e9d63a4baa142c875c1eb59f41b7243acd", size = 5382217, upload-time = "2026-09-30T15:29:30.589Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/87/ef344a9e616871f2519c22d6afcda79ddd5d35e9592d95eb6e677608d055/cryptography-50.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f21e8a22c8605750c7af886bab299a363721264061b4ac0a30efb73cfd58efc5", size = 4781387, upload-time = "2026-09-30T15:29:32.605Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/5b/f2fdb13cd0b96f6f932c8627bb292a45f11c64d21620a8e120aee9a3b848/cryptography-50.0.2-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:9c8402a82ea0dc4ceeab793db05f0fafa8ca139ca34fcde5df0f596103c74107", size = 4403790, upload-time = "2026-09-30T15:29:34.374Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/ce/7e4f662b1e3c393513569e402cfc85ac7da0bd3d5435e122a3140219eb2d/cryptography-50.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:0ddc924c04591c2811ca024d62ecad4f7f6f08af8939c211438f48a16bd23602", size = 4764319, upload-time = "2026-09-30T15:29:36.149Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/3f/86ff33ce34cc0de6847fb96e035a1a760d81652e38643f617c02ad32ef7a/cryptography-50.0.2-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a6557e5f38e065ca9fbdaf7cfc7435ecb1d113aa81a022d1b51921ee7432e227", size = 5338560, upload-time = "2026-09-30T15:29:39.053Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/cf/6b5c8e2fd9202d98988ab7cb5cc5c991704c4ad55f492ff408e4969f83f1/cryptography-50.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:1981f1db4630889b9ef7803fadef12b056f428cb6b85c27ba57b774793b6093c", size = 4780973, upload-time = "2026-09-30T15:29:41.251Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/bf/8d6ebc7dded797bd0f0160d52188021211f011a2b164ef0ae1dac4587465/cryptography-50.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7a8701d6b584d76e909e3d305b7d126b41439876a5aaf76cddc67fc230eafa2e", size = 4897738, upload-time = "2026-09-30T15:29:43.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/aa/f3f6e0de7e6253b8baa8b2d8fb9d50924fa75cee3d4624bd4bc1208ee923/cryptography-50.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce47f66801c20ec6c6632453bb5960fe38939e9306970b48b3a5a26de7745d94", size = 5058280, upload-time = "2026-09-30T15:29:44.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/b6/a1faf3a27ae9405fb34b1713cc73b2d8a26b04d5c561578fa2e6ef3e5bb9/cryptography-50.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:4e81d95e5bafc2d6e34e4bed780e53e4d5b9a2f928573428aa4d35fbec1eb0de", size = 3854095, upload-time = "2026-09-30T15:29:46.782Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/7a/f08d34ce09d60f89ebd391e2ebc6ba2b995e6dd7552f41820f8085f94e53/cryptography-50.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:92e665960f25fcdc73725b9cec7a3824f279ba97a98653afe9ffac2e43668f67", size = 4716035, upload-time = "2026-09-30T15:29:48.681Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/67/e18fb65592451a2acb76e9f2fbe14e0f47a8318b4c5430f1633851d03daa/cryptography-50.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eef4c2f3423810b3070ab391f85436d2f8bbfcb286ac15cbc73190b3563b1f1a", size = 4726917, upload-time = "2026-09-30T15:29:50.608Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/28/38fdce17e60f6b825e69fc3b7f75e70a6612759980704697e1de4cbfaf6e/cryptography-50.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:7c6d0330c472d96f6a6afe24d80dfdf15176c33096f0a4397ae4c60f3dd3be48", size = 4715341, upload-time = "2026-09-30T15:29:52.522Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/b1/d9121a717e0f893c64bd6ca7702614778d7df2a5c309128a002421788516/cryptography-50.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:1ba34f04897fcdaa73f74145c25f3ec146fbd56593853e88adc2e811303c5f42", size = 4726322, upload-time = "2026-09-30T15:29:54.263Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/8b/e6d153808bf353e152abd2fd4d8f09670d956ac78379ac46e60d7efbf04c/cryptography-50.0.2-pp311-pypy311_pp80-macosx_11_0_arm64.whl", hash = "sha256:3dc4fd8058cea1644971207d530e1a03a184a805ffc8ebdddf0599d78a331b81", size = 3873097, upload-time = "2026-09-30T15:29:56.097Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/1d/1271f287ff7170ddafc2aad36260c4eec20ccd2fea70f38455e9d56d427b/cryptography-50.0.2-pp311-pypy311_pp80-win_amd64.whl", hash = "sha256:7b75de3c8b3be1cdb1052747c929440c3eea46c1bc2cb8a6e3a48388e9b7b452", size = 3805376, upload-time = "2026-09-30T15:29:58.729Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "detect-installer"
|
||||
version = "0.2.1"
|
||||
@@ -582,6 +758,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx-sse"
|
||||
version = "0.4.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0f/4c/751061ffa58615a32c31b2d82e8482be8dd4a89154f003147acee90f2be9/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d", size = 15943, upload-time = "2025-10-10T21:48:22.271Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx2"
|
||||
version = "2.13.0"
|
||||
@@ -763,6 +948,33 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659, upload-time = "2026-03-23T22:32:31.568Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "4.26.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
{ name = "jsonschema-specifications" },
|
||||
{ name = "referencing" },
|
||||
{ name = "rpds-py" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema-specifications"
|
||||
version = "2025.9.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "referencing" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langchain"
|
||||
version = "1.4.2"
|
||||
@@ -816,6 +1028,20 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/18/cf18cfec118b02e003f35300b54d6a1173dc6e4905cffdf5ea49e390a7f9/langchain_core-1.6.3-py3-none-any.whl", hash = "sha256:114fe1868c9ed60606662b9dd0074bf3152cc6b0b1522ba37cbd6b04f55ca77d", size = 571753, upload-time = "2026-09-11T17:37:43.875Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langchain-mcp-adapters"
|
||||
version = "0.3.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
{ name = "mcp" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/05/49/f3b8497b64024ab50d10011f27e94d149668fef754da74c1c2ce6ebe4a30/langchain_mcp_adapters-0.3.2.tar.gz", hash = "sha256:61cd1a09597adb619a9bafb0642938ffc2a9463d699a753f7af0420ea46c381a", size = 47129, upload-time = "2026-08-06T06:15:04.094Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/5e/4f117d2500a661079a1895a6eb18954a906e458b1e45fa04a301fcdabd61/langchain_mcp_adapters-0.3.2-py3-none-any.whl", hash = "sha256:094e6b3096dbcc408417d5722f6915f164772e50c502ae3d8989405bf12c3c84", size = 28879, upload-time = "2026-08-06T06:15:02.832Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langchain-mongodb"
|
||||
version = "0.12.1"
|
||||
@@ -1102,6 +1328,31 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mcp"
|
||||
version = "1.30.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "httpx" },
|
||||
{ name = "httpx-sse" },
|
||||
{ name = "jsonschema" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "pydantic-settings" },
|
||||
{ name = "pyjwt", extra = ["crypto"] },
|
||||
{ name = "python-multipart" },
|
||||
{ name = "pywin32", marker = "sys_platform == 'win32'" },
|
||||
{ name = "sse-starlette" },
|
||||
{ name = "starlette" },
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-inspection" },
|
||||
{ name = "uvicorn", marker = "sys_platform != 'emscripten'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/93/0142dc84a666daf8ad51a34268f34c12fd6fda4f3810c4be2504eecc8212/mcp-1.30.0.tar.gz", hash = "sha256:445414625fce5c295faa505bb11bacece661ab6f4028d57c935db57820b7a3e4", size = 680511, upload-time = "2026-09-07T14:34:15.845Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/f4/e58bc33317c92a0203664daaf00bf6f41166cc0149e5d6870a03f7cd004a/mcp-1.30.0-py3-none-any.whl", hash = "sha256:666edb5009503e1047c9d60346a756f94b261f05cc2625f23d41c728ffc484d0", size = 234581, upload-time = "2026-09-07T14:34:14.266Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
@@ -1119,11 +1370,13 @@ dependencies = [
|
||||
{ name = "fastapi", extra = ["standard"] },
|
||||
{ name = "httpx" },
|
||||
{ name = "langchain" },
|
||||
{ name = "langchain-mcp-adapters" },
|
||||
{ name = "langchain-openai" },
|
||||
{ name = "langfuse" },
|
||||
{ name = "langgraph" },
|
||||
{ name = "langgraph-checkpoint-mongodb" },
|
||||
{ name = "loguru" },
|
||||
{ name = "mcp" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "pymongo" },
|
||||
{ name = "python-dotenv" },
|
||||
@@ -1136,11 +1389,13 @@ requires-dist = [
|
||||
{ name = "fastapi", extras = ["standard"], specifier = ">=0.141.1" },
|
||||
{ name = "httpx", specifier = ">=0.28.1" },
|
||||
{ name = "langchain", specifier = ">=1.4.2" },
|
||||
{ name = "langchain-mcp-adapters", specifier = ">=0.3.0" },
|
||||
{ name = "langchain-openai", specifier = ">=1.6.2" },
|
||||
{ name = "langfuse", specifier = "==4.15.6" },
|
||||
{ name = "langgraph", specifier = ">=1.2.12" },
|
||||
{ name = "langgraph-checkpoint-mongodb", specifier = ">=0.5.0" },
|
||||
{ name = "loguru", specifier = ">=0.7.3" },
|
||||
{ name = "mcp", specifier = ">=1.28.1" },
|
||||
{ name = "pydantic", specifier = ">=2.13.5,<3" },
|
||||
{ name = "pymongo", specifier = ">=4.17.0" },
|
||||
{ name = "python-dotenv", specifier = ">=1.2.3" },
|
||||
@@ -1574,6 +1829,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/04/d52c7016b04b6c5108f26691f9d33ec82a9b65d041f1a9c771137693d618/protobuf-7.36.2-py3-none-any.whl", hash = "sha256:bdb3a345d48db958e6ce1f18e508beb0cc981d64f24088427549c866cd039f1e", size = 179806, upload-time = "2026-09-17T20:07:58.211Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.13.5"
|
||||
@@ -1732,6 +1996,20 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyjwt"
|
||||
version = "2.15.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/43/ea/5194e52748b0da83d71e082d75496eaec6e58f419f5e184786ded517e6a9/pyjwt-2.15.1.tar.gz", hash = "sha256:4f259e80cdfb6b3fc18a7de51fd1ef9ec79652f25019bae68975ca2468a34df8", size = 121252, upload-time = "2026-09-28T18:40:42.598Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/50/ca/44de4e75f8aadc457f0634be3b542815078ded46dca30efb960edeecad6e/pyjwt-2.15.1-py3-none-any.whl", hash = "sha256:42d59d631f7768a1028a64c7ff581a9bf7519804daf91fc5b6c56e30eec5e193", size = 33860, upload-time = "2026-09-28T18:40:41.429Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
crypto = [
|
||||
{ name = "cryptography" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pymongo"
|
||||
version = "4.17.0"
|
||||
@@ -1823,6 +2101,28 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pywin32"
|
||||
version = "312"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/f5/10a6e845a00fc5e7afd0a988b744f403d4d57162a28d160a093c4d9322f0/pywin32-312-cp311-cp311-win32.whl", hash = "sha256:17948aeadbdb091f0ced6ef0841620794e68327b94ee415571c1203594b7215c", size = 6362659, upload-time = "2026-06-04T07:49:21.349Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/c4/dcd2d62b5944b6d5db53413a5899016ccd57ffcb7278f3f81655d25d2027/pywin32-312-cp311-cp311-win_amd64.whl", hash = "sha256:d11417d84412f859b722fad0841b3614459ed0047f7542d8362e77884f6b6e8a", size = 6928825, upload-time = "2026-06-04T07:49:23.934Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/56/3cbb433fe4501cdba2eb9040f56a4e1a8243faa4186b25295564d1a7a79d/pywin32-312-cp311-cp311-win_arm64.whl", hash = "sha256:b2200a054ca6d6625c4842fc56a4976a4b47f96b73dbe5538c3f813a80359f47", size = 6721875, upload-time = "2026-06-04T07:49:26.416Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/ff/32aa7d2ed0ab12b323aaa64f9b75e6ad4f8fd09f9ccfc28c79414d46838d/pywin32-312-cp312-cp312-win32.whl", hash = "sha256:dab4f65ac9c4e48400a2a0530c46c3c579cd5905ecd11b80692373915269208b", size = 6371877, upload-time = "2026-06-04T07:49:28.836Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/d9/77040d3b43df3f3be32ea289433d660d2727f5ba327bc73be835127d9d60/pywin32-312-cp312-cp312-win_amd64.whl", hash = "sha256:b457f6d628a47e8a7346ce22acb7e1a46a4a78b52e1d17e1af56871bd19a93bc", size = 6914841, upload-time = "2026-06-04T07:49:31.85Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/cc/7b1ec671775756020a0ee7f4feeaf3c568f0ab86bd3900088cf986937a92/pywin32-312-cp312-cp312-win_arm64.whl", hash = "sha256:6017c58e12f6809fbb0555b75df144c2922a9ffd18e4b9b5afa863b6c1a9d950", size = 6727901, upload-time = "2026-06-04T07:49:34.244Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/41/12fbfd7f36ed2146d8bc9de96c2741296bf0d490b98508496cff322e274c/pywin32-312-cp313-cp313-win32.whl", hash = "sha256:7a27df850933d16a8eabfbaeb73d52b273e2da667f80d70b01a89d1f6828d02c", size = 6370184, upload-time = "2026-06-04T07:49:36.253Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/db/36a78e3403099d31d9746d13fdcde5accc43c1155f375a34d15983a479a7/pywin32-312-cp313-cp313-win_amd64.whl", hash = "sha256:c53e878d15a1c44788082bfe712a905433473aa38f86375b7cf8b45e3acbaaf9", size = 6914298, upload-time = "2026-06-04T07:49:38.876Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/37/c1697194092b76de9ed47ca124323f02c57ffc8a45c06f88a3d5acaf01eb/pywin32-312-cp313-cp313-win_arm64.whl", hash = "sha256:59aba5d5940842075343a5ddc6b11f1cdf0d1567fe745290359dfbcc7c2eb831", size = 6727640, upload-time = "2026-06-04T07:49:41.083Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/2b/1f3cded5822fd49c02f40544cbb5f58c7cfd6b1694869fd476cb6170ee97/pywin32-312-cp314-cp314-win32.whl", hash = "sha256:a77a90fbb6881238d2ca9c6fd797b25817f3768fe78d214a90137ff055a75f5b", size = 6468928, upload-time = "2026-06-04T07:49:43.188Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/82/3bf86d2e2808902013132e1ce905a7da0da53790f3836c64bf44d55e24f3/pywin32-312-cp314-cp314-win_amd64.whl", hash = "sha256:a4dd3a848290ef724347b19f301045831d8e802fa4464f491b98b1e0a081432e", size = 7024157, upload-time = "2026-06-04T07:49:45.34Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/0e/73f6d6800b4f27655abd9e9f6aaeaefcddb2b946e4674efa2bab184a7f7b/pywin32-312-cp314-cp314-win_arm64.whl", hash = "sha256:9fce94568364e0155e6dfb781ac5d95903be8baf28670632beab1b523f300daa", size = 6839598, upload-time = "2026-06-04T07:49:47.613Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/61/caa39686032d2ebdd04ff0ab5cbe163126c0066d98e00c9018646e42393b/pywin32-312-cp315-cp315-win32.whl", hash = "sha256:5c1fbe4a937a73ae9297384a3da38518cbc694c68ad8a809b2e19acd350f03ed", size = 6471159, upload-time = "2026-06-04T07:49:50.035Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/cd/7e1de64a4a6f69c04214169657ccab0d93a670ea50e35eb8f489d7378249/pywin32-312-cp315-cp315-win_amd64.whl", hash = "sha256:c2f03a0f73f804a13c2735b99392b0cd426bb4f2c4d0178e5ac966a0f21618d5", size = 7025293, upload-time = "2026-06-04T07:49:54.857Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/ed/4532e9388e65fa16b46776ef47ad631a64eda1631884488af707666350ed/pywin32-312-cp315-cp315-win_arm64.whl", hash = "sha256:a8597d28f267b39074aef51fa593530082b39cbe5a074226096857b1fed2dfb9", size = 6840337, upload-time = "2026-06-04T07:49:57.531Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.3"
|
||||
@@ -1878,6 +2178,20 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "referencing"
|
||||
version = "0.37.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
{ name = "rpds-py" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "2026.9.10"
|
||||
@@ -2185,6 +2499,129 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/de/d2c11ed977298cee41c23b6625da9f816ba9f7b91005dfb6674cc0bec09c/rignore-0.8.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:f7b929db3f8f3fa240b0f328453de0b1b747e51b7992a9198c8412d16f4f0027", size = 1144578, upload-time = "2026-08-04T22:27:06.473Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpds-py"
|
||||
version = "2026.6.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "2.70.0"
|
||||
@@ -2298,6 +2735,19 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/7a/7d1879d78c086737acee5f3250cbff9d285e5bd7cb6bc2c730f24e8d400e/sqlalchemy-2.1.1-py3-none-any.whl", hash = "sha256:4357c1a222e141662251a59d3702f9b124294941171dfa6bd570513e9f4905ee", size = 2047471, upload-time = "2026-09-25T15:20:37.797Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sse-starlette"
|
||||
version = "3.5.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "starlette" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/be/0123026f719d1a7936f214a88b553bb5701e04ff2511147c1dab0c5035eb/sse_starlette-3.5.0.tar.gz", hash = "sha256:75de713aa8a9441513cc283220826da079d982770965b951e9437720e8bafdb2", size = 36794, upload-time = "2026-09-28T17:48:14.7Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/be/e4/cdda14023c316d71493bc54fdffc3dd006631b88866145c9d3cc33e0f1df/sse_starlette-3.5.0-py3-none-any.whl", hash = "sha256:3e6e1070df3f0f5d9cea81496de92dbb72f6721871d99748ece67441dd8b7997", size = 17407, upload-time = "2026-09-28T17:48:13.228Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "1.7.0"
|
||||
|
||||
Reference in New Issue
Block a user