Repository: SwanHubX/SwanLab (language: python)

Issue:
[BUG] 如果前端正在运行，新增加的图表无法显示，页面也无法跳转
<!-- Describe your bugs below ^_^ -->

## 🐛 Bug description [Please make everyone to understand it]

如果前端正在运行，并且有一部分图表在运行时被新增，则会造成一些错误
存在副作用就是，无法实现页面的跳转

## 🧑‍💻 Step to reproduce

1. 假设有个图表在10秒钟后被log

2. 在十秒钟之内进入前端界面，就能触发此bug

这样会带来副作用，页面也无法跳转

## 👾 Expected result

正常显示

## 🚑 Any additional [like screenshots]

- **SwanLab Version**: 0.2.1

- **Platform**: macOS

[FEATURE] Chart Tag Search
## 🤩 Features description [Please make everyone to understand it]

User can search Chart at the following location: 

<img width="550" alt="image" src="https://github.com/SwanHubX/SwanLab/assets/58305964/a430d419-1636-49f9-949e-223e408c4dde">




Discussion / hints:
我们计划在0.2.2修复此问题


Fix patch:
diff --git a/swanlab/db/db_connect.py b/swanlab/db/db_connect.py
index 4154fafa..e04d4838 100644
--- a/swanlab/db/db_connect.py
+++ b/swanlab/db/db_connect.py
@@ -10,7 +10,7 @@
 from ..env import get_db_path
 import os
 from peewee import SqliteDatabase
-from .table_config import tables, Tag, Experiment, Namespace
+from .table_config import tables, Tag, Experiment, Namespace, Chart
 from .migrate import *
 
 # 判断是否已经binded了
@@ -57,6 +57,10 @@ def connect(autocreate=False) -> SqliteDatabase:
         swandb.bind(tables)
         swandb.create_tables(tables)
         swandb.close()
+        # 完成数据迁移，如果chart表中没有status字段，则添加
+        if not Chart.field_exists("status"):
+            # 不启用外键约束
+            add_status(SqliteDatabase(path))
         # 完成数据迁移，如果namespace表中没有opened字段，则添加
         if not Namespace.field_exists("opened"):
             # 不启用外键约束
diff --git a/swanlab/db/migrate/__init__.py b/swanlab/db/migrate/__init__.py
index 02697638..32068e0e 100644
--- a/swanlab/db/migrate/__init__.py
+++ b/swanlab/db/migrate/__init__.py
@@ -7,6 +7,7 @@
 @Description:
     数据库迁移模块
 """
-from .tag_sort import add_sort
-from .exp_finish_time import add_finish_time
-from .namespace_opened import add_opened
+from .tag import add_sort
+from .experiment import add_finish_time
+from .namespace import add_opened
+from .chart import add_status
diff --git a/swanlab/db/migrate/chart.py b/swanlab/db/migrate/chart.py
new file mode 100644
index 00000000..382150ca
--- /dev/null
+++ b/swanlab/db/migrate/chart.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-09 17:39:12
+@File: swanlab/db/migrate/chart.py
+@IDE: vscode
+@Description:
+    chart相关迁移操作
+"""
+from peewee import SqliteDatabase, IntegerField
+from playhouse.migrate import migrate, SqliteMigrator
+from .experiment import (
+    add_hidden_opened as add_hidden_opened_experiment,
+    add_pinned_opened as add_pinned_opened_experiment,
+)
+from .project import add_hidden_opened as add_hidden_opened_project, add_pinned_opened as add_pinned_opened_project
+
+
+def add_status(db):
+    """
+    为数据库的Chart表添加status字段，默认为0
+    """
+    migrator = SqliteMigrator(db)
+    status = IntegerField(default=0)
+    migrate(migrator.add_column("chart", "status", status))
+    # 同时，添加sort字段
+    add_sort(db)
+    # 同时为experiment和project添加hidden_opened、pinned_opened字段
+    add_hidden_opened_experiment(db)
+    add_pinned_opened_experiment(db)
+    add_hidden_opened_project(db)
+    add_pinned_opened_project(db)
+
+
+def add_sort(db):
+    """
+    为数据库的Chart表添加sort字段，默认为NULL
+    """
+    migrator = SqliteMigrator(db)
+    sort = IntegerField(default=None, null=True)
+    migrate(migrator.add_column("chart", "sort", sort))
diff --git a/swanlab/db/migrate/exp_finish_time.py b/swanlab/db/migrate/experiment.py
similarity index 56%
rename from swanlab/db/migrate/exp_finish_time.py
rename to swanlab/db/migrate/experiment.py
index 2bc661a4..165ea683 100644
--- a/swanlab/db/migrate/exp_finish_time.py
+++ b/swanlab/db/migrate/experiment.py
@@ -9,7 +9,7 @@
     实验结束时间是指实验被标记为完成/崩溃的时间
 """
 
-from peewee import SqliteDatabase, CharField
+from peewee import SqliteDatabase, CharField, IntegerField
 from playhouse.migrate import migrate, SqliteMigrator
 
 
@@ -24,3 +24,23 @@ def add_finish_time(db):
     # 原子化操作，遍历所有status不为0的实验，将其finish_time设置为update_time
     for exp in db.execute_sql("select id, update_time from experiment where status != 0"):
         db.execute_sql(f"update experiment set finish_time = '{exp[1]}' where id = {exp[0]}")
+
+
+def add_pinned_opened(db):
+    """
+    为数据库的Experiment表添加pinned_opened字段,用于记录实验置顶部分是否打开
+    默认值为1，表示打开
+    """
+    migrator = SqliteMigrator(db)
+    pinned_opened = IntegerField(default=1, choices=[0, 1])
+    migrate(migrator.add_column("experiment", "pinned_opened", pinned_opened))
+
+
+def add_hidden_opened(db):
+    """
+    为数据库的Experiment表添加hidden_opened字段,用于记录实验隐藏部分是否打开
+    默认值为0,表示关闭
+    """
+    migrator = SqliteMigrator(db)
+    hidden_opened = IntegerField(default=0, choices=[0, 1])
+    migrate(migrator.add_column("experiment", "hidden_opened", hidden_opened))
diff --git a/swanlab/db/migrate/namespace_opened.py b/swanlab/db/migrate/namespace.py
similarity index 91%
rename from swanlab/db/migrate/namespace_opened.py
rename to swanlab/db/migrate/namespace.py
index 884025a5..73595118 100644
--- a/swanlab/db/migrate/namespace_opened.py
+++ b/swanlab/db/migrate/namespace.py
@@ -17,5 +17,5 @@ def add_opened(db):
     默认值为False
     """
     migrator = SqliteMigrator(db)
-    opened = IntegerField(default=1)
+    opened = IntegerField(default=1, choices=[0, 1])
     migrate(migrator.add_column("namespace", "opened", opened))
diff --git a/swanlab/db/migrate/project.py b/swanlab/db/migrate/project.py
new file mode 100644
index 00000000..7dc6023b
--- /dev/null
+++ b/swanlab/db/migrate/project.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-09 17:43:27
+@File: swanlab/db/migrate/project.py
+@IDE: vscode
+@Description:
+    为数据库的Project表添加迁移操作
+"""
+from peewee import IntegerField
+from playhouse.migrate import migrate, SqliteMigrator
+
+
+def add_pinned_opened(db):
+    """
+    为数据库的Project表添加pinned_opened字段,用于记录项目置顶部分是否打开
+    默认值为1，表示打开
+    """
+    migrator = SqliteMigrator(db)
+    pinned_opened = IntegerField(default=1, choices=[0, 1])
+    migrate(migrator.add_column("project", "pinned_opened", pinned_opened))
+
+
+def add_hidden_opened(db):
+    """
+    为数据库的Project表添加hidden_opened字段,用于记录项目隐藏部分是否打开
+    默认值为0,表示关闭
+    """
+    migrator = SqliteMigrator(db)
+    hidden_opened = IntegerField(default=0, choices=[0, 1])
+    migrate(migrator.add_column("project", "hidden_opened", hidden_opened))
diff --git a/swanlab/db/migrate/tag_sort.py b/swanlab/db/migrate/tag.py
similarity index 100%
rename from swanlab/db/migrate/tag_sort.py
rename to swanlab/db/migrate/tag.py
diff --git a/swanlab/db/models/charts.py b/swanlab/db/models/charts.py
index eb2024b0..e776a23f 100644
--- a/swanlab/db/models/charts.py
+++ b/swanlab/db/models/charts.py
@@ -8,7 +8,7 @@
     实验图标表
 """
 from ..model import SwanModel
-from peewee import CharField, IntegerField, ForeignKeyField, TextField, IntegrityError, Check, DatabaseProxy
+from peewee import CharField, IntegerField, ForeignKeyField, TextField, IntegrityError, Check, DatabaseProxy, fn
 from ..error import ExistedError, ForeignExpNotExistedError, ForeignProNotExistedError
 from .experiments import Experiment
 from .projects import Project
@@ -47,6 +47,10 @@ class Meta:
     """图表类型，由创建者决定，这与数据库本身无关"""
     reference = CharField(max_length=10, default="step")
     """图表数据参考，由创建者决定，这与数据库本身无关"""
+    status = IntegerField(null=False, default=0)
+    """图表状态 0代表默认状态 1代表被pinned -1代表被hidden"""
+    sort = IntegerField(null=True, default=None)
+    """图表在被pinned或hidden时的排序，越小越靠前，越大越靠后，如果为NULL则代表未被pinned或hidden"""
     config = TextField(null=True)
     """图表的其他配置，这实际上是一个json字符串"""
     more = TextField(null=True)
@@ -57,16 +61,20 @@ class Meta:
     """更新时间"""
 
     def __dict__(self):
+        experiment_id = None if self.experiment_id is None else self.experiment_id.__dict__()
+        project_id = None if self.project_id is None else self.project_id.__dict__()
         return {
             "id": self.id,
-            "experiment_id": self.experiment_id,
-            "project_id": self.project_id,
+            "experiment_id": experiment_id,
+            "project_id": project_id,
             "name": self.name,
             "description": self.description,
             "system": self.system,
             "type": self.type,
             "reference": self.reference,
             "config": self.config,
+            "status": self.status,
+            "sort": self.sort,
             "more": self.more,
             "create_time": self.create_time,
             "update_time": self.update_time,
@@ -143,3 +151,94 @@ def create(
             )
         except IntegrityError:
             raise ExistedError("图表已存在")
+
+    @classmethod
+    def pin(cls, id: int, sort: int = None) -> "Chart":
+        """
+        把某个chart置顶
+
+        Parameters
+        ----------
+        id : int
+            图表id
+        sort : int
+            图表在被pinned或hidden时的排序，越小越靠前，越大越靠后，如果为NULL则代表未被pinned或hidden, 默认为None
+            默认排在最后，也就是传入None的时候
+
+        Returns
+        -------
+        Chart : Chart
+            置顶的图表
+        """
+        chart: Chart = cls.get(cls.id == id)
+        chart.status = 1
+        if sort is None:
+            # 判断当前实验/项目下有多少个hidden的chart
+            project_id = None if chart.project_id is None else chart.project_id.id
+            experiment_id = None if chart.experiment_id is None else chart.experiment_id.id
+            # 获取当前namespace下的最大索引,如果没有，则为0
+            sort = (
+                cls.select(fn.Max(cls.sort))
+                .where(cls.project_id == project_id, cls.experiment_id == experiment_id, cls.status == 1)
+                .scalar()
+            )
+            sort = 0 if sort is None else sort + 1
+        chart.sort = sort
+        chart.save()
+        return chart
+
+    @classmethod
+    def restore(cls, id: int) -> "Chart":
+        """
+        把某个chart恢复正常状态
+
+        Parameters
+        ----------
+        id : int
+            图表id
+
+        Returns
+        -------
+        Chart : Chart
+            恢复的图表
+        """
+        chart: Chart = cls.get(cls.id == id)
+        chart.status = 0
+        chart.sort = None
+        chart.save()
+        return chart
+
+    @classmethod
+    def hide(cls, id: int, sort: int = None) -> "Chart":
+        """
+        把某个chart隐藏
+
+        Parameters
+        ----------
+        id : int
+            图表id
+        sort : int
+            图表在被pinned或hidden时的排序，越小越靠前，越大越靠后，如果为NULL则代表未被pinned或hidden, 默认为None
+            默认排在最后，也就是传入None的时候
+
+        Returns
+        -------
+        Chart : Chart
+            隐藏的图表
+        """
+        chart: Chart = cls.get(cls.id == id)
+        chart.status = -1
+        if sort is None:
+            # 判断当前实验/项目下有多少个hidden的chart
+            project_id = None if chart.project_id is None else chart.project_id.id
+            experiment_id = None if chart.experiment_id is None else chart.experiment_id.id
+            # 获取当前namespace下的最大索引,如果没有，则为0
+            sort = (
+                cls.select(fn.Max(cls.sort))
+                .where(cls.project_id == project_id, cls.experiment_id == experiment_id, cls.status == -1)
+                .scalar()
+            )
+            sort = 0 if sort is None else sort + 1
+        chart.sort = sort
+        chart.save()
+        return chart
diff --git a/swanlab/db/models/experiments.py b/swanlab/db/models/experiments.py
index e2c0adf5..5130ece8 100644
--- a/swanlab/db/models/experiments.py
+++ b/swanlab/db/models/experiments.py
@@ -72,6 +72,12 @@ class Meta:
     dark = CharField(max_length=20, null=True)
     """暗色主题颜色"""
 
+    pinned_opened = IntegerField(default=1, choices=[0, 1])
+    """实验图表置顶部分是否打开，默认值为1，表示打开"""
+
+    hidden_opened = IntegerField(default=0, choices=[0, 1])
+    """实验图表隐藏部分是否打开，默认值为0,表示关闭"""
+
     more = TextField(null=True)
     """更多信息配置，json格式，将在表函数中检查并解析"""
 
diff --git a/swanlab/db/models/namespaces.py b/swanlab/db/models/namespaces.py
index b9bc2adf..19b37ecb 100644
--- a/swanlab/db/models/namespaces.py
+++ b/swanlab/db/models/namespaces.py
@@ -58,7 +58,7 @@ class Meta:
     """命名空间描述，可为空"""
     sort = IntegerField()
     """命名空间索引，用于排序，同一个项目/实验下，命名空间索引不能重复，索引越小，排序越靠前，索引>=0"""
-    opened = IntegerField(default=1)
+    opened = IntegerField(default=1, choices=[0, 1])
     """命名空间是否已经被打开，默认为1，表示已经被打开，0表示未被打开"""
     more = TextField(default=None, null=True)
     """更多信息配置，json格式，将在表函数中检查并解析"""
diff --git a/swanlab/db/models/projects.py b/swanlab/db/models/projects.py
index abdb49dc..ea58bf19 100644
--- a/swanlab/db/models/projects.py
+++ b/swanlab/db/models/projects.py
@@ -42,6 +42,10 @@ class Meta:
     """项目下实验数量，包括已删除的实验，这是一个只增不减的值"""
     charts = IntegerField(default=0, choices=[0, 1], null=False)
     """是否已经生成项目级别图表，0 未生成，1 已生成"""
+    pinned_opened = IntegerField(default=1, choices=[0, 1])
+    """多实验图表置顶部分是否打开，默认值为1，表示打开"""
+    hidden_opened = IntegerField(default=0, choices=[0, 1])
+    """多实验图表隐藏部分是否打开，默认值为0,表示关闭"""
     more = CharField(null=True)
     """更多信息配置，json格式"""
     version = CharField(max_length=30, null=False)
@@ -59,6 +63,9 @@ def __dict__(self):
             "sum": self.sum,
             "charts": self.charts,
             "more": self.more,
+            "pinned_opened": self.pinned_opened,
+            "hidden_opened": self.hidden_opened,
+            "version": self.version,
             "create_time": self.create_time,
             "update_time": self.update_time,
         }
diff --git a/swanlab/server/app.py b/swanlab/server/app.py
index df391428..eddd95f4 100644
--- a/swanlab/server/app.py
+++ b/swanlab/server/app.py
@@ -86,6 +86,7 @@ async def _(*args, **kwargs):
 from .router.experiment import router as experiment
 from .router.project import router as project
 from .router.namespace import router as namespace
+from .router.chart import router as chart
 
 # 媒体文件路由，允许前端获取其他产生的媒体文件
 from .router.media import router as media
@@ -96,3 +97,4 @@ async def _(*args, **kwargs):
 app.include_router(experiment, prefix=prefix + "/experiment")
 app.include_router(media, prefix=prefix + "/media")
 app.include_router(namespace, prefix=prefix + "/namespace")
+app.include_router(chart, prefix=prefix + "/chart")
diff --git a/swanlab/server/controller/chart.py b/swanlab/server/controller/chart.py
new file mode 100644
index 00000000..385433ba
--- /dev/null
+++ b/swanlab/server/controller/chart.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-10 13:53:16
+@File: swanlab/server/controller/chart.py
+@IDE: vscode
+@Description:
+    图表相关操作api
+"""
+from .db import Chart
+from .utils import get_exp_charts, get_proj_charts
+from ..module import SUCCESS_200, PARAMS_ERROR_422
+
+
+def update_charts_status(chart_id: int, status: int):
+    """
+    更新图表状态，status=1表示置顶，status=0表示正常状态，status=-1表示隐藏
+
+    Parameters
+    ----------
+    chart_id : int
+        图表id
+    status : int
+        状态，1表示置顶，0表示正常状态，-1表示隐藏
+    """
+    chart: Chart = Chart.get_by_id(chart_id)
+
+    if not chart:
+        return PARAMS_ERROR_422("chart_id not exist")
+    if status == 1:
+        Chart.pin(id=chart_id)
+    elif status == -1:
+        Chart.hide(id=chart_id)
+    else:
+        Chart.restore(id=chart_id)
+    if chart.project_id:
+        chart_list, namespace_list = get_proj_charts(chart.project_id.id)
+    else:
+        chart_list, namespace_list = get_exp_charts(chart.experiment_id.id)
+    for namespace in namespace_list:
+        for j, chart_id in enumerate(namespace["charts"]):
+            # 在charts中找到对应的chart_id
+            namespace["charts"][j] = next((x for x in chart_list if x["id"] == chart_id), None)
+    return SUCCESS_200({"groups": namespace_list})
diff --git a/swanlab/server/controller/db.py b/swanlab/server/controller/db.py
new file mode 100644
index 00000000..faeb440e
--- /dev/null
+++ b/swanlab/server/controller/db.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-09 21:44:40
+@File: swanlab/server/controller/db.py
+@IDE: vscode
+@Description:
+    数据库，从数据库模块中导入数据库相关函数，供其他模块调用，不用每次都通过相对路径导入了
+"""
+from ...db import *
diff --git a/swanlab/server/controller/experiment.py b/swanlab/server/controller/experiment.py
index 97b52ac1..eee03be7 100644
--- a/swanlab/server/controller/experiment.py
+++ b/swanlab/server/controller/experiment.py
@@ -24,21 +24,19 @@
     get_requirements_path,
 )
 from ...utils import get_a_lock
-from ...utils.file import check_desc_format
 from ...utils.time import create_time
 import yaml
 from ...log import swanlog
 from typing import List, Dict
-
-from ...db import connect, NotExistedError
-
-from ...db import (
+from .db import connect, NotExistedError
+from .db import (
     Project,
     Experiment,
     Chart,
     Namespace,
     Tag,
 )
+from .utils import get_exp_charts, clear_field
 
 __to_list = Experiment.search2list
 
@@ -59,28 +57,6 @@
 # ---------------------------------- 工具函数 ----------------------------------
 
 
-def __clear_field(target: List[dict], field: str) -> List[dict]:
-    """遍历字典列表清除某个字段
-
-    Parameters
-    ----------
-    target : List[dict]
-        需要处理的列表
-    field : str
-        需要删除的字段
-
-    Returns
-    -------
-    List[dict]
-        处理后的字典列表
-    """
-
-    for item in target:
-        item.pop(field)
-
-    return target
-
-
 def __get_exp_dir_by_id(experiment_id: int) -> str:
     """通过 experiment_id 获取实验目录
 
@@ -294,24 +270,7 @@ def get_experiment_status(experiment_id: int):
     """
 
     experiment = Experiment.get(experiment_id)
-    charts = Chart.filter(Chart.experiment_id == experiment_id)
-    chart_list = __clear_field(__to_list(charts), "experiment_id")
-    for index, chart in enumerate(charts):
-        sources = []
-        for source in __to_list(chart.sources):
-            sources.append(source["tag_id"]["name"])
-        chart_list[index]["source"] = sources
-
-    # 当前实验下的命名空间
-    namespaces = Namespace.filter(Namespace.experiment_id == experiment_id)
-    namespace_list = __clear_field(__to_list(namespaces), "experiment_id")
-    # 获取每个命名空间对应的 display
-    # display 含有 chart 与 namespace 的对应关系
-    for index, namespace in enumerate(namespaces):
-        displays = []
-        for display in __to_list(namespace.displays):
-            displays.append(display["chart_id"]["id"])
-        namespace_list[index]["charts"] = displays
+    chart_list, namespace_list = get_exp_charts(experiment_id)
 
     return SUCCESS_200(
         {
@@ -319,8 +278,7 @@ def get_experiment_status(experiment_id: int):
             "update_time": experiment.update_time,
             "finish_time": experiment.finish_time,
             "charts": {
-                "_sum": charts.count(),
-                "charts": chart_list,
+                "charts": clear_field(chart_list, "experiment_id"),
                 "namespaces": namespace_list,
             },
         }
@@ -463,36 +421,11 @@ def get_experimet_charts(experiment_id: int):
         charts: List[dict]
         namesapces: List[dict]
     """
-
-    charts = Chart.filter(Chart.experiment_id == experiment_id)
-    chart_list = __to_list(charts)
-    # 获取每个图表对应的数据源
-    for index, chart in enumerate(charts):
-        sources = []
-        error = {}
-        for source in __to_list(chart.sources):
-            sources.append(source["tag_id"]["name"])
-            if source["error"]:
-                error[source["tag_id"]["name"]] = Chart.json2dict(source["error"])
-        chart_list[index]["error"] = error
-        chart_list[index]["source"] = sources
-        chart_list[index]["mutli"] = False
-
-    # 当前实验下的命名空间
-    namespaces = Namespace.filter(Namespace.experiment_id == experiment_id)
-    namespace_list = __clear_field(__to_list(namespaces), "experiment_id")
-    # 获取每个命名空间对应的 display
-    # display 含有 chart 与 namespace 的对应关系
-    for index, namespace in enumerate(namespaces):
-        displays = []
-        for display in __to_list(namespace.displays):
-            displays.append(display["chart_id"]["id"])
-        namespace_list[index]["charts"] = displays
+    chart_list, namespace_list = get_exp_charts(experiment_id)
 
     return SUCCESS_200(
         {
-            "_sum": charts.count(),
-            "charts": __clear_field(chart_list, "experiment_id"),
+            "charts": clear_field(chart_list, "experiment_id"),
             "namespaces": namespace_list,
         }
     )
diff --git a/swanlab/server/controller/namespace.py b/swanlab/server/controller/namespace.py
index d8e1b0f5..d0769956 100644
--- a/swanlab/server/controller/namespace.py
+++ b/swanlab/server/controller/namespace.py
@@ -1,43 +1,51 @@
-import os
-import ujson
-import shutil
-from ..module.resp import SUCCESS_200, DATA_ERROR_500, CONFLICT_409, NOT_FOUND_404
-from fastapi import Request
+from ..module.resp import SUCCESS_200, NOT_FOUND_404, PARAMS_ERROR_422
+from .db import NotExistedError
 
-import yaml
-from typing import List, Dict
-
-from ...db import connect, NotExistedError
-
-from ...db import (
+from .db import (
     Namespace,
+    Experiment,
+    Project,
 )
 
 
-__to_list = Namespace.search2list
-
-
 # 修改namespace可见性
-def change_namespace_visibility(namespace_id: int, opened: int):
-    """修改namespace可见性
+def change_namespace_opened(namespace_id: int, opened: int, experiment_id: int, project_id: int):
+    """修改namespace的打开/关闭状态
 
     Parameters
     ----------
     namespace_id : int
-        _description_
+        namespace的id，特别的，-1表示pinned，-2表示hidden
     opened : int
         在一个实验下，该namespace是否可见，true -> 1 , false -> 0
-
+    experiment_id : int
+        实验id，修改pinned/hidden的namespace的开启关闭状态时需要
+    project_id : int
+        项目id，修改pinned/hidden的namespace的开启关闭状态时需要
     Returns
     -------
     _type_:dict
         当前namespace信息
     """
+    if namespace_id in [-1, -2]:
+        if experiment_id is not None:
+            exp_or_proj = Experiment.get_by_id(experiment_id)
+        else:
+            exp_or_proj = Project.get_by_id(project_id)
+        # 如果实验或者项目不存在，则返回404
+        if exp_or_proj is None:
+            return NOT_FOUND_404("Experiment or project with id {} does not exist.".format(experiment_id))
+        if namespace_id == -1:
+            exp_or_proj.pinned_opened = 1 if opened else 0
+        else:
+            exp_or_proj.hidden_opened = 1 if opened else 0
+        exp_or_proj.save()
+        return SUCCESS_200(None)
+    # 正常的namespace
     try:
         namespace: Namespace = Namespace.get_by_id(namespace_id)
     except NotExistedError:
         return NOT_FOUND_404("Namespace with id {} does not exist.".format(namespace_id))
     namespace.opened = 1 if opened else 0
     namespace.save()
-    print(namespace_id, namespace.opened, opened)
-    return SUCCESS_200({"namespace": namespace.__dict__()})
+    return SUCCESS_200(None)
diff --git a/swanlab/server/controller/project.py b/swanlab/server/controller/project.py
index ca8fb0a4..99058090 100644
--- a/swanlab/server/controller/project.py
+++ b/swanlab/server/controller/project.py
@@ -19,8 +19,8 @@
 import yaml
 from typing import List
 from ...db.utils.chart import transform_to_multi_exp_charts
-
-from ...db import NotExistedError
+from .db import NotExistedError
+from .utils import get_proj_charts
 
 # 自定义响应
 from ..module.resp import (
@@ -58,29 +58,6 @@
 RUNNING_STATUS = Experiment.RUNNING_STATUS
 
 
-def __clear_fields(target: List[dict], fields: List[str]) -> list[dict]:
-    """遍历字典列表清除多个字段
-
-    Parameters
-    ----------
-    target : List[dict]
-        需要处理的列表
-    fields : List[str]
-        需要删除的字段列表
-
-    Returns
-    -------
-    list[dict]
-        处理后的字典列表
-    """
-
-    for item in target:
-        for field in fields:
-            item.pop(field)
-
-    return target
-
-
 # ---------------------------------- 路由对应的处理函数 ----------------------------------
 
 
@@ -286,51 +263,6 @@ async def get_project_charts(project_id: int = DEFAULT_PROJECT_ID) -> dict:
         transform_to_multi_exp_charts(project_id)
     except IndexError:  # 已经有多实验对比数据
         pass
-
-    # 获取当前项目下所有的多实验对比表
-    # 暂时只请求chart.type为default或者line的图表
-    allow_types = ["default", "line"]
-    multi_charts = Chart.filter(Chart.project_id == project_id, Chart.type.in_(allow_types))
-    _sum = multi_charts.count()
-    # 获取图表配置
-    charts = []
-    for _chart in multi_charts:
-        # 多实验图表的 source 中不是 tag_name，而是 experiment_name
-        sources = []
-        # 单箭头是通过外键反向索引的 chart -> source -> tag -> experiment => experiment_name
-        for source in _chart.sources:
-            sources.append(source.tag_id.experiment_id.name)
-        # 当前chart的error字段
-        error = {
-            source.tag_id.experiment_id.name: Chart.json2dict(source.error) for source in _chart.sources if source.error
-        }
-        charts.append(
-            {
-                "id": _chart.id,
-                "name": _chart.name,
-                "type": _chart.type,
-                "reference": _chart.reference,
-                "config": _chart.config,
-                "description": _chart.description,
-                "source": sources,
-                "mutli": True,
-                "error": error,
-            }
-        )
-    # 获取命名空间配置
-    namespaces = Namespace.filter(Namespace.project_id == project_id)
-    namespace_list = __clear_fields(__to_list(namespaces), ["project_id", "experiment_id"])
-    # 通过 namespace 获取 display，从而获取该 namespace 下的 charts
-    for index, namespace in enumerate(namespaces):
-        displays = []
-        for display in __to_list(namespace.displays):
-            # 只获取默认图表
-            if display["chart_id"]["type"] in allow_types:
-                displays.append(display["chart_id"]["id"])
-        if len(displays) > 0:
-            namespace_list[index]["charts"] = displays
-
-    # 过滤namespace中的空charts的namespace
-    namespace_list = [namespace for namespace in namespace_list if "charts" in namespace]
+    charts, namespace = get_proj_charts(project_id)
     # 获取项目下所有实验的图表数据
-    return SUCCESS_200({"_sum": _sum, "charts": charts, "namespaces": namespace_list})
+    return SUCCESS_200({"charts": charts, "namespaces": namespace})
diff --git a/swanlab/server/controller/utils/__init__.py b/swanlab/server/controller/utils/__init__.py
new file mode 100644
index 00000000..92ec2969
--- /dev/null
+++ b/swanlab/server/controller/utils/__init__.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-09 21:41:37
+@File: swanlab/server/controller/utils/__init__.py
+@IDE: vscode
+@Description:
+    共享工具函数
+"""
+from .charts import get_exp_charts, get_proj_charts
+from typing import List
+
+
+def clear_field(target: List[dict], field: str) -> List[dict]:
+    """遍历字典列表清除某个字段
+
+    Parameters
+    ----------
+    target : List[dict]
+        需要处理的列表
+    field : str
+        需要删除的字段
+
+    Returns
+    -------
+    List[dict]
+        处理后的字典列表
+    """
+
+    for item in target:
+        item.pop(field)
+
+    return target
diff --git a/swanlab/server/controller/utils/charts.py b/swanlab/server/controller/utils/charts.py
new file mode 100644
index 00000000..3720d648
--- /dev/null
+++ b/swanlab/server/controller/utils/charts.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-09 21:43:59
+@File: swanlab/server/controller/utils/charts.py
+@IDE: vscode
+@Description:
+    图表相关函数
+"""
+from ..db import Chart, Display, Namespace
+from typing import List, Union
+
+
+def get_exp_charts(id: int):
+    """
+    获取单实验图表数据
+
+    Parameters
+    ----------
+    id : int
+        实验id
+    """
+    charts: List[Chart] = Chart.filter(Chart.experiment_id == id)
+    chart_list = Chart.search2list(charts)
+    # 获取每个图表对应的数据源
+    for index, chart in enumerate(charts):
+        sources = []
+        error = {}
+        for source in Chart.search2list(chart.sources):
+            sources.append(source["tag_id"]["name"])
+            if source["error"]:
+                error[source["tag_id"]["name"]] = Chart.json2dict(source["error"])
+        chart_list[index]["error"] = error
+        chart_list[index]["source"] = sources
+        chart_list[index]["mutli"] = False
+    # 当前实验下的命名空间
+    namespaces = Namespace.filter(Namespace.experiment_id == id)
+    namespace_list = Namespace.search2list(namespaces)
+    # 获取每个命名空间对应的 display
+    # display 含有 chart 与 namespace 的对应关系
+    for index, namespace in enumerate(namespaces):
+        displays = []
+        for display in Namespace.search2list(namespace.displays):
+            displays.append(display["chart_id"]["id"])
+        namespace_list[index]["charts"] = displays
+    return get_pinned_and_hidden(chart_list, namespace_list)
+
+
+def get_proj_charts(id: int):
+    """
+    获取多实验对比图表数据
+
+    Parameters
+    ----------
+    id : int
+        项目id
+    """
+    # 获取当前项目下所有的多实验对比表
+    # 暂时只请求chart.type为default或者line的图表
+    allow_types = ["default", "line"]
+    multi_charts = Chart.filter(Chart.project_id == id, Chart.type.in_(allow_types))
+    # 获取图表配置
+    charts = []
+    for _chart in multi_charts:
+        # 多实验图表的 source 中不是 tag_name，而是 experiment_name
+        sources, error = [], {}
+        # 单箭头是通过外键反向索引的 chart -> source -> tag -> experiment => experiment_name
+        for source in _chart.sources:
+            sources.append(source.tag_id.experiment_id.name)
+        # 当前chart的error字段，将所有的error字段转换为dict，key为实验名
+        for source in _chart.sources:
+            if source.error:
+                error[source.tag_id.experiment_id.name] = Chart.json2dict(source.error)
+        t = _chart.__dict__()
+        charts.append({**t, "error": error, "source": sources, "mutli": True})
+    # 获取命名空间配置
+    namespaces = Namespace.filter(Namespace.project_id == id)
+    namespace_list = Namespace.search2list(namespaces)
+    # 通过 namespace 获取 display，从而获取该 namespace 下的 charts
+    for index, namespace in enumerate(namespaces):
+        displays = []
+        for display in Display.search2list(namespace.displays):
+            # 只获取默认图表
+            if display["chart_id"]["type"] in allow_types:
+                displays.append(display["chart_id"]["id"])
+        if len(displays) > 0:
+            namespace_list[index]["charts"] = displays
+    # 过滤namespace中的空charts的namespace
+    namespace_list = [namespace for namespace in namespace_list if "charts" in namespace]
+
+    return get_pinned_and_hidden(charts, namespace_list)
+
+
+def get_pinned_and_hidden(chart_list: List[dict], namespace_list: List[dict]) -> Union[List[dict], List[dict]]:
+    """
+    获取置顶图表与隐藏图表
+    """
+    if not len(chart_list) or not len(namespace_list):
+        return chart_list, namespace_list
+    # 获取pinned和hidden的开启/关闭状态，通过chart_list的第一个元素的experiment_id或者project_id获取
+    first_chart = chart_list[0]
+    if first_chart["experiment_id"] is not None:
+        exp_or_proj = first_chart["experiment_id"]
+    else:
+        exp_or_proj = first_chart["project_id"]
+    pinned_opened, hidden_opened = exp_or_proj["pinned_opened"], exp_or_proj["hidden_opened"]
+
+    # 遍历chart_list，动态生成pinned与hidden的namespace，这两个namespace的id分别为-1与-2
+    pinned_namespace = {
+        "id": -1,
+        "name": "pinned",
+        "charts": [],
+        "opened": pinned_opened,
+        "experiment_id": first_chart["experiment_id"],
+        "project_id": first_chart["project_id"],
+    }
+    hidden_namespace = {
+        "id": -2,
+        "name": "hidden",
+        "charts": [],
+        "opened": hidden_opened,
+        "experiment_id": first_chart["experiment_id"],
+        "project_id": first_chart["project_id"],
+    }
+    for chart in chart_list:
+        # 如果chart的status为1，则将其加入pinned的namespace，如果是-1加入hidden的namespace
+        # 如果是0，则不加入任何namespace
+        # 首先将chart对象加入pinned或hidden的namespace，后续会滤除为id
+        if chart["status"] == 1:
+            pinned_namespace["charts"].append(chart)
+        elif chart["status"] == -1:
+            hidden_namespace["charts"].append(chart)
+        if chart["status"] != 0:
+            del_chart_from_namespace(namespace_list, chart["id"])
+    # 滤除namespace中的空charts的namespace
+    namespace_list = [namespace for namespace in namespace_list if len(namespace["charts"]) != 0]
+    # 如果pinned_namespace中有charts，则加入namespace_list的首位
+    if len(pinned_namespace["charts"]) > 0:
+        # namespaces的charts字段根据每个元素的sort排序，小的在前
+        pinned_namespace["charts"].sort(key=lambda x: x["sort"])
+        pinned_namespace = {**pinned_namespace, "charts": [chart["id"] for chart in pinned_namespace["charts"]]}
+        namespace_list.insert(0, pinned_namespace)
+    # 如果hidden_namespace中有charts，则加入namespace_list的末位
+    if len(hidden_namespace["charts"]) > 0:
+        # namespaces的charts字段根据每个元素的sort排序，小的在前
+        hidden_namespace["charts"].sort(key=lambda x: x["sort"])
+        hidden_namespace = {**hidden_namespace, "charts": [chart["id"] for chart in hidden_namespace["charts"]]}
+        namespace_list.append(hidden_namespace)
+    return chart_list, namespace_list
+
+
+def del_chart_from_namespace(namespace_list: List[dict], chart_id: int) -> List[dict]:
+    """
+    从命名空间中删除图表
+    """
+    for namespace in namespace_list:
+        if chart_id in namespace["charts"]:
+            namespace["charts"].remove(chart_id)
+    return namespace_list
diff --git a/swanlab/server/middleware/common.py b/swanlab/server/middleware/common.py
index 8a679d7b..315cbfc1 100644
--- a/swanlab/server/middleware/common.py
+++ b/swanlab/server/middleware/common.py
@@ -70,6 +70,7 @@ async def catch_error(request: Request, call_next):
     try:
         return await call_next(request)
     except Exception as e:
+        swl.error(str(e))
         return UNEXPECTED_ERROR_500(str(e))
 
 
diff --git a/swanlab/server/module/__init__.py b/swanlab/server/module/__init__.py
index 8b137891..3f8c118a 100644
--- a/swanlab/server/module/__init__.py
+++ b/swanlab/server/module/__init__.py
@@ -1,1 +1,9 @@
-
+from .resp import (
+    SUCCESS_200,
+    SUCCESS_200,
+    PARAMS_ERROR_422,
+    NOT_FOUND_404,
+    CONFLICT_409,
+    DATA_ERROR_500,
+    UNEXPECTED_ERROR_500,
+)
diff --git a/swanlab/server/module/models/experiment.py b/swanlab/server/module/models/experiment.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/swanlab/server/module/models/project.py b/swanlab/server/module/models/project.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/swanlab/server/module/models/tag.py b/swanlab/server/module/models/tag.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/swanlab/server/router/chart.py b/swanlab/server/router/chart.py
new file mode 100644
index 00000000..2cdfbea4
--- /dev/null
+++ b/swanlab/server/router/chart.py
@@ -0,0 +1,34 @@
+from fastapi import APIRouter
+from ..module.resp import PARAMS_ERROR_422
+
+from ..controller.chart import (
+    update_charts_status,
+)
+from fastapi import Request
+from urllib.parse import quote
+
+router = APIRouter()
+
+
+@router.patch("/{chart_id}/status")
+async def _(chart_id: int, request: Request):
+    """修改图表状态
+
+    Parameters
+    ----------
+    chart_id : int
+        图表id
+    request : Request
+        请求体，包含 status 字段
+    Returns
+    -------
+    groups : list
+        图表列表
+    """
+
+    data = await request.json()
+    status = data.get("status")
+
+    if status is None:
+        return PARAMS_ERROR_422("Request parameter 'status'")
+    return update_charts_status(chart_id, status)
diff --git a/swanlab/server/router/namespace.py b/swanlab/server/router/namespace.py
index c3417504..8867df61 100644
--- a/swanlab/server/router/namespace.py
+++ b/swanlab/server/router/namespace.py
@@ -2,8 +2,8 @@
 from ..module.resp import PARAMS_ERROR_422
 
 from ..controller.namespace import (
-    # 修改namespace可见性
-    change_namespace_visibility,
+    # 修改namespace开启关闭状态
+    change_namespace_opened,
 )
 from fastapi import Request
 from urllib.parse import quote
@@ -28,7 +28,13 @@ async def _(namespace_id: int, request: Request):
         当前实验信息
     """
 
-    opened = (await request.json()).get("opened")
+    data = await request.json()
+    opened = data.get("opened")
+    experiment_id = data.get("experiment_id")
+    project_id = data.get("project_id")
+
     if opened is None:
-        return PARAMS_ERROR_422("Request parameter 'show'")
-    return change_namespace_visibility(namespace_id, opened)
+        return PARAMS_ERROR_422("Request parameter 'opened'")
+    if experiment_id is None and project_id is None:
+        return PARAMS_ERROR_422("Request parameter 'experiment_id' or 'project_id'")
+    return change_namespace_opened(namespace_id, opened, experiment_id, project_id)
diff --git a/vue/src/assets/iconfont.js b/vue/src/assets/iconfont.js
index 56a2d439..c0fa8a85 100644
--- a/vue/src/assets/iconfont.js
+++ b/vue/src/assets/iconfont.js
@@ -1,1 +1,1 @@
-window._iconfont_svg_string_4357075='<svg><symbol id="icon-smooth" viewBox="0 0 1024 1024"><path d="M533.12 10.666667a480 480 0 1 1 0 960 480 480 0 0 1 0-960z m0 96a384 384 0 1 0 0 768 384 384 0 0 0 0-768z"  ></path><path d="M449.066667 529.066667h38.4v38.4h-38.4v-38.4z m75.264 105.642666H389.12v-154.112c-22.357333-51.456-42.325333-124.373333-42.325333-220.288h58.666666c0 97.194667 23.04 167.338667 45.056 212.48h100.864v109.824c2.432 1.28 5.077333 2.816 7.68 4.138667 42.368 22.784 115.2 50.133333 222.933334 50.133333V695.466667c-120.064 0-203.861333-30.421333-257.536-60.8h-0.085334z"  ></path></symbol><symbol id="icon-chart" viewBox="0 0 1075 1024"><path d="M913.6128 792.0128H225.5872V167.936a8.0384 8.0384 0 0 0-7.9872-7.9872H161.5872A8.0384 8.0384 0 0 0 153.6 167.9872V856.064c0 4.4032 3.584 7.9872 7.9872 7.9872h752.0256c4.4032 0 7.9872-3.584 7.9872-7.9872v-56.0128a8.0384 8.0384 0 0 0-7.9872-7.9872z"  ></path><path d="M331.4176 637.696c3.072 3.072 8.0896 3.072 11.264 0l138.3424-137.5744 127.5904 128.3584c3.072 3.072 8.192 3.072 11.264 0l275.456-275.3024c3.072-3.072 3.072-8.192 0-11.264l-39.6288-39.6288a8.0384 8.0384 0 0 0-11.264 0L614.4 532.1728 487.0144 404.0704a8.0384 8.0384 0 0 0-11.3152 0l-183.808 182.6816c-3.072 3.072-3.072 8.192 0 11.264l39.5264 39.7312z"  ></path></symbol><symbol id="icon-charts" viewBox="0 0 1024 1024"><path d="M962.56 860.2112H137.472V111.9744A9.6256 9.6256 0 0 0 128 102.4H60.7744A9.6256 9.6256 0 0 0 51.2 111.9744V936.96c0 5.2736 4.3008 9.6256 9.5744 9.6256H962.56a9.6256 9.6256 0 0 0 9.6256-9.6256V869.888a9.6256 9.6256 0 0 0-9.6256-9.6256z"  ></path><path d="M234.7008 755.0976c3.0208 4.3008 8.9088 5.3248 13.312 2.304l191.5904-134.2464 124.4672 177.8176c3.072 4.2496 9.0624 5.3248 13.3632 2.304l381.7472-268.9024a9.6256 9.6256 0 0 0 2.304-13.312l-38.7072-54.9376a9.6256 9.6256 0 0 0-13.312-2.304l-318.8224 224.5632L466.432 510.7712a9.6256 9.6256 0 0 0-13.3632-2.304l-254.5664 178.176a9.6256 9.6256 0 0 0-2.304 13.4144l38.5536 54.9888z"  ></path><path d="M220.7232 520.1408c3.7376 3.6864 9.728 3.6864 13.568 0l165.8368-165.0176 152.9856 153.9584a9.6256 9.6256 0 0 0 13.568 0l330.24-330.0864a9.6256 9.6256 0 0 0 0-13.568l-47.5136-47.5136a9.6256 9.6256 0 0 0-13.5168 0l-275.8144 275.712-152.7808-153.7536a9.6256 9.6256 0 0 0-13.5168 0l-220.416 219.136a9.6256 9.6256 0 0 0 0 13.5168l47.36 47.616z"  ></path></symbol><symbol id="icon-pause" viewBox="0 0 1024 1024"><path d="M688 288H336a48 48 0 0 0-48 48v352a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V336a48 48 0 0 0-48-48z"  ></path></symbol><symbol id="icon-play" viewBox="0 0 1024 1024"><path d="M817.088 484.96l-512-323.744c-9.856-6.24-22.336-6.624-32.512-0.992A31.993 31.993 0 0 0 256 188.256v647.328c0 11.648 6.336 22.4 16.576 28.032A31.82 31.82 0 0 0 288 867.584a32.107 32.107 0 0 0 17.088-4.928l512-323.616A31.976 31.976 0 0 0 832 512a31.976 31.976 0 0 0-14.912-27.04z"  ></path></symbol><symbol id="icon-eye-close" viewBox="0 0 1228 1024"><path d="M1041.408 273.92c-131.328 163.2768-262.5024 242.4832-393.8816 242.4832-131.84 0-268.4416-79.7696-409.6-243.712a47.9744 47.9744 0 1 0-72.704 62.5664c157.696 183.296 318.464 277.0944 482.304 277.0944 164.4032 0 320.7168-94.3616 468.6336-278.3232a47.9744 47.9744 0 0 0-74.752-60.1088z"  ></path><path d="M303.616 461.6704l-91.4432 105.728a34.304 34.304 0 0 0 51.8656 44.8512l91.392-105.728a34.304 34.304 0 1 0-51.8656-44.8512z m184.5248 124.0576l-36.5568 146.2272a34.304 34.304 0 1 0 66.5088 16.64l36.5568-146.2272a34.304 34.304 0 0 0-66.5088-16.64z m265.3184 5.9904l51.4048 146.176a34.304 34.304 0 0 0 64.6656-22.7328l-51.4048-146.176a34.304 34.304 0 0 0-64.6656 22.7328z m186.5216-124.5184l105.728 105.728a34.304 34.304 0 0 0 48.4864-48.4864l-105.728-105.728a34.304 34.304 0 0 0-48.4864 48.4864z"  ></path></symbol><symbol id="icon-eye" viewBox="0 0 1228 1024"><path d="M614.4 832c-187.7504 0-355.2256-98.7136-502.0672-291.584A46.7456 46.7456 0 0 1 102.4 512c0-10.0352 3.4304-19.9168 9.9328-28.416C259.1744 290.7136 426.7008 192 614.4 192c187.7504 0 355.2256 98.7136 502.1184 291.584A46.7456 46.7456 0 0 1 1126.4 512a46.7456 46.7456 0 0 1-9.8816 28.416c-146.8928 192.8704-314.368 291.584-502.1184 291.584zM614.4 256c-155.392 0-299.3664 83.8656-432.128 256 132.7616 172.1344 276.736 256 432.128 256 155.4432 0 299.3664-83.8656 432.128-256-132.7616-172.1344-276.6848-256-432.128-256z m0 405.3504c-99.84 0-180.7872-66.8672-180.7872-149.3504 0-82.432 80.896-149.3504 180.7872-149.3504 99.84 0 180.7872 66.8672 180.7872 149.3504 0 82.432-80.896 149.3504-180.736 149.3504z m0-64c57.088 0 103.3216-38.2464 103.3216-85.3504S671.488 426.6496 614.4 426.6496c-57.0368 0-103.3216 38.2464-103.3216 85.3504s46.2848 85.3504 103.3216 85.3504z"  ></path></symbol><symbol id="icon-experiment" viewBox="0 0 1024 1024"><path d="M882.580211 421.295158a406.258526 406.258526 0 0 0-87.309474-129.509053A406.312421 406.312421 0 0 0 507.149474 172.463158a406.258526 406.258526 0 0 0-288.121263 119.322947A406.258526 406.258526 0 0 0 99.705263 579.907368c0 120.724211 53.032421 234.388211 145.408 312.050527l1.616842 1.293473a29.480421 29.480421 0 0 0 18.701474 6.790737h483.543579c6.844632 0 13.473684-2.425263 18.755368-6.790737l1.562948-1.293473a406.905263 406.905263 0 0 0 145.30021-312.050527c0-54.972632-10.778947-108.328421-32.013473-158.61221z m-148.58779 409.6H280.252632a337.542737 337.542737 0 0 1-111.454316-250.98779 335.764211 335.764211 0 0 1 99.112421-239.184842 336.087579 336.087579 0 0 1 239.184842-99.166315 335.764211 335.764211 0 0 1 239.184842 99.166315 336.087579 336.087579 0 0 1 99.166316 239.184842c0 96.040421-40.474947 186.906947-111.562105 251.041685z"  ></path><path d="M608.579368 453.955368a7.275789 7.275789 0 0 0-10.24 0L521.377684 530.863158a50.876632 50.876632 0 1 0 22.851369 85.207579 50.822737 50.822737 0 0 0 13.20421-49.205895l76.8-76.853895a7.275789 7.275789 0 0 0 0-10.24l-25.707789-25.761684zM487.154526 361.633684h40.04379c3.988211 0 7.275789-3.233684 7.275789-7.275789v-72.757895a7.275789 7.275789 0 0 0-7.275789-7.275789h-40.04379a7.275789 7.275789 0 0 0-7.275789 7.275789v72.757895c0 4.042105 3.233684 7.275789 7.275789 7.275789z m236.490106 198.332632v39.989895c0 3.988211 3.233684 7.275789 7.275789 7.275789h72.757895c3.988211 0 7.221895-3.287579 7.221895-7.275789v-40.04379a7.275789 7.275789 0 0 0-7.221895-7.275789h-72.757895a7.275789 7.275789 0 0 0-7.275789 7.275789z m11.533473-179.415579l-28.294737-28.240842a7.275789 7.275789 0 0 0-10.24 0l-51.523368 51.469473a7.275789 7.275789 0 0 0 0 10.24l28.294737 28.294737a7.275789 7.275789 0 0 0 10.24 0l51.523368-51.469473a7.275789 7.275789 0 0 0 0-10.24z m-417.091368-28.240842a7.275789 7.275789 0 0 0-10.24 0l-28.348632 28.240842a7.275789 7.275789 0 0 0 0 10.293895l51.523369 51.469473a7.275789 7.275789 0 0 0 10.24 0l28.294737-28.294737a7.275789 7.275789 0 0 0 0-10.24l-51.469474-51.469473z m-38.265263 200.326737h-72.757895a7.275789 7.275789 0 0 0-7.27579 7.275789v40.04379c0 3.988211 3.233684 7.275789 7.27579 7.275789h72.757895c3.988211 0 7.275789-3.287579 7.275789-7.275789v-40.04379a7.275789 7.275789 0 0 0-7.275789-7.275789z"  ></path></symbol><symbol id="icon-runs" viewBox="0 0 1024 1024"><path d="M51.2 152.0128A100.864 100.864 0 0 1 152.0128 51.2H871.936A100.864 100.864 0 0 1 972.8 152.0128V871.936A100.8128 100.8128 0 0 1 871.9872 972.8H152.064A100.8128 100.8128 0 0 1 51.2 871.9872V152.064z m374.4256 273.6128v460.8h446.3616a14.3872 14.3872 0 0 0 14.4384-14.4384V425.6256h-460.8z m460.8-86.4256V152.0128a14.3872 14.3872 0 0 0-14.4384-14.3872H425.6256v201.5744h460.8zM137.6256 425.6256v446.3616c0 7.936 6.4 14.4384 14.336 14.4384h187.2384v-460.8H137.5744z m201.5744-86.4256V137.5744H152.0128a14.3872 14.3872 0 0 0-14.3872 14.4384v187.1872h201.5744z"  ></path></symbol><symbol id="icon-success" viewBox="0 0 1024 1024"><path d="M515.072 40.384C256.768 40.384 46.592 250.624 46.592 508.928c0 258.368 210.176 468.544 468.48 468.544 258.368 0 468.544-210.176 468.544-468.48C983.68 250.56 773.44 40.32 515.2 40.32z m0 875.648a407.552 407.552 0 0 1-407.04-407.04 407.552 407.552 0 0 1 407.04-407.168 407.552 407.552 0 0 1 407.104 407.104 407.552 407.552 0 0 1-407.04 407.104z"  ></path><path d="M678.272 363.2L451.968 589.504 352 489.408a30.72 30.72 0 1 0-43.456 43.456l121.792 121.792a30.72 30.72 0 0 0 43.456 0l248-248a30.72 30.72 0 1 0-43.52-43.456z"  ></path></symbol><symbol id="icon-error" viewBox="0 0 1024 1024"><path d="M512 42.688a469.312 469.312 0 1 1 0 938.624A469.312 469.312 0 0 1 512 42.688z m0 64a405.376 405.376 0 1 0 0 810.688A405.376 405.376 0 0 0 512 106.624z m-104.704 256a8.512 8.512 0 0 1 6.016 2.432L512 463.808l98.688-98.688a8.512 8.512 0 0 1 6.08-2.496h66.304a8.512 8.512 0 0 1 6.08 14.592l-131.84 131.84 137.6 137.664a8.576 8.576 0 0 1-6.016 14.592H622.528a8.512 8.512 0 0 1-6.016-2.496L512 554.304l-104.512 104.512a8.512 8.512 0 0 1-6.016 2.56H335.104a8.576 8.576 0 0 1-6.016-14.656l137.664-137.6-131.84-131.84a8.512 8.512 0 0 1 6.016-14.592h66.368z"  ></path></symbol><symbol id="icon-circle-fill" viewBox="0 0 1024 1024"><path d="M512 512m-384 0a384 384 0 1 0 768 0 384 384 0 1 0-768 0Z"  ></path></symbol><symbol id="icon-model" viewBox="0 0 1075 1024"><path d="M539.5456 921.6c-5.12 0-10.24-1.28-14.8992-3.8912l-330.496-189.952a29.7984 29.7984 0 0 1-14.9504-25.856V322.2016c0-10.5984 5.7344-20.48 14.9504-25.8048l330.496-189.952a29.7984 29.7984 0 0 1 29.8496 0l330.496 189.952c9.216 5.376 14.9504 15.104 14.9504 25.8048v379.8528c0 10.5472-5.7344 20.48-14.9504 25.8048l-330.496 189.8496a30.5152 30.5152 0 0 1-14.9504 3.8912z m-300.6464-236.6976l300.6464 172.7488 300.6464-172.7488v-345.6l-300.6464-172.7488-300.6464 172.7488v345.6z m300.6464-143.1552a29.952 29.952 0 0 1-14.8992-3.9936L287.8976 401.8688a29.696 29.696 0 0 1-11.008-40.704 30.0032 30.0032 0 0 1 40.8576-10.9056l236.7488 135.9872a29.696 29.696 0 0 1-14.9504 55.552z m0 272.1792a29.7984 29.7984 0 0 1-29.8496-29.7472v-254.8736l-221.5424-127.488s-0.1536 0-0.1536-0.1024L194.2528 347.8528A29.696 29.696 0 0 1 183.2448 307.2a29.952 29.952 0 0 1 40.8576-10.9056l330.496 189.952c9.216 5.376 14.9504 15.104 14.9504 25.8048v272.0256a30.0032 30.0032 0 0 1-30.0032 29.7984z m0 107.6736a29.7984 29.7984 0 0 1-29.8496-29.696V512c0-16.384 13.3632-29.696 29.8496-29.696 16.4864 0 29.8496 13.312 29.8496 29.696v379.8528a29.696 29.696 0 0 1-29.8496 29.696z m0-379.8016a29.696 29.696 0 0 1-14.9504-55.5008l330.5472-190.0032a30.0032 30.0032 0 0 1 40.8064 10.9056 29.696 29.696 0 0 1-10.9568 40.6528l-330.496 190.0032a29.184 29.184 0 0 1-14.9504 3.8912z"  ></path></symbol><symbol id="icon-logs" viewBox="0 0 1075 1024"><path d="M238.9504 298.6496a42.6496 42.6496 0 1 0 0-85.2992 42.6496 42.6496 0 0 0 0 85.2992zM409.6 224a32 32 0 0 0 0 64h426.6496a32 32 0 1 0 0-64H409.6zM409.6 736a32 32 0 1 0 0 64h426.6496a32 32 0 1 0 0-64H409.6zM377.6 512c0-17.664 14.336-32 32-32h426.6496a32 32 0 1 1 0 64H409.6A32 32 0 0 1 377.6 512zM238.9504 554.6496a42.6496 42.6496 0 1 0 0-85.2992 42.6496 42.6496 0 0 0 0 85.2992zM281.6 768a42.6496 42.6496 0 1 1-85.3504 0A42.6496 42.6496 0 0 1 281.6 768z"  ></path></symbol><symbol id="icon-download" viewBox="0 0 1024 1024"><path d="M943.766588 737.581176c-1.204706-28.912941-20.178824-44.935529-45.17647-44.333176-24.696471 0.602353-41.080471 16.865882-43.369412 46.441412-1.746824 21.805176-0.301176 43.791059-0.783059 65.65647-1.204706 54.874353-13.010824 67.584-67.945412 68.668236-52.826353 1.024-105.773176 0.361412-158.659764 0.361411-122.157176 0-244.314353 0.060235-366.531765-0.12047-84.148706-0.060235-91.437176-7.348706-91.858824-89.148235 0-14.576941 0.662588-29.274353-0.602353-43.730824-2.891294-30.840471-17.347765-46.863059-41.803294-48.188235-26.383059-1.566118-45.658353 16.384-47.646117 48.188235-1.807059 29.033412-0.783059 58.247529-0.602353 87.461647 0.602353 94.448941 42.465882 136.854588 136.914823 137.336471 98.484706 0.602353 196.969412 0.180706 295.454118 0.180706h87.521882c74.752 0 149.564235 1.024 224.316236-0.421648 65.897412-1.204706 114.085647-39.333647 119.627294-97.159529 4.216471-43.369412 2.951529-87.521882 1.14447-131.192471z"  ></path><path d="M179.139765 447.186824l282.081882 282.142117 11.625412 11.565177c15.058824 15.36 32.768 23.973647 54.151529 15.902117a45.296941 45.296941 0 0 0 16.564706-11.143529c2.951529-2.048 5.842824-4.276706 8.432941-6.806588 48.308706-46.983529 254.313412-253.650824 301.899294-301.417412 5.12-5.180235 9.999059-10.661647 14.034824-16.685177 12.950588-19.215059 11.203765-38.068706-4.216471-54.874353-15.661176-17.227294-35.418353-17.950118-54.874353-8.432941-9.456941 4.698353-17.287529 13.251765-24.997647 20.901647-31.984941 31.744-147.877647 147.516235-225.40047 225.15953V239.495529c0-36.442353 1.204706-72.944941-0.602353-109.266823-1.746824-33.792-18.070588-51.019294-44.513883-51.862588-27.105882-0.903529-43.489882 15.600941-47.164235 48.850823-1.385412 12.649412-0.602353 25.479529-0.662588 38.249412v420.321882l-12.528941 5.481412-72.282353-71.981176c-50.236235-50.236235-99.870118-101.135059-151.009883-150.40753-23.070118-22.287059-49.874824-22.648471-68.246588-5.12-19.817412 18.853647-19.094588 41.321412 2.469647 67.704471 4.577882 5.662118 10.059294 10.541176 15.23953 15.661176z"  ></path></symbol><symbol id="icon-sidebar" viewBox="0 0 1024 1024"><path d="M116.14 761.521h788.995v78.926H116.14v-78.926zM550.058 485.37h355.078v78.926H550.057v-78.926z m0-276.152h355.078v78.926H550.057v-78.926zM130.818 406.443L354.061 183.29l55.81 55.81L186.63 462.255l-55.81-55.81z"  ></path><path d="M351.688 629.686L128.445 406.443l55.81-55.81L407.41 573.875l-55.723 55.81z"  ></path></symbol><symbol id="icon-trash" viewBox="0 0 1024 1024"><path d="M602.232471 753.061647a30.057412 30.057412 0 0 1-30.117647-30.117647V391.529412a30.057412 30.057412 0 1 1 60.235294 0v331.233882a30.177882 30.177882 0 0 1-30.117647 30.298353zM421.586824 753.061647a30.057412 30.057412 0 0 1-30.117648-30.117647V391.529412a30.057412 30.057412 0 1 1 60.235295 0v331.233882a30.177882 30.177882 0 0 1-30.117647 30.298353zM903.529412 240.941176H752.941176V180.705882c0-49.874824-40.116706-90.352941-89.630117-90.352941H361.351529A90.352941 90.352941 0 0 0 271.058824 180.705882v60.235294H120.470588a30.057412 30.057412 0 1 0 0 60.235295H903.529412a30.057412 30.057412 0 1 0 0-60.235295zM331.294118 180.705882c0-16.504471 13.552941-30.117647 30.117647-30.117647h301.899294c16.504471 0 29.455059 13.251765 29.455059 30.117647v60.235294H331.233882V180.705882z"  ></path><path d="M722.823529 933.647059H301.357176a90.352941 90.352941 0 0 1-90.352941-90.352941V391.228235a30.057412 30.057412 0 1 1 60.235294 0v452.186353a30.117647 30.117647 0 0 0 30.117647 30.117647h421.707295c16.685176 0 30.117647-13.432471 30.117647-30.117647V392.312471a30.057412 30.057412 0 1 1 60.235294 0V843.294118a90.714353 90.714353 0 0 1-90.473412 90.352941z"  ></path></symbol><symbol id="icon-modify" viewBox="0 0 1024 1024"><path d="M65.250485 1015.627294a40.176941 40.176941 0 0 1 0-79.751529h893.409882a40.176941 40.176941 0 0 1 0 79.751529H65.250485zM801.084838 78.787765l89.931294 89.991529a63.849412 63.849412 0 0 1 0 89.99153l-570.488471 568.621176a63.849412 63.849412 0 0 1-45.357176 18.492235H156.567191a31.924706 31.924706 0 0 1-31.924706-31.924706V692.103529a63.849412 63.849412 0 0 1 18.492235-45.296941l568.018824-568.018823a63.849412 63.849412 0 0 1 89.991529 0zM204.333779 698.488471v67.644235h67.644235l552.056471-552.056471-67.644236-68.246588-552.05647 552.658824z"  ></path></symbol><symbol id="icon-info" viewBox="0 0 1024 1024"><path d="M512 958.0032c-245.9136 0-446.0032-200.0384-446.0032-446.0032 0-245.9136 200.0896-446.0032 445.952-446.0032 246.016 0 446.0544 200.0384 446.0544 446.0032S757.9648 958.0032 512 958.0032zM512 130.048c-210.688 0-382.0032 171.3664-382.0032 382.0032 0 210.6368 171.3152 382.0032 381.952 382.0032 210.688 0 382.0544-171.3664 382.0544-382.0032 0-210.6368-171.3664-382.0032-382.0032-382.0032z"  ></path><path d="M464.0256 304.0256a48.0256 48.0256 0 1 0 96 0 48.0256 48.0256 0 0 0-96.0512 0zM512 768a32 32 0 0 1-32-32V448a32 32 0 0 1 64 0v288c0 17.7152-14.336 32-32 32z"  ></path></symbol><symbol id="icon-close" viewBox="0 0 1024 1024"><path d="M587.264 506.197333l397.141333-397.226666a52.053333 52.053333 0 0 0 0-73.130667L982.186667 33.621333a51.968 51.968 0 0 0-73.130667 0L511.914667 431.445333 114.858667 33.621333a52.053333 52.053333 0 0 0-73.130667 0L39.594667 35.84a51.029333 51.029333 0 0 0 0 73.130667l397.056 397.226666-397.056 397.226667a52.053333 52.053333 0 0 0 0 73.130667l2.133333 2.218666a51.968 51.968 0 0 0 73.130667 0L512 581.546667l397.141333 397.226666a51.968 51.968 0 0 0 73.130667 0l2.133333-2.133333a52.053333 52.053333 0 0 0 0-73.130667L587.264 506.197333z"  ></path></symbol><symbol id="icon-zoom" viewBox="0 0 1024 1024"><path d="M429.91 872.79h-211.2l232.106-232.107a43.947 43.947 0 1 0-62.208-62.166L152.747 814.208V604.8a43.99 43.99 0 0 0-87.979 0v312.021c0 24.278 19.67 43.947 43.99 43.947h320.98a43.99 43.99 0 0 0 0.129-87.979zM915.882 64.852H594.9a43.99 43.99 0 0 0 0 87.979h211.115l-232.15 232.021a43.947 43.947 0 1 0 62.209 62.208l235.69-235.733v209.365a43.99 43.99 0 0 0 87.979 0V108.715a43.819 43.819 0 0 0-43.904-43.947z"  ></path></symbol><symbol id="icon-config" viewBox="0 0 1024 1024"><path d="M750.657741 768.65536c-55.33696 6.67648-105.92256-30.5152-112.59904-83.968-6.67648-53.41184 32.44032-103.05536 87.77728-109.73184 55.33696-6.67648 105.92256 30.55616 112.59904 83.968 6.67648 53.4528-32.44032 103.05536-87.77728 109.7728z m6.67648 48.66048c83.02592-10.48576 142.1312-83.968 131.6864-164.08576-10.52672-80.15872-85.89312-137.4208-167.936-126.93504-83.02592 10.52672-142.17216 83.968-131.6864 164.12672 9.54368 80.15872 84.91008 137.4208 167.936 126.89408z m-271.9744-79.17568a19.78368 19.78368 0 0 1-5.69344-9.54368l-5.7344-47.7184c0-8.6016 6.67648-16.22016 15.27808-17.2032l26.70592-3.76832a29.696 29.696 0 0 0 23.87968-21.95456l9.54368-34.36544a28.2624 28.2624 0 0 0-8.6016-30.5152l-20.97152-16.22016c-7.65952-5.7344-8.6016-16.22016-2.8672-23.87968l28.59008-35.26656a25.43616 25.43616 0 0 1 13.39392-6.67648 16.54784 16.54784 0 0 1 13.35296 2.8672l20.97152 16.1792c8.6016 6.71744 23.87968 6.71744 32.44032 0.98304l31.49824-18.14528a28.42624 28.42624 0 0 0 15.27808-27.648l-2.8672-26.74688c-0.98304-4.75136 0.94208-8.6016 3.80928-12.41088a17.69472 17.69472 0 0 1 11.4688-6.67648l46.73536-5.7344a15.89248 15.89248 0 0 1 19.08736 13.39392l3.80928 27.648c0.94208 11.4688 11.4688 21.01248 22.9376 22.9376l35.26656 9.50272c11.4688 3.85024 23.83872 0 31.49824-8.6016l16.22016-20.97152c2.8672-3.80928 7.61856-4.75136 12.41088-5.7344a16.5888 16.5888 0 0 1 13.35296 2.8672l36.2496 26.74688c7.61856 5.7344 8.6016 16.22016 2.8672 23.83872l-16.22016 20.97152a25.8048 25.8048 0 0 0-0.94208 31.5392l18.10432 30.5152c5.7344 10.48576 16.22016 17.16224 28.63104 16.22016l26.70592-3.85024c4.79232-0.94208 9.54368 0 12.41088 2.8672 3.80928 2.8672 5.7344 6.67648 6.67648 11.4688l2.8672 44.8512a17.03936 17.03936 0 0 1-14.336 19.08736l-29.57312 5.7344a29.696 29.696 0 0 0-23.83872 21.9136l-9.54368 34.36544a28.2624 28.2624 0 0 0 8.6016 30.5152l20.97152 16.22016c7.65952 5.7344 8.6016 16.22016 2.8672 23.87968l-27.648 34.32448c-5.7344 7.65952-17.2032 8.6016-24.82176 2.8672l-21.01248-16.22016c-8.6016-6.67648-23.83872-6.67648-32.44032-0.94208l-31.45728 18.10432a28.34432 28.34432 0 0 0-16.22016 27.68896l2.8672 26.70592c0.94208 4.79232-0.98304 8.6016-3.85024 12.41088a17.69472 17.69472 0 0 1-11.4688 6.67648l-46.6944 5.7344c-4.79232 0.94208-9.58464 0-12.41088-2.8672a17.69472 17.69472 0 0 1-6.67648-11.4688l-2.8672-26.70592a27.40224 27.40224 0 0 0-21.95456-22.89664l-35.30752-9.54368a29.81888 29.81888 0 0 0-31.49824 8.6016l-16.22016 20.97152c-5.7344 7.65952-17.2032 8.6016-24.7808 2.8672l-36.29056-26.70592c-7.61856-5.7344-8.6016-16.22016-2.8672-23.83872l16.22016-21.01248a25.8048 25.8048 0 0 0 0.98304-31.49824l-18.14528-30.5152a30.59712 30.59712 0 0 0-28.63104-16.22016l-27.648 2.8672a15.1552 15.1552 0 0 1-12.41088-2.8672z"  ></path><path d="M811.729101 95.0272H108.486861A89.16992 89.16992 0 0 0 19.767501 183.78752v656.42496c0 48.66048 40.05888 88.76032 88.71936 88.76032h374.04672v-101.1712H177.217741a52.96128 52.96128 0 0 1-52.51072-52.4288v-351.15008c0-28.63104 23.87968-52.46976 52.51072-52.46976h565.78048c26.74688 0 48.70144 20.02944 51.52768 45.79328h104.98048v-234.7008a87.53152 87.53152 0 0 0-87.77728-87.81824zM218.218701 269.63968a21.58592 21.58592 0 0 1-21.9136 21.95456H144.777421a21.58592 21.58592 0 0 1-21.95456-21.95456V222.90432c0-12.41088 9.54368-21.95456 21.95456-21.95456H196.305101c12.36992 0 21.9136 9.54368 21.9136 21.95456v46.73536z m234.7008 0a21.58592 21.58592 0 0 1-21.9136 21.95456H305.995981a21.58592 21.58592 0 0 1-21.9136-21.95456V222.90432c0-12.41088 9.54368-21.95456 21.9136-21.95456h125.00992c12.41088 0 21.95456 9.54368 21.95456 21.95456v46.73536z"  ></path></symbol><symbol id="icon-down" viewBox="0 0 1024 1024"><path d="M736 480a32.042667 32.042667 0 0 0-45.312 0l-167.381333 167.381333a16.042667 16.042667 0 0 1-22.613334 0L333.312 480a32.042667 32.042667 0 0 0-45.312 45.312l178.688 178.688a64 64 0 0 0 90.496 0l178.816-178.688a32.042667 32.042667 0 0 0 0-45.312z"  ></path></symbol><symbol id="icon-search" viewBox="0 0 1024 1024"><path d="M942.144 855.36l-152.96-152.96a401.408 401.408 0 0 0-607.616-520.896 401.152 401.152 0 0 0 0 567.488 401.28 401.28 0 0 0 520.832 40.128l152.96 152.96a61.568 61.568 0 0 0 86.848 0 61.44 61.44 0 0 0 0-86.72z m-253.696-166.912a315.52 315.52 0 1 1-446.208-446.208 315.52 315.52 0 0 1 446.208 446.208z"  ></path></symbol><symbol id="icon-home" viewBox="0 0 1024 1024"><path d="M293.888 948.352v-290.944A72.704 72.704 0 0 1 366.72 584.704h290.88a72.704 72.704 0 0 1 72.768 72.704v290.944h218.176V336L512 75.52 75.712 335.744v612.48h218.24zM38.528 273.408L474.88 13.056a72.704 72.704 0 0 1 74.432 0l436.352 260.352a72.704 72.704 0 0 1 35.52 62.592v612.352a72.768 72.768 0 0 1-72.704 72.704H75.712a72.704 72.704 0 0 1-72.704-72.704V336A72.704 72.704 0 0 1 38.4 273.408z m328.128 384v290.944h290.88v-290.944H366.72z"  ></path></symbol><symbol id="icon-cloud" viewBox="0 0 1024 1024"><path d="M788.48 834.56H235.52a235.52 235.52 0 0 1-48.128-465.92 327.68 327.68 0 0 1 648.704 0 235.52 235.52 0 0 1-48.128 465.92h0.512zM235.52 465.92a133.12 133.12 0 0 0 0 266.24h552.96a133.12 133.12 0 1 0 0-266.24h-51.2v-51.2a225.28 225.28 0 0 0-450.56 0v51.2h-51.2z"  ></path></symbol><symbol id="icon-help" viewBox="0 0 1024 1024"><path d="M953.276415 0c14.847879 0 26.879782 11.519906 26.879781 25.599792v972.792096a26.303786 26.303786 0 0 1-26.879781 25.599792H90.883422A26.303786 26.303786 0 0 1 64.00364 998.391888V25.599792c0-14.079886 12.095902-25.599792 26.943781-25.599792h862.328994z m-80.831344 107.775124H171.778764v808.441432h700.666307V107.775124z"  ></path><path d="M789.501745 0v477.820118l-179.71054-62.719491-179.58254 62.719491V0h359.29308z m-107.839124 107.775124H537.983789v218.174228l71.807416-24.959798 71.871416 24.959798V107.775124z"  ></path></symbol><symbol id="icon-pin" viewBox="0 0 1024 1024"><path d="M885.312 347.392l-272.64-272.64a36.608 36.608 0 0 0-52.032 0L382.4 253.12A364.672 364.672 0 0 0 113.28 330.88a36.736 36.736 0 0 0-3.008 54.656l201.088 201.088-238.336 238.08a17.472 17.472 0 0 0-5.12 10.88l-3.776 41.152c-0.96 10.432 7.296 19.264 17.6 19.264 0.576 0 1.088 0 1.664-0.128l41.152-3.712a17.472 17.472 0 0 0 10.88-5.12l238.336-238.336 200.96 201.024a36.608 36.608 0 0 0 54.72-2.944 365.504 365.504 0 0 0 77.696-269.376l178.24-178.24a36.672 36.672 0 0 0 0-51.84z m-234.688 173.952l-27.136 27.072 4.224 38.08a287.616 287.616 0 0 1-33.664 170.304L203.392 365.888a286.208 286.208 0 0 1 170.24-33.664l38.08 4.224 27.136-27.136 147.904-147.968 211.904 211.904-148.032 148.096z"  ></path></symbol><symbol id="icon-copy" viewBox="0 0 1024 1024"><path d="M702.8224 0H144.2816A93.0816 93.0816 0 0 0 51.2 93.0816v651.6736h93.0816V93.0816h558.592V0z m139.6224 186.1632h-512a93.0816 93.0816 0 0 0-93.0816 93.1328v651.6224c0 51.4048 41.6768 93.0816 93.1328 93.0816h512a93.1328 93.1328 0 0 0 93.0816-93.0816V279.296a93.1328 93.1328 0 0 0-93.1328-93.1328z m-512 93.1328h512v651.6224h-512V279.296z"  ></path></symbol><symbol id="icon-link" viewBox="0 0 1024 1024"><path d="M607.957333 417.834667a192.128 192.128 0 0 0-19.584-16.896 38.826667 38.826667 0 1 0-47.146666 61.226666c3.669333 2.986667 7.253333 5.973333 10.666666 9.386667l3.157334 3.2c40.277333 40.192 28.288 109.525333-11.989334 149.802667l-171.904 171.818666a103.424 103.424 0 0 1-146.048 0l-3.2-3.2a103.253333 103.253333 0 0 1 0-146.005333l75.946667-75.946667a42.24 42.24 0 1 0-49.92-68.010666c-0.085333 0-0.085333 0-0.128-0.085334l-0.810667 0.768a42.496 42.496 0 0 0-8.021333 7.509334l-78.933333 73.813333a191.317333 191.317333 0 0 0 0 269.781333l3.242666 3.2a191.36 191.36 0 0 0 269.696 0l171.818667-171.861333c74.069333-74.197333 80.384-191.189333 6.272-265.344l-3.114667-3.157333z"  ></path><path d="M855.594667 165.802667l-3.2-3.2a191.274667 191.274667 0 0 0-269.653334 0L410.88 334.464c-74.197333 74.197333-78.250667 181.333333-4.096 255.573333l3.157333 3.072c3.370667 3.370667 6.826667 6.528 10.453334 9.6a36.693333 36.693333 0 0 0 8.96 7.296l0.085333 0.085334a36.693333 36.693333 0 0 0 51.285333-47.786667c-4.821333-10.922667-13.909333-17.536-20.181333-23.808l-3.157333-3.114667c-40.277333-40.277333-24.96-98.816 15.317333-139.093333l171.946667-171.818667a103.253333 103.253333 0 0 1 145.92 0l3.242666 3.157334c40.277333 40.277333 40.277333 105.813333 0 146.048l-75.690666 75.776a41.813333 41.813333 0 0 0 24.874666 75.52 41.685333 41.685333 0 0 0 21.930667-6.229334l0.170667 0.256 1.152-1.066666a41.984 41.984 0 0 0 9.557333-8.832l79.786667-73.6a191.232 191.232 0 0 0 0-269.653334z"  ></path></symbol><symbol id="icon-setting" viewBox="0 0 1024 1024"><path d="M662.3744 108.9536l118.6816 69.5296c-5.632 34.304-13.824 111.5136 16.896 165.7344 31.744 55.808 105.3696 87.9616 137.0624 99.2256 3.072 19.968 6.144 48.64 6.144 69.0688 0 18.944-3.072 46.592-6.144 69.0688-32.256 11.776-104.8576 43.4688-137.0624 99.7376-31.232 54.7328-23.04 131.9424-16.896 165.7344l-118.6816 69.5296c-28.16-23.04-88.9856-67.5328-150.3744-67.5328-61.9008 0-123.7504 45.056-150.8864 67.584l-119.1936-69.12c5.632-34.2528 13.824-111.4624-16.896-165.6832-31.6928-55.808-105.3184-88.0128-137.0624-99.2256-3.072-19.968-6.144-48.64-6.144-69.12 0-18.8928 3.072-46.4896 6.144-69.0176 32.256-11.776 104.8576-43.4688 137.1136-99.7376 31.232-54.7328 22.528-131.4304 16.896-165.7344l118.6304-69.5296c28.16 23.04 88.9856 67.4816 150.3744 67.4816 61.952 0 123.8016-45.0048 151.3984-67.9936z m-2.048-86.9888c-14.848 0-30.1568 5.632-40.9088 15.872-15.872 14.848-69.5808 57.2928-107.9296 57.2928-38.3488 0-92.0576-42.496-107.9296-57.2928a60.3136 60.3136 0 0 0-63.8976-11.264L184.6272 117.6064l-3.072 2.048c-17.92 13.312-27.0848 38.912-22.4768 61.44 5.12 20.9408 14.336 89.4976-5.12 123.2384C135.0144 338.1248 71.68 363.6736 51.2 370.3296c-20.48 6.656-38.4 26.624-41.984 48.0768C8.704 420.9664 0 474.112 0 513.024c0 38.912 8.704 92.5696 9.216 94.6176 3.584 21.504 21.504 41.984 41.9328 48.128 20.48 6.656 83.8656 32.7168 102.8096 65.9456 18.944 33.792 9.728 101.7856 5.12 123.2896-5.12 22.016 4.608 47.5648 22.528 61.3376l154.9824 91.5968 3.072 1.536a60.3136 60.3136 0 0 0 63.9488-11.264c15.8208-14.848 69.5296-57.2928 107.8784-57.2928 38.4 0 92.1088 42.496 107.9296 57.2928 10.752 9.728 26.112 15.36 40.96 15.36 7.68 0 15.872-1.536 22.9888-4.608l154.9824-90.5728 3.072-2.048c17.92-13.312 27.136-39.3728 22.528-61.3376-5.12-20.992-14.336-89.5488 5.12-123.2896 18.944-33.792 82.3296-59.8528 102.8096-65.9968 20.48-6.656 38.3488-26.624 41.9328-48.0768 0.512-2.56 9.216-55.7568 9.216-94.6176 0-38.912-8.704-92.5696-9.216-94.6176-3.584-21.504-21.504-41.984-41.984-48.128-20.48-6.656-83.8656-32.7168-102.8096-65.9456-18.944-33.792-9.728-101.7856-5.12-123.2896 5.12-22.016-4.608-47.5648-22.4768-61.3888L686.4384 28.16l-3.072-1.536c-7.168-3.072-15.36-4.608-23.04-4.608z"  ></path><path d="M511.488 369.8176a143.6672 143.6672 0 0 1 143.2576 143.2064 143.616 143.616 0 0 1-143.2576 143.2064 143.616 143.616 0 0 1-143.2064-143.2064A143.616 143.616 0 0 1 511.488 369.8176z m0-81.8688a225.0752 225.0752 0 1 0 0 450.1504 225.0752 225.0752 0 0 0 0-450.1504z"  ></path></symbol><symbol id="icon-github" viewBox="0 0 1024 1024"><path d="M512.265011 32.19456A491.52 491.52 0 0 0 20.294451 524.16512c0 217.4976 140.9024 401.57184 336.40448 466.7392 24.41216 4.87424 33.3824-10.60864 33.3824-23.63392 0-11.38688-0.8192-50.50368-0.8192-91.21792-136.8064 29.32736-165.35552-58.65472-165.35552-58.65472-21.95456-57.01632-54.55872-71.68-54.55872-71.68-44.81024-30.14656 3.2768-30.14656 3.2768-30.14656 49.68448 3.2768 75.73504 50.50368 75.73504 50.50368 43.99104 74.9568 114.85184 53.78048 143.36 40.71424 4.096-31.744 17.08032-53.73952 30.96576-65.9456-109.1584-11.42784-224.01024-53.78048-224.01024-242.72896 0-53.78048 19.53792-97.77152 50.50368-131.97312-4.9152-12.20608-21.99552-62.6688 4.9152-130.29376 0 0 41.49248-13.06624 135.168 50.46272a476.32384 476.32384 0 0 1 123.00288-16.26112c41.53344 0 83.88608 5.69344 123.00288 16.26112 93.67552-63.488 135.168-50.46272 135.168-50.46272 26.91072 67.584 9.8304 118.08768 4.9152 130.29376 31.78496 34.2016 50.50368 78.2336 50.50368 131.97312 0 188.94848-114.85184 230.48192-224.82944 242.72896 17.94048 15.48288 33.42336 44.76928 33.42336 91.21792 0 65.9456-0.8192 118.90688-0.8192 135.168 0 13.1072 8.97024 28.54912 33.3824 23.67488 195.50208-65.16736 336.40448-249.2416 336.40448-466.7392 0.8192-272.05632-219.9552-491.9296-491.15136-491.9296z"  ></path><path d="M206.785331 738.38592c-0.8192 2.4576-4.9152 3.2768-8.15104 1.6384-3.2768-1.6384-5.69344-4.9152-4.096-7.3728 0.8192-2.41664 4.9152-3.23584 8.192-1.6384 3.2768 1.6384 4.87424 4.9152 4.096 7.3728z m19.53792 21.99552c-2.4576 2.4576-7.33184 0.8192-9.74848-2.4576-3.2768-3.2768-4.096-8.15104-1.6384-10.56768 2.4576-2.4576 6.5536-0.8192 9.78944 2.4576 3.2768 4.05504 4.096 8.92928 1.6384 10.56768z m19.57888 28.50816c-3.2768 2.4576-8.192 0-10.60864-4.096-3.2768-4.096-3.2768-9.74848 0-11.38688 3.2768-2.4576 8.15104 0 10.60864 4.096 3.2768 4.05504 3.2768 8.92928 0 11.38688z m26.86976 27.68896c-2.4576 3.2768-8.15104 2.4576-13.02528-1.6384-4.096-4.096-5.7344-9.78944-2.4576-12.20608 2.4576-3.2768 8.15104-2.4576 13.02528 1.6384 4.096 3.2768 4.9152 8.92928 2.4576 12.20608z m36.6592 15.48288c-0.8192 4.096-6.5536 5.69344-12.24704 4.096-5.69344-1.6384-8.92928-6.5536-8.11008-9.8304 0.8192-4.05504 6.51264-5.69344 12.20608-4.05504 5.7344 1.6384 8.97024 5.7344 8.15104 9.78944z m39.89504 3.2768c0 4.05504-4.9152 7.29088-10.56768 7.29088-5.7344 0-10.60864-3.2768-10.60864-7.33184 0-4.096 4.9152-7.33184 10.60864-7.33184s10.56768 3.2768 10.56768 7.3728z m37.4784-6.5536c0.8192 4.096-3.2768 8.15104-8.97024 8.97024-5.7344 0.8192-10.56768-1.6384-11.38688-5.7344-0.8192-4.05504 3.2768-8.11008 8.92928-8.92928 5.7344-0.8192 10.60864 1.6384 11.42784 5.7344z"  ></path></symbol></svg>',function(t){var a=(a=document.getElementsByTagName("script"))[a.length-1],l=a.getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var c,o,h,i,e,m=function(a,l){l.parentNode.insertBefore(a,l)};if(l&&!t.__iconfont__svg__cssinject__){t.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(a){console&&console.log(a)}}c=function(){var a,l=document.createElement("div");l.innerHTML=t._iconfont_svg_string_4357075,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?m(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),c()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(h=c,i=t.document,e=!1,s(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,d())})}function d(){e||(e=!0,h())}function s(){try{i.documentElement.doScroll("left")}catch(a){return void setTimeout(s,50)}d()}}(window);
\ No newline at end of file
+window._iconfont_svg_string_4357075='<svg><symbol id="icon-loading" viewBox="0 0 1024 1024"><path d="M512 96a416 416 0 0 0 0 832V824a312 312 0 1 1 312-312h104A416 416 0 0 0 512 96z"  ></path></symbol><symbol id="icon-pinned" viewBox="0 0 1024 1024"><path d="M648.704 130.773333c8.490667 3.669333 16.213333 8.917333 22.698667 15.445334l191.573333 191.744a73.173333 73.173333 0 0 1-22.186667 118.613333l-67.84 30.037333-127.36 127.488-10.069333 140.245334a73.130667 73.130667 0 0 1-124.714667 46.421333l-123.648-123.776-210.730666 211.712-51.84-51.626667 210.858666-211.84-127.914666-128a73.130667 73.130667 0 0 1 46.293333-124.629333l144.213333-10.794667 125.098667-125.226666 29.397333-67.754667a73.173333 73.173333 0 0 1 96.170667-38.058667z"  ></path></symbol><symbol id="icon-more" viewBox="0 0 1024 1024"><path d="M144 512a80 80 0 1 0 160 0 80 80 0 0 0-160 0zM432 512a80 80 0 1 0 160 0 80 80 0 0 0-160 0zM720 512a80 80 0 1 0 160 0 80 80 0 0 0-160 0z"  ></path></symbol><symbol id="icon-pin1" viewBox="0 0 1024 1024"><path d="M711.626105 57.397895c10.725053 4.634947 20.48 11.264 28.672 19.509894l241.987369 242.202948a92.429474 92.429474 0 0 1-28.025263 149.827368l-85.692632 37.941895-160.87579 161.037474-12.719157 177.152a92.375579 92.375579 0 0 1-157.534316 58.637473l-156.186948-156.348631-266.186105 267.425684-65.482105-65.212632 266.347789-267.587368-161.576421-161.684211a92.375579 92.375579 0 0 1 58.47579-157.426526l182.16421-13.635368 158.019369-158.181053 37.133473-85.584842a92.429474 92.429474 0 0 1 121.478737-48.074105z m-36.702316 84.776421l-44.139789 101.753263-194.613895 194.937263-216.495158 16.114526 383.137685 383.407158 15.198315-211.429052 197.362527-197.632 101.537684-44.948211-241.987369-242.202947z"  ></path></symbol><symbol id="icon-smooth" viewBox="0 0 1024 1024"><path d="M533.12 10.666667a480 480 0 1 1 0 960 480 480 0 0 1 0-960z m0 96a384 384 0 1 0 0 768 384 384 0 0 0 0-768z"  ></path><path d="M449.066667 529.066667h38.4v38.4h-38.4v-38.4z m75.264 105.642666H389.12v-154.112c-22.357333-51.456-42.325333-124.373333-42.325333-220.288h58.666666c0 97.194667 23.04 167.338667 45.056 212.48h100.864v109.824c2.432 1.28 5.077333 2.816 7.68 4.138667 42.368 22.784 115.2 50.133333 222.933334 50.133333V695.466667c-120.064 0-203.861333-30.421333-257.536-60.8h-0.085334z"  ></path></symbol><symbol id="icon-chart" viewBox="0 0 1075 1024"><path d="M913.6128 792.0128H225.5872V167.936a8.0384 8.0384 0 0 0-7.9872-7.9872H161.5872A8.0384 8.0384 0 0 0 153.6 167.9872V856.064c0 4.4032 3.584 7.9872 7.9872 7.9872h752.0256c4.4032 0 7.9872-3.584 7.9872-7.9872v-56.0128a8.0384 8.0384 0 0 0-7.9872-7.9872z"  ></path><path d="M331.4176 637.696c3.072 3.072 8.0896 3.072 11.264 0l138.3424-137.5744 127.5904 128.3584c3.072 3.072 8.192 3.072 11.264 0l275.456-275.3024c3.072-3.072 3.072-8.192 0-11.264l-39.6288-39.6288a8.0384 8.0384 0 0 0-11.264 0L614.4 532.1728 487.0144 404.0704a8.0384 8.0384 0 0 0-11.3152 0l-183.808 182.6816c-3.072 3.072-3.072 8.192 0 11.264l39.5264 39.7312z"  ></path></symbol><symbol id="icon-charts" viewBox="0 0 1024 1024"><path d="M962.56 860.2112H137.472V111.9744A9.6256 9.6256 0 0 0 128 102.4H60.7744A9.6256 9.6256 0 0 0 51.2 111.9744V936.96c0 5.2736 4.3008 9.6256 9.5744 9.6256H962.56a9.6256 9.6256 0 0 0 9.6256-9.6256V869.888a9.6256 9.6256 0 0 0-9.6256-9.6256z"  ></path><path d="M234.7008 755.0976c3.0208 4.3008 8.9088 5.3248 13.312 2.304l191.5904-134.2464 124.4672 177.8176c3.072 4.2496 9.0624 5.3248 13.3632 2.304l381.7472-268.9024a9.6256 9.6256 0 0 0 2.304-13.312l-38.7072-54.9376a9.6256 9.6256 0 0 0-13.312-2.304l-318.8224 224.5632L466.432 510.7712a9.6256 9.6256 0 0 0-13.3632-2.304l-254.5664 178.176a9.6256 9.6256 0 0 0-2.304 13.4144l38.5536 54.9888z"  ></path><path d="M220.7232 520.1408c3.7376 3.6864 9.728 3.6864 13.568 0l165.8368-165.0176 152.9856 153.9584a9.6256 9.6256 0 0 0 13.568 0l330.24-330.0864a9.6256 9.6256 0 0 0 0-13.568l-47.5136-47.5136a9.6256 9.6256 0 0 0-13.5168 0l-275.8144 275.712-152.7808-153.7536a9.6256 9.6256 0 0 0-13.5168 0l-220.416 219.136a9.6256 9.6256 0 0 0 0 13.5168l47.36 47.616z"  ></path></symbol><symbol id="icon-pause" viewBox="0 0 1024 1024"><path d="M688 288H336a48 48 0 0 0-48 48v352a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V336a48 48 0 0 0-48-48z"  ></path></symbol><symbol id="icon-play" viewBox="0 0 1024 1024"><path d="M817.088 484.96l-512-323.744c-9.856-6.24-22.336-6.624-32.512-0.992A31.993 31.993 0 0 0 256 188.256v647.328c0 11.648 6.336 22.4 16.576 28.032A31.82 31.82 0 0 0 288 867.584a32.107 32.107 0 0 0 17.088-4.928l512-323.616A31.976 31.976 0 0 0 832 512a31.976 31.976 0 0 0-14.912-27.04z"  ></path></symbol><symbol id="icon-eye-close" viewBox="0 0 1228 1024"><path d="M1041.408 273.92c-131.328 163.2768-262.5024 242.4832-393.8816 242.4832-131.84 0-268.4416-79.7696-409.6-243.712a47.9744 47.9744 0 1 0-72.704 62.5664c157.696 183.296 318.464 277.0944 482.304 277.0944 164.4032 0 320.7168-94.3616 468.6336-278.3232a47.9744 47.9744 0 0 0-74.752-60.1088z"  ></path><path d="M303.616 461.6704l-91.4432 105.728a34.304 34.304 0 0 0 51.8656 44.8512l91.392-105.728a34.304 34.304 0 1 0-51.8656-44.8512z m184.5248 124.0576l-36.5568 146.2272a34.304 34.304 0 1 0 66.5088 16.64l36.5568-146.2272a34.304 34.304 0 0 0-66.5088-16.64z m265.3184 5.9904l51.4048 146.176a34.304 34.304 0 0 0 64.6656-22.7328l-51.4048-146.176a34.304 34.304 0 0 0-64.6656 22.7328z m186.5216-124.5184l105.728 105.728a34.304 34.304 0 0 0 48.4864-48.4864l-105.728-105.728a34.304 34.304 0 0 0-48.4864 48.4864z"  ></path></symbol><symbol id="icon-eye" viewBox="0 0 1228 1024"><path d="M614.4 832c-187.7504 0-355.2256-98.7136-502.0672-291.584A46.7456 46.7456 0 0 1 102.4 512c0-10.0352 3.4304-19.9168 9.9328-28.416C259.1744 290.7136 426.7008 192 614.4 192c187.7504 0 355.2256 98.7136 502.1184 291.584A46.7456 46.7456 0 0 1 1126.4 512a46.7456 46.7456 0 0 1-9.8816 28.416c-146.8928 192.8704-314.368 291.584-502.1184 291.584zM614.4 256c-155.392 0-299.3664 83.8656-432.128 256 132.7616 172.1344 276.736 256 432.128 256 155.4432 0 299.3664-83.8656 432.128-256-132.7616-172.1344-276.6848-256-432.128-256z m0 405.3504c-99.84 0-180.7872-66.8672-180.7872-149.3504 0-82.432 80.896-149.3504 180.7872-149.3504 99.84 0 180.7872 66.8672 180.7872 149.3504 0 82.432-80.896 149.3504-180.736 149.3504z m0-64c57.088 0 103.3216-38.2464 103.3216-85.3504S671.488 426.6496 614.4 426.6496c-57.0368 0-103.3216 38.2464-103.3216 85.3504s46.2848 85.3504 103.3216 85.3504z"  ></path></symbol><symbol id="icon-experiment" viewBox="0 0 1024 1024"><path d="M882.580211 421.295158a406.258526 406.258526 0 0 0-87.309474-129.509053A406.312421 406.312421 0 0 0 507.149474 172.463158a406.258526 406.258526 0 0 0-288.121263 119.322947A406.258526 406.258526 0 0 0 99.705263 579.907368c0 120.724211 53.032421 234.388211 145.408 312.050527l1.616842 1.293473a29.480421 29.480421 0 0 0 18.701474 6.790737h483.543579c6.844632 0 13.473684-2.425263 18.755368-6.790737l1.562948-1.293473a406.905263 406.905263 0 0 0 145.30021-312.050527c0-54.972632-10.778947-108.328421-32.013473-158.61221z m-148.58779 409.6H280.252632a337.542737 337.542737 0 0 1-111.454316-250.98779 335.764211 335.764211 0 0 1 99.112421-239.184842 336.087579 336.087579 0 0 1 239.184842-99.166315 335.764211 335.764211 0 0 1 239.184842 99.166315 336.087579 336.087579 0 0 1 99.166316 239.184842c0 96.040421-40.474947 186.906947-111.562105 251.041685z"  ></path><path d="M608.579368 453.955368a7.275789 7.275789 0 0 0-10.24 0L521.377684 530.863158a50.876632 50.876632 0 1 0 22.851369 85.207579 50.822737 50.822737 0 0 0 13.20421-49.205895l76.8-76.853895a7.275789 7.275789 0 0 0 0-10.24l-25.707789-25.761684zM487.154526 361.633684h40.04379c3.988211 0 7.275789-3.233684 7.275789-7.275789v-72.757895a7.275789 7.275789 0 0 0-7.275789-7.275789h-40.04379a7.275789 7.275789 0 0 0-7.275789 7.275789v72.757895c0 4.042105 3.233684 7.275789 7.275789 7.275789z m236.490106 198.332632v39.989895c0 3.988211 3.233684 7.275789 7.275789 7.275789h72.757895c3.988211 0 7.221895-3.287579 7.221895-7.275789v-40.04379a7.275789 7.275789 0 0 0-7.221895-7.275789h-72.757895a7.275789 7.275789 0 0 0-7.275789 7.275789z m11.533473-179.415579l-28.294737-28.240842a7.275789 7.275789 0 0 0-10.24 0l-51.523368 51.469473a7.275789 7.275789 0 0 0 0 10.24l28.294737 28.294737a7.275789 7.275789 0 0 0 10.24 0l51.523368-51.469473a7.275789 7.275789 0 0 0 0-10.24z m-417.091368-28.240842a7.275789 7.275789 0 0 0-10.24 0l-28.348632 28.240842a7.275789 7.275789 0 0 0 0 10.293895l51.523369 51.469473a7.275789 7.275789 0 0 0 10.24 0l28.294737-28.294737a7.275789 7.275789 0 0 0 0-10.24l-51.469474-51.469473z m-38.265263 200.326737h-72.757895a7.275789 7.275789 0 0 0-7.27579 7.275789v40.04379c0 3.988211 3.233684 7.275789 7.27579 7.275789h72.757895c3.988211 0 7.275789-3.287579 7.275789-7.275789v-40.04379a7.275789 7.275789 0 0 0-7.275789-7.275789z"  ></path></symbol><symbol id="icon-runs" viewBox="0 0 1024 1024"><path d="M51.2 152.0128A100.864 100.864 0 0 1 152.0128 51.2H871.936A100.864 100.864 0 0 1 972.8 152.0128V871.936A100.8128 100.8128 0 0 1 871.9872 972.8H152.064A100.8128 100.8128 0 0 1 51.2 871.9872V152.064z m374.4256 273.6128v460.8h446.3616a14.3872 14.3872 0 0 0 14.4384-14.4384V425.6256h-460.8z m460.8-86.4256V152.0128a14.3872 14.3872 0 0 0-14.4384-14.3872H425.6256v201.5744h460.8zM137.6256 425.6256v446.3616c0 7.936 6.4 14.4384 14.336 14.4384h187.2384v-460.8H137.5744z m201.5744-86.4256V137.5744H152.0128a14.3872 14.3872 0 0 0-14.3872 14.4384v187.1872h201.5744z"  ></path></symbol><symbol id="icon-success" viewBox="0 0 1024 1024"><path d="M515.072 40.384C256.768 40.384 46.592 250.624 46.592 508.928c0 258.368 210.176 468.544 468.48 468.544 258.368 0 468.544-210.176 468.544-468.48C983.68 250.56 773.44 40.32 515.2 40.32z m0 875.648a407.552 407.552 0 0 1-407.04-407.04 407.552 407.552 0 0 1 407.04-407.168 407.552 407.552 0 0 1 407.104 407.104 407.552 407.552 0 0 1-407.04 407.104z"  ></path><path d="M678.272 363.2L451.968 589.504 352 489.408a30.72 30.72 0 1 0-43.456 43.456l121.792 121.792a30.72 30.72 0 0 0 43.456 0l248-248a30.72 30.72 0 1 0-43.52-43.456z"  ></path></symbol><symbol id="icon-error" viewBox="0 0 1024 1024"><path d="M512 42.688a469.312 469.312 0 1 1 0 938.624A469.312 469.312 0 0 1 512 42.688z m0 64a405.376 405.376 0 1 0 0 810.688A405.376 405.376 0 0 0 512 106.624z m-104.704 256a8.512 8.512 0 0 1 6.016 2.432L512 463.808l98.688-98.688a8.512 8.512 0 0 1 6.08-2.496h66.304a8.512 8.512 0 0 1 6.08 14.592l-131.84 131.84 137.6 137.664a8.576 8.576 0 0 1-6.016 14.592H622.528a8.512 8.512 0 0 1-6.016-2.496L512 554.304l-104.512 104.512a8.512 8.512 0 0 1-6.016 2.56H335.104a8.576 8.576 0 0 1-6.016-14.656l137.664-137.6-131.84-131.84a8.512 8.512 0 0 1 6.016-14.592h66.368z"  ></path></symbol><symbol id="icon-circle-fill" viewBox="0 0 1024 1024"><path d="M512 512m-384 0a384 384 0 1 0 768 0 384 384 0 1 0-768 0Z"  ></path></symbol><symbol id="icon-model" viewBox="0 0 1075 1024"><path d="M539.5456 921.6c-5.12 0-10.24-1.28-14.8992-3.8912l-330.496-189.952a29.7984 29.7984 0 0 1-14.9504-25.856V322.2016c0-10.5984 5.7344-20.48 14.9504-25.8048l330.496-189.952a29.7984 29.7984 0 0 1 29.8496 0l330.496 189.952c9.216 5.376 14.9504 15.104 14.9504 25.8048v379.8528c0 10.5472-5.7344 20.48-14.9504 25.8048l-330.496 189.8496a30.5152 30.5152 0 0 1-14.9504 3.8912z m-300.6464-236.6976l300.6464 172.7488 300.6464-172.7488v-345.6l-300.6464-172.7488-300.6464 172.7488v345.6z m300.6464-143.1552a29.952 29.952 0 0 1-14.8992-3.9936L287.8976 401.8688a29.696 29.696 0 0 1-11.008-40.704 30.0032 30.0032 0 0 1 40.8576-10.9056l236.7488 135.9872a29.696 29.696 0 0 1-14.9504 55.552z m0 272.1792a29.7984 29.7984 0 0 1-29.8496-29.7472v-254.8736l-221.5424-127.488s-0.1536 0-0.1536-0.1024L194.2528 347.8528A29.696 29.696 0 0 1 183.2448 307.2a29.952 29.952 0 0 1 40.8576-10.9056l330.496 189.952c9.216 5.376 14.9504 15.104 14.9504 25.8048v272.0256a30.0032 30.0032 0 0 1-30.0032 29.7984z m0 107.6736a29.7984 29.7984 0 0 1-29.8496-29.696V512c0-16.384 13.3632-29.696 29.8496-29.696 16.4864 0 29.8496 13.312 29.8496 29.696v379.8528a29.696 29.696 0 0 1-29.8496 29.696z m0-379.8016a29.696 29.696 0 0 1-14.9504-55.5008l330.5472-190.0032a30.0032 30.0032 0 0 1 40.8064 10.9056 29.696 29.696 0 0 1-10.9568 40.6528l-330.496 190.0032a29.184 29.184 0 0 1-14.9504 3.8912z"  ></path></symbol><symbol id="icon-logs" viewBox="0 0 1075 1024"><path d="M238.9504 298.6496a42.6496 42.6496 0 1 0 0-85.2992 42.6496 42.6496 0 0 0 0 85.2992zM409.6 224a32 32 0 0 0 0 64h426.6496a32 32 0 1 0 0-64H409.6zM409.6 736a32 32 0 1 0 0 64h426.6496a32 32 0 1 0 0-64H409.6zM377.6 512c0-17.664 14.336-32 32-32h426.6496a32 32 0 1 1 0 64H409.6A32 32 0 0 1 377.6 512zM238.9504 554.6496a42.6496 42.6496 0 1 0 0-85.2992 42.6496 42.6496 0 0 0 0 85.2992zM281.6 768a42.6496 42.6496 0 1 1-85.3504 0A42.6496 42.6496 0 0 1 281.6 768z"  ></path></symbol><symbol id="icon-download" viewBox="0 0 1024 1024"><path d="M943.766588 737.581176c-1.204706-28.912941-20.178824-44.935529-45.17647-44.333176-24.696471 0.602353-41.080471 16.865882-43.369412 46.441412-1.746824 21.805176-0.301176 43.791059-0.783059 65.65647-1.204706 54.874353-13.010824 67.584-67.945412 68.668236-52.826353 1.024-105.773176 0.361412-158.659764 0.361411-122.157176 0-244.314353 0.060235-366.531765-0.12047-84.148706-0.060235-91.437176-7.348706-91.858824-89.148235 0-14.576941 0.662588-29.274353-0.602353-43.730824-2.891294-30.840471-17.347765-46.863059-41.803294-48.188235-26.383059-1.566118-45.658353 16.384-47.646117 48.188235-1.807059 29.033412-0.783059 58.247529-0.602353 87.461647 0.602353 94.448941 42.465882 136.854588 136.914823 137.336471 98.484706 0.602353 196.969412 0.180706 295.454118 0.180706h87.521882c74.752 0 149.564235 1.024 224.316236-0.421648 65.897412-1.204706 114.085647-39.333647 119.627294-97.159529 4.216471-43.369412 2.951529-87.521882 1.14447-131.192471z"  ></path><path d="M179.139765 447.186824l282.081882 282.142117 11.625412 11.565177c15.058824 15.36 32.768 23.973647 54.151529 15.902117a45.296941 45.296941 0 0 0 16.564706-11.143529c2.951529-2.048 5.842824-4.276706 8.432941-6.806588 48.308706-46.983529 254.313412-253.650824 301.899294-301.417412 5.12-5.180235 9.999059-10.661647 14.034824-16.685177 12.950588-19.215059 11.203765-38.068706-4.216471-54.874353-15.661176-17.227294-35.418353-17.950118-54.874353-8.432941-9.456941 4.698353-17.287529 13.251765-24.997647 20.901647-31.984941 31.744-147.877647 147.516235-225.40047 225.15953V239.495529c0-36.442353 1.204706-72.944941-0.602353-109.266823-1.746824-33.792-18.070588-51.019294-44.513883-51.862588-27.105882-0.903529-43.489882 15.600941-47.164235 48.850823-1.385412 12.649412-0.602353 25.479529-0.662588 38.249412v420.321882l-12.528941 5.481412-72.282353-71.981176c-50.236235-50.236235-99.870118-101.135059-151.009883-150.40753-23.070118-22.287059-49.874824-22.648471-68.246588-5.12-19.817412 18.853647-19.094588 41.321412 2.469647 67.704471 4.577882 5.662118 10.059294 10.541176 15.23953 15.661176z"  ></path></symbol><symbol id="icon-sidebar" viewBox="0 0 1024 1024"><path d="M116.14 761.521h788.995v78.926H116.14v-78.926zM550.058 485.37h355.078v78.926H550.057v-78.926z m0-276.152h355.078v78.926H550.057v-78.926zM130.818 406.443L354.061 183.29l55.81 55.81L186.63 462.255l-55.81-55.81z"  ></path><path d="M351.688 629.686L128.445 406.443l55.81-55.81L407.41 573.875l-55.723 55.81z"  ></path></symbol><symbol id="icon-trash" viewBox="0 0 1024 1024"><path d="M602.232471 753.061647a30.057412 30.057412 0 0 1-30.117647-30.117647V391.529412a30.057412 30.057412 0 1 1 60.235294 0v331.233882a30.177882 30.177882 0 0 1-30.117647 30.298353zM421.586824 753.061647a30.057412 30.057412 0 0 1-30.117648-30.117647V391.529412a30.057412 30.057412 0 1 1 60.235295 0v331.233882a30.177882 30.177882 0 0 1-30.117647 30.298353zM903.529412 240.941176H752.941176V180.705882c0-49.874824-40.116706-90.352941-89.630117-90.352941H361.351529A90.352941 90.352941 0 0 0 271.058824 180.705882v60.235294H120.470588a30.057412 30.057412 0 1 0 0 60.235295H903.529412a30.057412 30.057412 0 1 0 0-60.235295zM331.294118 180.705882c0-16.504471 13.552941-30.117647 30.117647-30.117647h301.899294c16.504471 0 29.455059 13.251765 29.455059 30.117647v60.235294H331.233882V180.705882z"  ></path><path d="M722.823529 933.647059H301.357176a90.352941 90.352941 0 0 1-90.352941-90.352941V391.228235a30.057412 30.057412 0 1 1 60.235294 0v452.186353a30.117647 30.117647 0 0 0 30.117647 30.117647h421.707295c16.685176 0 30.117647-13.432471 30.117647-30.117647V392.312471a30.057412 30.057412 0 1 1 60.235294 0V843.294118a90.714353 90.714353 0 0 1-90.473412 90.352941z"  ></path></symbol><symbol id="icon-modify" viewBox="0 0 1024 1024"><path d="M65.250485 1015.627294a40.176941 40.176941 0 0 1 0-79.751529h893.409882a40.176941 40.176941 0 0 1 0 79.751529H65.250485zM801.084838 78.787765l89.931294 89.991529a63.849412 63.849412 0 0 1 0 89.99153l-570.488471 568.621176a63.849412 63.849412 0 0 1-45.357176 18.492235H156.567191a31.924706 31.924706 0 0 1-31.924706-31.924706V692.103529a63.849412 63.849412 0 0 1 18.492235-45.296941l568.018824-568.018823a63.849412 63.849412 0 0 1 89.991529 0zM204.333779 698.488471v67.644235h67.644235l552.056471-552.056471-67.644236-68.246588-552.05647 552.658824z"  ></path></symbol><symbol id="icon-info" viewBox="0 0 1024 1024"><path d="M512 958.0032c-245.9136 0-446.0032-200.0384-446.0032-446.0032 0-245.9136 200.0896-446.0032 445.952-446.0032 246.016 0 446.0544 200.0384 446.0544 446.0032S757.9648 958.0032 512 958.0032zM512 130.048c-210.688 0-382.0032 171.3664-382.0032 382.0032 0 210.6368 171.3152 382.0032 381.952 382.0032 210.688 0 382.0544-171.3664 382.0544-382.0032 0-210.6368-171.3664-382.0032-382.0032-382.0032z"  ></path><path d="M464.0256 304.0256a48.0256 48.0256 0 1 0 96 0 48.0256 48.0256 0 0 0-96.0512 0zM512 768a32 32 0 0 1-32-32V448a32 32 0 0 1 64 0v288c0 17.7152-14.336 32-32 32z"  ></path></symbol><symbol id="icon-close" viewBox="0 0 1024 1024"><path d="M587.264 506.197333l397.141333-397.226666a52.053333 52.053333 0 0 0 0-73.130667L982.186667 33.621333a51.968 51.968 0 0 0-73.130667 0L511.914667 431.445333 114.858667 33.621333a52.053333 52.053333 0 0 0-73.130667 0L39.594667 35.84a51.029333 51.029333 0 0 0 0 73.130667l397.056 397.226666-397.056 397.226667a52.053333 52.053333 0 0 0 0 73.130667l2.133333 2.218666a51.968 51.968 0 0 0 73.130667 0L512 581.546667l397.141333 397.226666a51.968 51.968 0 0 0 73.130667 0l2.133333-2.133333a52.053333 52.053333 0 0 0 0-73.130667L587.264 506.197333z"  ></path></symbol><symbol id="icon-zoom" viewBox="0 0 1024 1024"><path d="M429.91 872.79h-211.2l232.106-232.107a43.947 43.947 0 1 0-62.208-62.166L152.747 814.208V604.8a43.99 43.99 0 0 0-87.979 0v312.021c0 24.278 19.67 43.947 43.99 43.947h320.98a43.99 43.99 0 0 0 0.129-87.979zM915.882 64.852H594.9a43.99 43.99 0 0 0 0 87.979h211.115l-232.15 232.021a43.947 43.947 0 1 0 62.209 62.208l235.69-235.733v209.365a43.99 43.99 0 0 0 87.979 0V108.715a43.819 43.819 0 0 0-43.904-43.947z"  ></path></symbol><symbol id="icon-config" viewBox="0 0 1024 1024"><path d="M750.657741 768.65536c-55.33696 6.67648-105.92256-30.5152-112.59904-83.968-6.67648-53.41184 32.44032-103.05536 87.77728-109.73184 55.33696-6.67648 105.92256 30.55616 112.59904 83.968 6.67648 53.4528-32.44032 103.05536-87.77728 109.7728z m6.67648 48.66048c83.02592-10.48576 142.1312-83.968 131.6864-164.08576-10.52672-80.15872-85.89312-137.4208-167.936-126.93504-83.02592 10.52672-142.17216 83.968-131.6864 164.12672 9.54368 80.15872 84.91008 137.4208 167.936 126.89408z m-271.9744-79.17568a19.78368 19.78368 0 0 1-5.69344-9.54368l-5.7344-47.7184c0-8.6016 6.67648-16.22016 15.27808-17.2032l26.70592-3.76832a29.696 29.696 0 0 0 23.87968-21.95456l9.54368-34.36544a28.2624 28.2624 0 0 0-8.6016-30.5152l-20.97152-16.22016c-7.65952-5.7344-8.6016-16.22016-2.8672-23.87968l28.59008-35.26656a25.43616 25.43616 0 0 1 13.39392-6.67648 16.54784 16.54784 0 0 1 13.35296 2.8672l20.97152 16.1792c8.6016 6.71744 23.87968 6.71744 32.44032 0.98304l31.49824-18.14528a28.42624 28.42624 0 0 0 15.27808-27.648l-2.8672-26.74688c-0.98304-4.75136 0.94208-8.6016 3.80928-12.41088a17.69472 17.69472 0 0 1 11.4688-6.67648l46.73536-5.7344a15.89248 15.89248 0 0 1 19.08736 13.39392l3.80928 27.648c0.94208 11.4688 11.4688 21.01248 22.9376 22.9376l35.26656 9.50272c11.4688 3.85024 23.83872 0 31.49824-8.6016l16.22016-20.97152c2.8672-3.80928 7.61856-4.75136 12.41088-5.7344a16.5888 16.5888 0 0 1 13.35296 2.8672l36.2496 26.74688c7.61856 5.7344 8.6016 16.22016 2.8672 23.83872l-16.22016 20.97152a25.8048 25.8048 0 0 0-0.94208 31.5392l18.10432 30.5152c5.7344 10.48576 16.22016 17.16224 28.63104 16.22016l26.70592-3.85024c4.79232-0.94208 9.54368 0 12.41088 2.8672 3.80928 2.8672 5.7344 6.67648 6.67648 11.4688l2.8672 44.8512a17.03936 17.03936 0 0 1-14.336 19.08736l-29.57312 5.7344a29.696 29.696 0 0 0-23.83872 21.9136l-9.54368 34.36544a28.2624 28.2624 0 0 0 8.6016 30.5152l20.97152 16.22016c7.65952 5.7344 8.6016 16.22016 2.8672 23.87968l-27.648 34.32448c-5.7344 7.65952-17.2032 8.6016-24.82176 2.8672l-21.01248-16.22016c-8.6016-6.67648-23.83872-6.67648-32.44032-0.94208l-31.45728 18.10432a28.34432 28.34432 0 0 0-16.22016 27.68896l2.8672 26.70592c0.94208 4.79232-0.98304 8.6016-3.85024 12.41088a17.69472 17.69472 0 0 1-11.4688 6.67648l-46.6944 5.7344c-4.79232 0.94208-9.58464 0-12.41088-2.8672a17.69472 17.69472 0 0 1-6.67648-11.4688l-2.8672-26.70592a27.40224 27.40224 0 0 0-21.95456-22.89664l-35.30752-9.54368a29.81888 29.81888 0 0 0-31.49824 8.6016l-16.22016 20.97152c-5.7344 7.65952-17.2032 8.6016-24.7808 2.8672l-36.29056-26.70592c-7.61856-5.7344-8.6016-16.22016-2.8672-23.83872l16.22016-21.01248a25.8048 25.8048 0 0 0 0.98304-31.49824l-18.14528-30.5152a30.59712 30.59712 0 0 0-28.63104-16.22016l-27.648 2.8672a15.1552 15.1552 0 0 1-12.41088-2.8672z"  ></path><path d="M811.729101 95.0272H108.486861A89.16992 89.16992 0 0 0 19.767501 183.78752v656.42496c0 48.66048 40.05888 88.76032 88.71936 88.76032h374.04672v-101.1712H177.217741a52.96128 52.96128 0 0 1-52.51072-52.4288v-351.15008c0-28.63104 23.87968-52.46976 52.51072-52.46976h565.78048c26.74688 0 48.70144 20.02944 51.52768 45.79328h104.98048v-234.7008a87.53152 87.53152 0 0 0-87.77728-87.81824zM218.218701 269.63968a21.58592 21.58592 0 0 1-21.9136 21.95456H144.777421a21.58592 21.58592 0 0 1-21.95456-21.95456V222.90432c0-12.41088 9.54368-21.95456 21.95456-21.95456H196.305101c12.36992 0 21.9136 9.54368 21.9136 21.95456v46.73536z m234.7008 0a21.58592 21.58592 0 0 1-21.9136 21.95456H305.995981a21.58592 21.58592 0 0 1-21.9136-21.95456V222.90432c0-12.41088 9.54368-21.95456 21.9136-21.95456h125.00992c12.41088 0 21.95456 9.54368 21.95456 21.95456v46.73536z"  ></path></symbol><symbol id="icon-down" viewBox="0 0 1024 1024"><path d="M736 480a32.042667 32.042667 0 0 0-45.312 0l-167.381333 167.381333a16.042667 16.042667 0 0 1-22.613334 0L333.312 480a32.042667 32.042667 0 0 0-45.312 45.312l178.688 178.688a64 64 0 0 0 90.496 0l178.816-178.688a32.042667 32.042667 0 0 0 0-45.312z"  ></path></symbol><symbol id="icon-search" viewBox="0 0 1024 1024"><path d="M942.144 855.36l-152.96-152.96a401.408 401.408 0 0 0-607.616-520.896 401.152 401.152 0 0 0 0 567.488 401.28 401.28 0 0 0 520.832 40.128l152.96 152.96a61.568 61.568 0 0 0 86.848 0 61.44 61.44 0 0 0 0-86.72z m-253.696-166.912a315.52 315.52 0 1 1-446.208-446.208 315.52 315.52 0 0 1 446.208 446.208z"  ></path></symbol><symbol id="icon-home" viewBox="0 0 1024 1024"><path d="M293.888 948.352v-290.944A72.704 72.704 0 0 1 366.72 584.704h290.88a72.704 72.704 0 0 1 72.768 72.704v290.944h218.176V336L512 75.52 75.712 335.744v612.48h218.24zM38.528 273.408L474.88 13.056a72.704 72.704 0 0 1 74.432 0l436.352 260.352a72.704 72.704 0 0 1 35.52 62.592v612.352a72.768 72.768 0 0 1-72.704 72.704H75.712a72.704 72.704 0 0 1-72.704-72.704V336A72.704 72.704 0 0 1 38.4 273.408z m328.128 384v290.944h290.88v-290.944H366.72z"  ></path></symbol><symbol id="icon-cloud" viewBox="0 0 1024 1024"><path d="M788.48 834.56H235.52a235.52 235.52 0 0 1-48.128-465.92 327.68 327.68 0 0 1 648.704 0 235.52 235.52 0 0 1-48.128 465.92h0.512zM235.52 465.92a133.12 133.12 0 0 0 0 266.24h552.96a133.12 133.12 0 1 0 0-266.24h-51.2v-51.2a225.28 225.28 0 0 0-450.56 0v51.2h-51.2z"  ></path></symbol><symbol id="icon-help" viewBox="0 0 1024 1024"><path d="M953.276415 0c14.847879 0 26.879782 11.519906 26.879781 25.599792v972.792096a26.303786 26.303786 0 0 1-26.879781 25.599792H90.883422A26.303786 26.303786 0 0 1 64.00364 998.391888V25.599792c0-14.079886 12.095902-25.599792 26.943781-25.599792h862.328994z m-80.831344 107.775124H171.778764v808.441432h700.666307V107.775124z"  ></path><path d="M789.501745 0v477.820118l-179.71054-62.719491-179.58254 62.719491V0h359.29308z m-107.839124 107.775124H537.983789v218.174228l71.807416-24.959798 71.871416 24.959798V107.775124z"  ></path></symbol><symbol id="icon-pin" viewBox="0 0 1024 1024"><path d="M885.312 347.392l-272.64-272.64a36.608 36.608 0 0 0-52.032 0L382.4 253.12A364.672 364.672 0 0 0 113.28 330.88a36.736 36.736 0 0 0-3.008 54.656l201.088 201.088-238.336 238.08a17.472 17.472 0 0 0-5.12 10.88l-3.776 41.152c-0.96 10.432 7.296 19.264 17.6 19.264 0.576 0 1.088 0 1.664-0.128l41.152-3.712a17.472 17.472 0 0 0 10.88-5.12l238.336-238.336 200.96 201.024a36.608 36.608 0 0 0 54.72-2.944 365.504 365.504 0 0 0 77.696-269.376l178.24-178.24a36.672 36.672 0 0 0 0-51.84z m-234.688 173.952l-27.136 27.072 4.224 38.08a287.616 287.616 0 0 1-33.664 170.304L203.392 365.888a286.208 286.208 0 0 1 170.24-33.664l38.08 4.224 27.136-27.136 147.904-147.968 211.904 211.904-148.032 148.096z"  ></path></symbol><symbol id="icon-copy" viewBox="0 0 1024 1024"><path d="M702.8224 0H144.2816A93.0816 93.0816 0 0 0 51.2 93.0816v651.6736h93.0816V93.0816h558.592V0z m139.6224 186.1632h-512a93.0816 93.0816 0 0 0-93.0816 93.1328v651.6224c0 51.4048 41.6768 93.0816 93.1328 93.0816h512a93.1328 93.1328 0 0 0 93.0816-93.0816V279.296a93.1328 93.1328 0 0 0-93.1328-93.1328z m-512 93.1328h512v651.6224h-512V279.296z"  ></path></symbol><symbol id="icon-link" viewBox="0 0 1024 1024"><path d="M607.957333 417.834667a192.128 192.128 0 0 0-19.584-16.896 38.826667 38.826667 0 1 0-47.146666 61.226666c3.669333 2.986667 7.253333 5.973333 10.666666 9.386667l3.157334 3.2c40.277333 40.192 28.288 109.525333-11.989334 149.802667l-171.904 171.818666a103.424 103.424 0 0 1-146.048 0l-3.2-3.2a103.253333 103.253333 0 0 1 0-146.005333l75.946667-75.946667a42.24 42.24 0 1 0-49.92-68.010666c-0.085333 0-0.085333 0-0.128-0.085334l-0.810667 0.768a42.496 42.496 0 0 0-8.021333 7.509334l-78.933333 73.813333a191.317333 191.317333 0 0 0 0 269.781333l3.242666 3.2a191.36 191.36 0 0 0 269.696 0l171.818667-171.861333c74.069333-74.197333 80.384-191.189333 6.272-265.344l-3.114667-3.157333z"  ></path><path d="M855.594667 165.802667l-3.2-3.2a191.274667 191.274667 0 0 0-269.653334 0L410.88 334.464c-74.197333 74.197333-78.250667 181.333333-4.096 255.573333l3.157333 3.072c3.370667 3.370667 6.826667 6.528 10.453334 9.6a36.693333 36.693333 0 0 0 8.96 7.296l0.085333 0.085334a36.693333 36.693333 0 0 0 51.285333-47.786667c-4.821333-10.922667-13.909333-17.536-20.181333-23.808l-3.157333-3.114667c-40.277333-40.277333-24.96-98.816 15.317333-139.093333l171.946667-171.818667a103.253333 103.253333 0 0 1 145.92 0l3.242666 3.157334c40.277333 40.277333 40.277333 105.813333 0 146.048l-75.690666 75.776a41.813333 41.813333 0 0 0 24.874666 75.52 41.685333 41.685333 0 0 0 21.930667-6.229334l0.170667 0.256 1.152-1.066666a41.984 41.984 0 0 0 9.557333-8.832l79.786667-73.6a191.232 191.232 0 0 0 0-269.653334z"  ></path></symbol><symbol id="icon-setting" viewBox="0 0 1024 1024"><path d="M662.3744 108.9536l118.6816 69.5296c-5.632 34.304-13.824 111.5136 16.896 165.7344 31.744 55.808 105.3696 87.9616 137.0624 99.2256 3.072 19.968 6.144 48.64 6.144 69.0688 0 18.944-3.072 46.592-6.144 69.0688-32.256 11.776-104.8576 43.4688-137.0624 99.7376-31.232 54.7328-23.04 131.9424-16.896 165.7344l-118.6816 69.5296c-28.16-23.04-88.9856-67.5328-150.3744-67.5328-61.9008 0-123.7504 45.056-150.8864 67.584l-119.1936-69.12c5.632-34.2528 13.824-111.4624-16.896-165.6832-31.6928-55.808-105.3184-88.0128-137.0624-99.2256-3.072-19.968-6.144-48.64-6.144-69.12 0-18.8928 3.072-46.4896 6.144-69.0176 32.256-11.776 104.8576-43.4688 137.1136-99.7376 31.232-54.7328 22.528-131.4304 16.896-165.7344l118.6304-69.5296c28.16 23.04 88.9856 67.4816 150.3744 67.4816 61.952 0 123.8016-45.0048 151.3984-67.9936z m-2.048-86.9888c-14.848 0-30.1568 5.632-40.9088 15.872-15.872 14.848-69.5808 57.2928-107.9296 57.2928-38.3488 0-92.0576-42.496-107.9296-57.2928a60.3136 60.3136 0 0 0-63.8976-11.264L184.6272 117.6064l-3.072 2.048c-17.92 13.312-27.0848 38.912-22.4768 61.44 5.12 20.9408 14.336 89.4976-5.12 123.2384C135.0144 338.1248 71.68 363.6736 51.2 370.3296c-20.48 6.656-38.4 26.624-41.984 48.0768C8.704 420.9664 0 474.112 0 513.024c0 38.912 8.704 92.5696 9.216 94.6176 3.584 21.504 21.504 41.984 41.9328 48.128 20.48 6.656 83.8656 32.7168 102.8096 65.9456 18.944 33.792 9.728 101.7856 5.12 123.2896-5.12 22.016 4.608 47.5648 22.528 61.3376l154.9824 91.5968 3.072 1.536a60.3136 60.3136 0 0 0 63.9488-11.264c15.8208-14.848 69.5296-57.2928 107.8784-57.2928 38.4 0 92.1088 42.496 107.9296 57.2928 10.752 9.728 26.112 15.36 40.96 15.36 7.68 0 15.872-1.536 22.9888-4.608l154.9824-90.5728 3.072-2.048c17.92-13.312 27.136-39.3728 22.528-61.3376-5.12-20.992-14.336-89.5488 5.12-123.2896 18.944-33.792 82.3296-59.8528 102.8096-65.9968 20.48-6.656 38.3488-26.624 41.9328-48.0768 0.512-2.56 9.216-55.7568 9.216-94.6176 0-38.912-8.704-92.5696-9.216-94.6176-3.584-21.504-21.504-41.984-41.984-48.128-20.48-6.656-83.8656-32.7168-102.8096-65.9456-18.944-33.792-9.728-101.7856-5.12-123.2896 5.12-22.016-4.608-47.5648-22.4768-61.3888L686.4384 28.16l-3.072-1.536c-7.168-3.072-15.36-4.608-23.04-4.608z"  ></path><path d="M511.488 369.8176a143.6672 143.6672 0 0 1 143.2576 143.2064 143.616 143.616 0 0 1-143.2576 143.2064 143.616 143.616 0 0 1-143.2064-143.2064A143.616 143.616 0 0 1 511.488 369.8176z m0-81.8688a225.0752 225.0752 0 1 0 0 450.1504 225.0752 225.0752 0 0 0 0-450.1504z"  ></path></symbol><symbol id="icon-github" viewBox="0 0 1024 1024"><path d="M512.265011 32.19456A491.52 491.52 0 0 0 20.294451 524.16512c0 217.4976 140.9024 401.57184 336.40448 466.7392 24.41216 4.87424 33.3824-10.60864 33.3824-23.63392 0-11.38688-0.8192-50.50368-0.8192-91.21792-136.8064 29.32736-165.35552-58.65472-165.35552-58.65472-21.95456-57.01632-54.55872-71.68-54.55872-71.68-44.81024-30.14656 3.2768-30.14656 3.2768-30.14656 49.68448 3.2768 75.73504 50.50368 75.73504 50.50368 43.99104 74.9568 114.85184 53.78048 143.36 40.71424 4.096-31.744 17.08032-53.73952 30.96576-65.9456-109.1584-11.42784-224.01024-53.78048-224.01024-242.72896 0-53.78048 19.53792-97.77152 50.50368-131.97312-4.9152-12.20608-21.99552-62.6688 4.9152-130.29376 0 0 41.49248-13.06624 135.168 50.46272a476.32384 476.32384 0 0 1 123.00288-16.26112c41.53344 0 83.88608 5.69344 123.00288 16.26112 93.67552-63.488 135.168-50.46272 135.168-50.46272 26.91072 67.584 9.8304 118.08768 4.9152 130.29376 31.78496 34.2016 50.50368 78.2336 50.50368 131.97312 0 188.94848-114.85184 230.48192-224.82944 242.72896 17.94048 15.48288 33.42336 44.76928 33.42336 91.21792 0 65.9456-0.8192 118.90688-0.8192 135.168 0 13.1072 8.97024 28.54912 33.3824 23.67488 195.50208-65.16736 336.40448-249.2416 336.40448-466.7392 0.8192-272.05632-219.9552-491.9296-491.15136-491.9296z"  ></path><path d="M206.785331 738.38592c-0.8192 2.4576-4.9152 3.2768-8.15104 1.6384-3.2768-1.6384-5.69344-4.9152-4.096-7.3728 0.8192-2.41664 4.9152-3.23584 8.192-1.6384 3.2768 1.6384 4.87424 4.9152 4.096 7.3728z m19.53792 21.99552c-2.4576 2.4576-7.33184 0.8192-9.74848-2.4576-3.2768-3.2768-4.096-8.15104-1.6384-10.56768 2.4576-2.4576 6.5536-0.8192 9.78944 2.4576 3.2768 4.05504 4.096 8.92928 1.6384 10.56768z m19.57888 28.50816c-3.2768 2.4576-8.192 0-10.60864-4.096-3.2768-4.096-3.2768-9.74848 0-11.38688 3.2768-2.4576 8.15104 0 10.60864 4.096 3.2768 4.05504 3.2768 8.92928 0 11.38688z m26.86976 27.68896c-2.4576 3.2768-8.15104 2.4576-13.02528-1.6384-4.096-4.096-5.7344-9.78944-2.4576-12.20608 2.4576-3.2768 8.15104-2.4576 13.02528 1.6384 4.096 3.2768 4.9152 8.92928 2.4576 12.20608z m36.6592 15.48288c-0.8192 4.096-6.5536 5.69344-12.24704 4.096-5.69344-1.6384-8.92928-6.5536-8.11008-9.8304 0.8192-4.05504 6.51264-5.69344 12.20608-4.05504 5.7344 1.6384 8.97024 5.7344 8.15104 9.78944z m39.89504 3.2768c0 4.05504-4.9152 7.29088-10.56768 7.29088-5.7344 0-10.60864-3.2768-10.60864-7.33184 0-4.096 4.9152-7.33184 10.60864-7.33184s10.56768 3.2768 10.56768 7.3728z m37.4784-6.5536c0.8192 4.096-3.2768 8.15104-8.97024 8.97024-5.7344 0.8192-10.56768-1.6384-11.38688-5.7344-0.8192-4.05504 3.2768-8.11008 8.92928-8.92928 5.7344-0.8192 10.60864 1.6384 11.42784 5.7344z"  ></path></symbol></svg>',function(o){var a=(a=document.getElementsByTagName("script"))[a.length-1],l=a.getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var t,c,h,i,e,m=function(a,l){l.parentNode.insertBefore(a,l)};if(l&&!o.__iconfont__svg__cssinject__){o.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(a){console&&console.log(a)}}t=function(){var a,l=document.createElement("div");l.innerHTML=o._iconfont_svg_string_4357075,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?m(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(c=function(){document.removeEventListener("DOMContentLoaded",c,!1),t()},document.addEventListener("DOMContentLoaded",c,!1)):document.attachEvent&&(h=t,i=o.document,e=!1,s(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,d())})}function d(){e||(e=!0,h())}function s(){try{i.documentElement.doScroll("left")}catch(a){return void setTimeout(s,50)}d()}}(window);
\ No newline at end of file
diff --git a/vue/src/charts/ChartsDashboard.vue b/vue/src/charts/ChartsDashboard.vue
index 95b75009..81d20bf0 100644
--- a/vue/src/charts/ChartsDashboard.vue
+++ b/vue/src/charts/ChartsDashboard.vue
@@ -1,17 +1,28 @@
 <template>
   <!-- 图表顶层，嵌入全局功能 -->
   <div class="charts-pannel">
+    <!-- 搜索框 -->
+    <div class="w-60 mr-2">
+      <SLSearch :placeholder="$t('common.chart.search.placeholder')" reverse @search="search" @input="search" />
+    </div>
     <SmoothButton @smooth="handleSmooth" :default-method-id="1" />
   </div>
   <!-- 每一个namespace对应一个图表容器 -->
   <ChartsContainer
-    v-for="(group, index) in groups"
+    v-for="(group, index) in nowChartsGroupList"
     :ref="(el) => setChartsRefList(el, index)"
-    :key="group.name"
-    :label="getNamespaces(group.name)"
+    :key="group.id"
+    :label="getNamespaces(group)"
     :charts="getCharts(group)"
+    :index="index"
     :opened="!!group.opened"
-    @switch="(opened) => debouncedHandleSwitch(group.id, opened)"
+    :isPinned="group.id === -1"
+    :isHidden="group.id === -2"
+    @switch="(opened) => debouncedHandleSwitch(group.id, opened, group)"
+    @pin="pin"
+    @unpin="unpin"
+    @hide="hide"
+    @unhide="unhide"
   />
 </template>
 
@@ -24,8 +35,9 @@
 import ChartsContainer from './components/ChartsContainer.vue'
 import { t } from '@swanlab-vue/i18n'
 import SmoothButton from './components/SmoothButton.vue'
-import { debounce } from '@swanlab-vue/utils/common'
+import { debounces } from '@swanlab-vue/utils/common'
 import http from '@swanlab-vue/api/http'
+import SLSearch from '@swanlab-vue/components/SLSearch.vue'
 const props = defineProps({
   // 整个图表列表集合
   groups: {
@@ -33,23 +45,38 @@ const props = defineProps({
     required: true
   }
 })
+const chartsGroupList = ref(props.groups)
+watch(
+  () => props.groups,
+  (newVal) => {
+    // 当groups发生变化时，更新chartsGroupList
+    chartsGroupList.value = newVal
+  }
+)
+const searchChartsGroupList = ref(null)
 
 const chartsRefList = ref([])
 
+const nowChartsGroupList = computed(() => {
+  return searchChartsGroupList.value ? searchChartsGroupList.value : chartsGroupList.value
+})
+
 const setChartsRefList = (el, index) => {
   chartsRefList.value[index] = el
-  chartsRefList.value.length = props.groups.length
+  chartsRefList.value.length = chartsGroupList.value.length
 }
 
 // ---------------------------------- 获取namespace名称 ----------------------------------
 /**
  * 将组名进行一些翻译
- * @param { string } namespace 组名
+ * @param { Object } namespace 命名空间配置
  */
 const getNamespaces = (namespace) => {
   // console.log(name)
-  if (namespace === 'default') return t('common.chart.label.default')
-  else return namespace
+  if (namespace.name === 'default') return t('common.chart.label.default')
+  if (namespace.id === -1) return t('common.chart.label.pinned')
+  if (namespace.id === -2) return t('common.chart.label.hidden')
+  else return namespace.name
 }
 
 // ---------------------------------- 获取图表列表 ----------------------------------
@@ -61,7 +88,7 @@ const getCharts = (group) => {
 }
 
 // ---------------------------------- 处理图表平滑事件 ----------------------------------
-
+const smoothMethod = ref(null)
 const handleSmooth = (method) => {
   // 遍历chartsRefList中的所有chartRefList，调用其smooth方法
   chartsRefList.value.forEach((chartsRef) => {
@@ -69,23 +96,86 @@ const handleSmooth = (method) => {
       chartRef.smooth(method)
     })
   })
+  smoothMethod.value = method
 }
+// 暂时先以provide的方式传递smoothMethod，后续会存储在后端，通过接口获取
+provide('smoothMethod', smoothMethod)
 
 // ---------------------------------- 在此处处理命名空间打开和关闭 ----------------------------------
-const handleSwitch = (id, opened) => {
-  console.log('namespace click', id, opened)
+const handleSwitch = (id, opened, namespace) => {
+  // console.log('namespace click', id, opened)
   // 向后端更新展开状态
   http.patch('/namespace/' + id + '/opened', {
+    experiment_id: namespace?.experiment_id?.id,
+    project_id: namespace?.project_id?.id,
     opened
   })
 }
 
-const debouncedHandleSwitch = debounce(handleSwitch, 300)
+const debouncedHandleSwitch = debounces(handleSwitch, 300)
+
+const updateChartStatus = async (chart, status) => {
+  const { data } = await http.patch('/chart/' + chart.id + '/status', {
+    status
+  })
+  chartsGroupList.value = data.groups
+}
+
+// ---------------------------------- 处理pin事件 ----------------------------------
+/**
+ * 图表置顶
+ * @param { Object } chart 图表配置
+ */
+const pin = (chart) => {
+  updateChartStatus(chart, 1)
+}
+
+/**
+ * 图表取消置顶
+ * @param { Object } chart 图表配置
+ */
+const unpin = (chart) => {
+  updateChartStatus(chart, 0)
+}
+
+// ---------------------------------- 处理hide事件 ----------------------------------
+/**
+ * 图表隐藏
+ * @param { Object } chart 图表配置
+ */
+const hide = (chart) => {
+  updateChartStatus(chart, -1)
+}
+
+/**
+ * 图表取消隐藏
+ * @param { Object } chart 图表配置
+ */
+const unhide = (chart) => {
+  updateChartStatus(chart, 0)
+}
+
+// ---------------------------------- 处理搜索图表事件 ----------------------------------
+const search = (value) => {
+  if (!value) return (searchChartsGroupList.value = null)
+  const newGroup = chartsGroupList.value.filter((group) => {
+    return group.charts.some((chart) => {
+      return chart.name.toLowerCase().includes(value.toLowerCase())
+    })
+  })
+  // 然后将newGroup中滤除不包含value的chart
+  newGroup.forEach((group) => {
+    group.charts = group.charts.filter((chart) => {
+      return chart.name.toLowerCase().includes(value.toLowerCase())
+    })
+  })
+  searchChartsGroupList.value = newGroup
+}
 </script>
 
 <style lang="scss" scoped>
 .charts-pannel {
-  @apply sticky px-4 py-3 bg-higher flex justify-end top-0 border-b;
+  @apply sticky px-4 py-3 bg-higher flex justify-between top-0 border-b;
   z-index: 30;
 }
 </style>
diff --git a/vue/src/charts/README.md b/vue/src/charts/README.md
index 7ae609e1..141b1b8a 100644
--- a/vue/src/charts/README.md
+++ b/vue/src/charts/README.md
@@ -1,6 +1,6 @@
 # 这里提供了 SwanLab 所有支持的图表类型
 
-每个图表类型被抽象为一个组件,但是在外部通过本部分提供的[ChartsContainer](./ChartsContainer.vue)组件统一调用，所需的就是传入chart配置  
+每个图表类型被抽象为一个组件,但是在外部通过本部分提供的[ChartsDashboard](./ChartsDashboard.vue)组件统一调用，所需的就是传入chart配置  
 一个ChartsContainer组件代表一个命名空间
 
 ## 图表组件
diff --git a/vue/src/charts/components/ChartContainer.vue b/vue/src/charts/components/ChartContainer.vue
index 2c62cf60..29f6892d 100644
--- a/vue/src/charts/components/ChartContainer.vue
+++ b/vue/src/charts/components/ChartContainer.vue
@@ -12,8 +12,44 @@
     </div>
     <template v-else>
       <!-- 图表相关控制按钮 -->
-      <div class="chart-pannel" v-if="hover && !unknown && !isAllError">
-        <PannelButton icon="zoom" :tip="$t('common.chart.zoom')" @click="zoom" />
+      <div class="chart-pannel">
+        <!-- 取消置顶的按钮 -->
+        <PannelButton
+          class="!text-positive-default"
+          icon="pinned"
+          click-icon="loading"
+          click-class="animate-spin"
+          :tip="$t('common.chart.unpin')"
+          @click="unpin"
+          v-if="isPinned"
+        />
+        <template v-if="hover && !unknown && !isAllError">
+          <!-- 置顶 -->
+          <PannelButton
+            icon="pin"
+            :tip="$t('common.chart.pin')"
+            @click="pin"
+            click-icon="loading"
+            click-class="animate-spin"
+            v-if="!isPinned"
+          />
+          <!-- 放大功能 -->
+          <PannelButton icon="zoom" :tip="$t('common.chart.zoom')" @click="zoom" />
+          <!-- 更多功能 -->
+          <SLMenu menu-class="flex-shrink-0" class="right-0 top-4">
+            <PannelButton icon="more" :tip="$t('common.chart.more')" />
+            <template #pop>
+              <SLMenuItems>
+                <SLMenuItem class="py-1" @click="unhide" v-if="isHidden">
+                  {{ $t('common.chart.unhide') }}
+                </SLMenuItem>
+                <SLMenuItem class="py-1" @click="hide" v-else>
+                  {{ $t('common.chart.hide') }}
+                </SLMenuItem>
+              </SLMenuItems>
+            </template>
+          </SLMenu>
+        </template>
       </div>
       <component :index="index" ref="chartRef" :is="chartComponent.type" :title="chart.name" :chart="chart" />
     </template>
@@ -43,6 +79,10 @@ import UnknownChart from '../package/UnknownChart.vue'
 import PannelButton from './PannelButton.vue'
 import { debounce } from '@swanlab-vue/utils/common'
 import ImageChart from '../package/ImageChart.vue'
+import SLLoading from '@swanlab-vue/components/SLLoading.vue'
+import SLMenu from '@swanlab-vue/components/menu/SLMenu.vue'
+import SLMenuItems from '@swanlab-vue/components/menu/SLMenuItems.vue'
+import SLMenuItem from '@swanlab-vue/components/menu/SLMenuItem.vue'
 const props = defineProps({
   chart: {
     type: Object,
@@ -51,11 +91,20 @@ const props = defineProps({
   index: {
     type: Number,
     required: true
+  },
+  isPinned: {
+    type: Boolean,
+    required: true
+  },
+  isHidden: {
+    type: Boolean,
+    required: true
   }
 })
 
 const cid = props.chart.id
 const source = props.chart.source
+const emit = defineEmits(['pin', 'unpin', 'hide', 'unhide'])
 
 // ---------------------------------- 判断是否处于hover状态 ----------------------------------
 const hover = ref(false)
@@ -224,6 +273,24 @@ const smooth = (method) => {
   chartRef.value.smooth && chartRef.value.smooth(method)
 }
 
+// ---------------------------------- 图表置顶 ----------------------------------
+const pin = () => {
+  emit('pin', props.chart)
+}
+const unpin = () => {
+  emit('unpin', props.chart)
+}
+
+// ---------------------------------- 图表隐藏 ----------------------------------
+
+const hide = () => {
+  emit('hide', props.chart)
+}
+
+const unhide = () => {
+  emit('unhide', props.chart)
+}
+
 // ---------------------------------- 暴露组件对象 ----------------------------------
 defineExpose({
   chartRef,
@@ -240,17 +307,16 @@ defineExpose({
   @apply w-full h-auto min-h-[288px] border rounded relative bg-default;
   @apply px-3 py-4;
   @apply flex-col flex justify-between;
-  .line-chart {
-    @apply col-span-3;
-  }
 }
 
 .chart-pannel {
   @apply absolute top-1 right-2 h-4;
-  @apply flex justify-end gap-2;
+  @apply flex justify-end items-center gap-2;
 }
 // ---------------------------------- 图表样式 ----------------------------------
-
+.line-chart {
+  @apply col-span-3 lg:col-span-1;
+}
 .audio-chart,
 .image-chart,
 .text-chart {
diff --git a/vue/src/charts/components/ChartsContainer.vue b/vue/src/charts/components/ChartsContainer.vue
index 17b8de85..82f95068 100644
--- a/vue/src/charts/components/ChartsContainer.vue
+++ b/vue/src/charts/components/ChartsContainer.vue
@@ -17,10 +17,16 @@
     <div class="charts-slot" v-show="isExpand" ref="chartsSlotRef">
       <ChartContainer
         v-for="(chart, index) in charts"
-        :key="chart._cid"
+        :key="chart.id"
         :chart="chart"
         :index="index"
+        :isPinned="isPinned"
+        :isHidden="isHidden"
         :ref="(el) => setChartRefList(el, index)"
+        @pin="pin"
+        @unpin="unpin"
+        @hide="hide"
+        @unhide="unhide"
       />
     </div>
   </div>
@@ -44,12 +50,25 @@ const props = defineProps({
     type: Array,
     required: true
   },
+  // namespace的索引
+  index: {
+    type: Number,
+    required: true
+  },
   opened: {
     type: Boolean,
     required: true
+  },
+  isPinned: {
+    type: Boolean,
+    required: true
+  },
+  isHidden: {
+    type: Boolean,
+    required: true
   }
 })
-const emit = defineEmits(['switch'])
+const emit = defineEmits(['switch', 'pin', 'unpin', 'hide', 'unhide'])
 // ---------------------------------- 控制展开和关闭的状态 ----------------------------------
 const isExpand = ref(props.opened)
 
@@ -72,6 +91,23 @@ provide('chartRefList', chartRefList)
 defineExpose({
   chartRefList
 })
+
+// ---------------------------------- 图表置顶、隐藏、取消置顶、取消隐藏 ----------------------------------
+const pin = (chart) => {
+  emit('pin', chart)
+}
+
+const unpin = (chart) => {
+  emit('unpin', chart)
+}
+
+const hide = (chart) => {
+  emit('hide', chart)
+}
+
+const unhide = (chart) => {
+  emit('unhide', chart)
+}
 </script>
 
 <style lang="scss" scoped>
diff --git a/vue/src/charts/components/PannelButton.vue b/vue/src/charts/components/PannelButton.vue
index db886cdb..c723fa49 100644
--- a/vue/src/charts/components/PannelButton.vue
+++ b/vue/src/charts/components/PannelButton.vue
@@ -1,6 +1,6 @@
 <template>
-  <button class="pannel-button" v-tippy="{ content: tip }">
-    <SLIcon class="h-full aspect-square" :icon="icon" />
+  <button class="pannel-button" v-tippy="{ content: tip }" @click="handleIconClick" :disabled="disabled">
+    <SLIcon class="h-full aspect-square" :class="pannelIconClass" :icon="pannelIcon" />
   </button>
 </template>
 
@@ -13,7 +13,7 @@ import SLIcon from '@swanlab-vue/components/SLIcon.vue'
  * @since: 2023-12-12 21:43:02
  **/
 
-defineProps({
+const props = defineProps({
   icon: {
     type: String,
     required: true
@@ -21,12 +21,41 @@ defineProps({
   tip: {
     type: String,
     required: true
+  },
+  // 点击后的icon名称，可以不传入，这样点击前后的icon不变
+  clickIcon: {
+    type: String,
+    required: false
+  },
+  // 点击后的icon样式，可以不传入，这样点击前后的icon样式不变
+  clickClass: {
+    type: String,
+    required: false
   }
 })
+const pannelIcon = ref(props.icon)
+const pannelIconClass = ref('')
+const disabled = ref(false)
+
+const handleIconClick = () => {
+  if (disabled.value) return
+  if (props.clickIcon) {
+    pannelIcon.value = props.clickIcon
+    disabled.value = true
+  }
+  if (props.clickClass) {
+    pannelIconClass.value = props.clickClass
+    disabled.value = true
+  }
+}
 </script>
 
 <style lang="scss" scoped>
 .pannel-button {
+  @apply w-4 h-4;
   @apply text-dimmer h-full p-0.5 rounded hover:bg-positive-dimmest hover:text-positive-highest;
+  &:disabled {
+    @apply cursor-progress opacity-60;
+  }
 }
 </style>
diff --git a/vue/src/charts/package/LineChart.vue b/vue/src/charts/package/LineChart.vue
index 5089288c..72446d69 100644
--- a/vue/src/charts/package/LineChart.vue
+++ b/vue/src/charts/package/LineChart.vue
@@ -91,7 +91,7 @@ const chartRefListExceptSelf = computed(() => {
   return chartRefList.value.filter((_, i) => i !== props.index)
 })
 // 平滑配置
-let smoothMethod = props.chart.smooth || undefined
+let smoothMethod = inject('smoothMethod')?.value || undefined
 // ---------------------------------- 图表样式配置 ----------------------------------
 // 后续需要适配不同的颜色，但是Line不支持css变量，考虑自定义主题或者js获取css变量完成计算
 const colors = inject('colors')
@@ -485,7 +485,7 @@ const registerTooltipEvent = (dom, zoom) => {
     // 通知其他图表，当前图表的数据被hover到了
     !zoom &&
       chartRefListExceptSelf.value?.forEach((chart) => {
-        chart.showTooltip(point)
+        chart?.showTooltip(point)
       })
     manual = true
   })
@@ -496,7 +496,7 @@ const registerTooltipEvent = (dom, zoom) => {
     if (manual && !zoom)
       // 通知其他图表，当前图表的数据被hover到了
       chartRefListExceptSelf.value?.forEach((chart) => {
-        chart.hideTooltip(...args)
+        chart?.hideTooltip(...args)
       })
     nowData = null
     manual = true
@@ -592,7 +592,7 @@ const thickenByTag = (plot, zoom, tag, color) => {
   nowThickenColor = color
   // 加粗其他图表的数据，保持联动
   chartRefListExceptSelf.value.forEach((chart) => {
-    chart.thicken(zoom, tag, color)
+    chart?.thicken(zoom, tag, color)
   })
 }
 
@@ -626,7 +626,7 @@ const restoreByTag = (plot, zoom, tag, color) => {
   nowThickenTag = null
   nowThickenColor = null
   chartRefListExceptSelf.value.forEach((chart) => {
-    chart.thin(zoom, tag, color)
+    chart?.thin(zoom, tag, color)
   })
 }
 
diff --git a/vue/src/components/menu/SLMenuItem.vue b/vue/src/components/menu/SLMenuItem.vue
index 1636127e..e8520423 100644
--- a/vue/src/components/menu/SLMenuItem.vue
+++ b/vue/src/components/menu/SLMenuItem.vue
@@ -1,5 +1,5 @@
 <template>
-  <MenuItem :as="as" class="p-3 hover:bg-gray-light cursor-pointer">
+  <MenuItem :as="as" class="p-3 hover:bg-higher cursor-pointer">
     <slot></slot>
   </MenuItem>
 </template>
diff --git a/vue/src/i18n/en-US/common.json b/vue/src/i18n/en-US/common.json
index 88a05051..5f0f729b 100644
--- a/vue/src/i18n/en-US/common.json
+++ b/vue/src/i18n/en-US/common.json
@@ -37,11 +37,21 @@
     },
     "empty": "Empty Experiment with No Charts",
     "error": "This chart is not displayed correctly.",
+    "search": {
+      "placeholder": "Search Chart..."
+    },
     "label": {
-      "default": "Charts"
+      "default": "Charts",
+      "pinned": "Pinned",
+      "hidden": "Hidden"
     },
     "unkonwn": "Unknown chart type: {type}",
-    "zoom": "Zoom In"
+    "zoom": "Zoom In",
+    "pin": "Pin",
+    "unpin": "Unpin",
+    "more": "More actions",
+    "hide": "Hide",
+    "unhide": "Unhide"
   },
   "config-editor": {
     "button": "Edit",
diff --git a/vue/src/i18n/zh-CN/common.json b/vue/src/i18n/zh-CN/common.json
index 07636e77..0dae0485 100644
--- a/vue/src/i18n/zh-CN/common.json
+++ b/vue/src/i18n/zh-CN/common.json
@@ -37,11 +37,21 @@
     },
     "empty": "缺少实验数据",
     "error": "此图表无法正确显示",
+    "search": {
+      "placeholder": "搜索图表..."
+    },
     "label": {
-      "default": "图表"
+      "default": "图表",
+      "pinned": "置顶图表",
+      "hidden": "隐藏图表"
     },
     "unkonwn": "未知的图表类型: {type}",
-    "zoom": "放大展示"
+    "zoom": "放大展示",
+    "pin": "置顶",
+    "unpin": "取消置顶",
+    "more": "更多操作",
+    "hide": "隐藏",
+    "unhide": "取消隐藏"
   },
   "config-editor": {
     "button": "Edit",


Test patch:
diff --git a/test/db/test_pinned.py b/test/db/test_pinned.py
new file mode 100644
index 00000000..a3be3c28
--- /dev/null
+++ b/test/db/test_pinned.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+r"""
+@DATE: 2024-03-09 22:46:04
+@File: test/db/test_pinned.py
+@IDE: vscode
+@Description:
+    手动把某个chart置顶
+"""
+from swanlab.db import connect
+from swanlab.db.models.charts import Chart
+
+connect()
+chart_id = 1
+
+Chart.pinned(chart_id)