提交 510f8603 编写于 作者: 查尔斯-BUG万象集's avatar 查尔斯-BUG万象集

新增:新增系统管理/菜单管理(列表、创建、修改、删除、导出)

上级 1319cb32
......@@ -249,6 +249,7 @@ continew-admin
│ │ ├─ monitor # 系统监控模块
│ │ └─ system # 系统管理模块
│ ├─ assets # 静态资源
│ │ ├─ icons # 图标资源
│ │ ├─ images # 图片资源
│ │ └─ style # 样式资源
│ ├─ components # 通用业务组件
......
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.charles7c.cnadmin.common.base.BaseEnum;
/**
* 菜单类型枚举
*
* @author Charles7c
* @since 2023/2/15 20:12
*/
@Getter
@RequiredArgsConstructor
public enum MenuTypeEnum implements BaseEnum<Integer, String> {
/** 目录 */
DIR(1, "目录"),
/** 菜单 */
MENU(2, "菜单"),
/** 按钮 */
BUTTON(3, "按钮"),;
private final Integer value;
private final String description;
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import top.charles7c.cnadmin.system.model.entity.MenuDO;
/**
* 菜单 Mapper
*
* @author Charles7c
* @since 2023/2/15 20:30
*/
public interface MenuMapper extends BaseMapper<MenuDO> {}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import top.charles7c.cnadmin.system.model.entity.RoleMenuDO;
/**
* 角色和菜单 Mapper
*
* @author Charles7c
* @since 2023/2/15 20:30
*/
public interface RoleMenuMapper extends BaseMapper<RoleMenuDO> {}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.model.entity;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import top.charles7c.cnadmin.common.base.BaseDO;
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
import top.charles7c.cnadmin.common.enums.MenuTypeEnum;
/**
* 菜单实体
*
* @author Charles7c
* @since 2023/2/15 20:14
*/
@Data
@TableName("sys_menu")
public class MenuDO extends BaseDO {
private static final long serialVersionUID = 1L;
/**
* 菜单 ID
*/
@TableId
private Long menuId;
/**
* 菜单名称
*/
private String menuName;
/**
* 上级菜单 ID
*/
private Long parentId;
/**
* 菜单类型(1目录 2菜单 3按钮)
*/
private MenuTypeEnum menuType;
/**
* 路由地址
*/
private String path;
/**
* 组件名称
*/
private String name;
/**
* 组件路径
*/
private String component;
/**
* 菜单图标
*/
private String icon;
/**
* 是否外链
*/
private Boolean isExternal;
/**
* 是否缓存
*/
private Boolean isCache;
/**
* 是否隐藏
*/
private Boolean isHidden;
/**
* 权限标识
*/
private String permission;
/**
* 菜单排序
*/
private Integer menuSort;
/**
* 状态(1启用 2禁用)
*/
private DisEnableStatusEnum status;
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.model.entity;
import java.io.Serializable;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* 角色和菜单实体
*
* @author Charles7c
* @since 2023/2/15 20:20
*/
@Data
@TableName("sys_role_menu")
public class RoleMenuDO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 角色 ID
*/
private Long roleId;
/**
* 菜单 ID
*/
private Long menuId;
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.model.query;
import java.io.Serializable;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springdoc.api.annotations.ParameterObject;
import top.charles7c.cnadmin.common.annotation.Query;
/**
* 菜单查询条件
*
* @author Charles7c
* @since 2023/2/15 20:21
*/
@Data
@ParameterObject
@Schema(description = "菜单查询条件")
public class MenuQuery implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 菜单名称
*/
@Schema(description = "菜单名称")
@Query(type = Query.Type.INNER_LIKE)
private String menuName;
/**
* 状态(1启用 2禁用)
*/
@Schema(description = "状态(1启用 2禁用)")
@Query
private Integer status;
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.model.request;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import top.charles7c.cnadmin.common.base.BaseRequest;
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
import top.charles7c.cnadmin.common.enums.MenuTypeEnum;
/**
* 创建或修改菜单信息
*
* @author Charles7c
* @since 2023/2/15 20:21
*/
@Data
@Schema(description = "创建或修改菜单信息")
public class MenuRequest extends BaseRequest {
private static final long serialVersionUID = 1L;
/**
* 菜单 ID
*/
@Schema(description = "菜单 ID")
@Null(message = "新增时,ID 必须为空", groups = Create.class)
@NotNull(message = "修改时,ID 不能为空", groups = Update.class)
private Long menuId;
/**
* 上级菜单 ID
*/
@Schema(description = "上级菜单 ID")
private Long parentId;
/**
* 菜单名称
*/
@Schema(description = "菜单名称")
@NotBlank(message = "菜单名称不能为空")
private String menuName;
/**
* 菜单类型(1目录 2菜单 3按钮)
*/
@Schema(description = "菜单类型(1目录 2菜单 3按钮)", type = "Integer", allowableValues = {"1", "2", "3"})
@NotNull(message = "菜单类型非法")
private MenuTypeEnum menuType;
/**
* 路由地址
*/
@Schema(description = "路由地址")
private String path;
/**
* 组件名称
*/
@Schema(description = "组件名称")
private String name;
/**
* 组件路径
*/
@Schema(description = "组件路径")
private String component;
/**
* 菜单图标
*/
@Schema(description = "菜单图标")
private String icon;
/**
* 是否外链
*/
@Schema(description = "是否外链")
private Boolean isExternal;
/**
* 是否缓存
*/
@Schema(description = "是否缓存")
private Boolean isCache;
/**
* 是否隐藏
*/
@Schema(description = "是否隐藏")
private Boolean isHidden;
/**
* 权限标识
*/
@Schema(description = "权限标识")
private String permission;
/**
* 菜单排序
*/
@Schema(description = "菜单排序")
@NotNull(message = "菜单排序不能为空")
private Integer menuSort;
/**
* 状态(1启用 2禁用)
*/
@Schema(description = "状态(1启用 2禁用)", type = "Integer", allowableValues = {"1", "2"})
private DisEnableStatusEnum status;
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.model.vo;
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import top.charles7c.cnadmin.common.base.BaseVO;
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
import top.charles7c.cnadmin.common.enums.MenuTypeEnum;
/**
* 菜单信息
*
* @author Charles7c
* @since 2023/2/15 20:23
*/
@Data
@Accessors(chain = true)
@Schema(description = "菜单信息")
public class MenuVO extends BaseVO {
private static final long serialVersionUID = 1L;
/**
* 菜单 ID
*/
@Schema(description = "菜单 ID")
private Long menuId;
/**
* 菜单名称
*/
@Schema(description = "菜单名称")
private String menuName;
/**
* 上级菜单 ID
*/
@Schema(description = "上级菜单 ID")
private Long parentId;
/**
* 菜单类型(1目录 2菜单 3按钮)
*/
@Schema(description = "菜单类型(1目录 2菜单 3按钮)")
private MenuTypeEnum menuType;
/**
* 路由地址
*/
@Schema(description = "路由地址")
private String path;
/**
* 组件名称
*/
@Schema(description = "组件名称")
private String name;
/**
* 组件路径
*/
@Schema(description = "组件路径")
private String component;
/**
* 菜单图标
*/
@Schema(description = "菜单图标")
private String icon;
/**
* 是否外链
*/
@Schema(description = "是否外链")
private Boolean isExternal;
/**
* 是否缓存
*/
@Schema(description = "是否缓存")
private Boolean isCache;
/**
* 是否隐藏
*/
@Schema(description = "是否隐藏")
private Boolean isHidden;
/**
* 权限标识
*/
@Schema(description = "权限标识")
private String permission;
/**
* 菜单排序
*/
@Schema(description = "菜单排序")
private Integer menuSort;
/**
* 状态(1启用 2禁用)
*/
@Schema(description = "状态(1启用 2禁用)")
private DisEnableStatusEnum status;
/**
* 子菜单列表
*/
@Schema(description = "子菜单列表")
private List<MenuVO> children;
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.service;
import java.util.List;
import cn.hutool.core.lang.tree.Tree;
import top.charles7c.cnadmin.common.base.BaseService;
import top.charles7c.cnadmin.system.model.query.MenuQuery;
import top.charles7c.cnadmin.system.model.request.MenuRequest;
import top.charles7c.cnadmin.system.model.vo.MenuVO;
/**
* 菜单业务接口
*
* @author Charles7c
* @since 2023/2/15 20:30
*/
public interface MenuService extends BaseService<MenuVO, MenuVO, MenuQuery, MenuRequest> {
/**
* 构建树
*
* @param list
* 原始列表数据
* @return 树列表
*/
List<MenuVO> buildListTree(List<MenuVO> list);
/**
* 构建树
*
* @param list
* 原始列表数据
* @return 树列表
*/
List<Tree<Long>> buildTree(List<MenuVO> list);
}
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
import top.charles7c.cnadmin.common.util.TreeUtils;
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
import top.charles7c.cnadmin.system.mapper.MenuMapper;
import top.charles7c.cnadmin.system.model.entity.MenuDO;
import top.charles7c.cnadmin.system.model.query.MenuQuery;
import top.charles7c.cnadmin.system.model.request.MenuRequest;
import top.charles7c.cnadmin.system.model.vo.MenuVO;
import top.charles7c.cnadmin.system.service.MenuService;
/**
* 菜单业务实现类
*
* @author Charles7c
* @since 2023/2/15 20:30
*/
@Service
@RequiredArgsConstructor
public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, MenuVO, MenuQuery, MenuRequest>
implements MenuService {
@Override
@Transactional(rollbackFor = Exception.class)
public Long create(MenuRequest request) {
String menuName = request.getMenuName();
boolean isExists = this.checkNameExists(menuName, request.getParentId(), request.getMenuId());
CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", menuName));
// 保存信息
request.setStatus(DisEnableStatusEnum.ENABLE);
return super.create(request);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(MenuRequest request) {
String menuName = request.getMenuName();
boolean isExists = this.checkNameExists(menuName, request.getParentId(), request.getMenuId());
CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", menuName));
super.update(request);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(List<Long> ids) {
super.delete(ids);
super.lambdaUpdate().in(MenuDO::getParentId, ids).remove();
}
@Override
public List<MenuVO> buildListTree(List<MenuVO> list) {
if (CollUtil.isEmpty(list)) {
return new ArrayList<>();
}
// 去除重复子菜单列表
List<MenuVO> deDuplicationList = deDuplication(list);
return deDuplicationList.stream().map(m -> m.setChildren(this.getChildren(m, list)))
.collect(Collectors.toList());
}
/**
* 数据去重(去除重复子菜单列表)
*
* @param list
* 菜单列表
* @return 去重后菜单列表
*/
private List<MenuVO> deDuplication(List<MenuVO> list) {
List<MenuVO> deDuplicationList = new ArrayList<>();
for (MenuVO outer : list) {
boolean flag = true;
for (MenuVO inner : list) {
// 忽略重复子列表
if (inner.getMenuId().equals(outer.getParentId())) {
flag = false;
break;
}
}
if (flag) {
deDuplicationList.add(outer);
}
}
return deDuplicationList;
}
/**
* 获取指定菜单的子菜单列表
*
* @param menuVO
* 指定菜单
* @param list
* 菜单列表
* @return 子菜单列表
*/
private List<MenuVO> getChildren(MenuVO menuVO, List<MenuVO> list) {
return list.stream().filter(m -> Objects.equals(m.getParentId(), menuVO.getMenuId()))
.map(m -> m.setChildren(this.getChildren(m, list))).collect(Collectors.toList());
}
@Override
public List<Tree<Long>> buildTree(List<MenuVO> list) {
return TreeUtils.build(list, (m, tree) -> {
tree.setId(m.getMenuId());
tree.setName(m.getMenuName());
tree.setParentId(m.getParentId());
tree.setWeight(m.getMenuSort());
});
}
/**
* 检查名称是否存在
*
* @param name
* 名称
* @param parentId
* 上级 ID
* @param id
* ID
* @return 是否存在
*/
private boolean checkNameExists(String name, Long parentId, Long id) {
return super.lambdaQuery().eq(MenuDO::getMenuName, name).eq(MenuDO::getParentId, parentId)
.ne(id != null, MenuDO::getMenuId, id).exists();
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.charles7c.cnadmin.system.mapper.MenuMapper">
</mapper>
\ No newline at end of file
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import path from 'path';
export default function createSvgIcon(isBuild: boolean) {
return createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
symbolId: 'icon-[dir]-[name]',
svgoOptions: isBuild,
});
}
import { mergeConfig } from 'vite';
import eslint from 'vite-plugin-eslint';
import baseConfig from './vite.config.base';
import createSvgIcon from './plugin/svg-icon';
export default mergeConfig(
{
......@@ -17,6 +18,7 @@ export default mergeConfig(
include: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
exclude: ['node_modules'],
}),
createSvgIcon(false),
],
},
baseConfig
......
......@@ -5,6 +5,7 @@ import configVisualizerPlugin from './plugin/visualizer';
import configArcoResolverPlugin from './plugin/arcoResolver';
import configStyleImportPlugin from './plugin/styleImport';
import configImageminPlugin from './plugin/imagemin';
import createSvgIcon from './plugin/svg-icon';
export default mergeConfig(
{
......@@ -15,6 +16,7 @@ export default mergeConfig(
configArcoResolverPlugin(),
configStyleImportPlugin(),
configImageminPlugin(),
createSvgIcon(true),
],
build: {
rollupOptions: {
......
......@@ -91,6 +91,7 @@
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-imagemin": "^0.6.1",
"vite-plugin-style-import": "1.4.1",
"vite-plugin-svg-icons": "^2.0.1",
"vite-svg-loader": "^3.6.0",
"vue-tsc": "^1.0.14"
},
......
import axios from 'axios';
import qs from 'query-string';
import { DeptParam } from '@/api/system/dept';
import { MenuParam } from '@/api/system/menu';
import { TreeNodeData } from '@arco-design/web-vue';
export default function listDeptTree(params: DeptParam) {
export function listDeptTree(params: DeptParam) {
return axios.get<TreeNodeData[]>('/common/tree/dept', {
params,
paramsSerializer: (obj) => {
......@@ -11,3 +12,12 @@ export default function listDeptTree(params: DeptParam) {
},
});
}
export function listMenuTree(params: MenuParam) {
return axios.get<TreeNodeData[]>('/common/tree/menu', {
params,
paramsSerializer: (obj) => {
return qs.stringify(obj);
},
});
}
import axios from 'axios';
import qs from 'query-string';
const BASE_URL = '/system/menu';
export interface MenuRecord {
menuId?: number;
menuName: string;
parentId?: number;
menuType: number;
path?: string;
name?: string;
component?: string;
icon?: string;
isExternal: boolean;
isCache: boolean;
isHidden: boolean;
permission?: string;
menuSort: number;
status?: number;
createUserString?: string;
createTime?: string;
updateUserString?: string;
updateTime?: string;
children?: Array<MenuRecord>;
parentName?: string;
}
export interface MenuParam {
menuName?: string;
status?: number;
}
export function listMenu(params: MenuParam) {
return axios.get<MenuRecord[]>(`${BASE_URL}/list`, {
params,
paramsSerializer: (obj) => {
return qs.stringify(obj);
},
});
}
export function getMenu(id: number) {
return axios.get<MenuRecord>(`${BASE_URL}/${id}`);
}
export function createMenu(req: MenuRecord) {
return axios.post(BASE_URL, req);
}
export function updateMenu(req: MenuRecord) {
return axios.put(BASE_URL, req);
}
export function deleteMenu(ids: number | Array<number>) {
return axios.delete(`${BASE_URL}/${ids}`);
}
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M44 9H4m38 20H6m28-10H14m20 20H14" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M44 9H4m36 20H4m21-10H4m21 20H4" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M4 9h40M8 29h36M23 19h21M23 39h21" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path stroke="#4E5969" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M7 7h13v13H7zM28 7h13v13H28zM7 28h13v13H7zM28 28h13v13H28z"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="9" y="18" width="30" height="22" rx="1" stroke="#4E5969" stroke-width="4"/><path d="M6 9a1 1 0 011-1h34a1 1 0 011 1v8a1 1 0 01-1 1H7a1 1 0 01-1-1V9zM19 27h10" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M11.27 27.728l12.728 12.728 12.728-12.728M24 5v34.295" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M24.008 41.99a.01.01 0 01-.016 0l-9.978-11.974A.01.01 0 0114.02 30H33.98a.01.01 0 01.007.016l-9.978 11.975z" stroke="#4E5969" stroke-width="4"/><path d="M24 42L14 30h20L24 42z" fill="#4E5969"/><path stroke="#4E5969" stroke-width="4" d="M22 6h4v26h-4z"/><path fill="#4E5969" d="M22 6h4v26h-4z"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M20.272 11.27L7.544 23.998l12.728 12.728M43 24H8.705" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M27.728 11.27l12.728 12.728-12.728 12.728M5 24h34.295" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M23.992 6.01a.01.01 0 01.016 0l9.978 11.974a.01.01 0 01-.007.016H14.02a.01.01 0 01-.007-.016l9.978-11.975z" stroke="#4E5969" stroke-width="4"/><path d="M24 6l10 12H14L24 6z" fill="#4E5969"/><path stroke="#4E5969" stroke-width="4" d="M26 42h-4V16h4z"/><path fill="#4E5969" d="M26 42h-4V16h4z"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M11.27 20.272L23.998 7.544l12.728 12.728M24 43V8.705" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M31 23a7 7 0 11-14 0 7 7 0 0114 0zm0 0c0 3.038 2.462 6.5 5.5 6.5A5.5 5.5 0 0042 24c0-9.941-8.059-18-18-18S6 14.059 6 24s8.059 18 18 18c4.244 0 8.145-1.469 11.222-3.925" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M29.037 15.236s-9.174 9.267-11.48 11.594c-2.305 2.327-1.646 4.987-.329 6.316 1.317 1.33 3.994 1.953 6.258-.332L37.32 18.851c3.623-3.657 2.092-8.492 0-10.639-2.093-2.147-6.916-3.657-10.54 0L11.3 23.838c-3.623 3.657-3.953 10.638.329 14.96 4.282 4.322 11.115 4.105 14.821.333 3.706-3.773 8.74-8.822 11.224-11.33" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M38.293 36.293L26.707 24.707a1 1 0 010-1.414l11.586-11.586c.63-.63 1.707-.184 1.707.707v23.172c0 .89-1.077 1.337-1.707.707zM21 12.414v23.172c0 .89-1.077 1.337-1.707.707L7.707 24.707a1 1 0 010-1.414l11.586-11.586c.63-.63 1.707-.184 1.707.707z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M19 5.25L22.75 9m0 0l12.043 12.043a1 1 0 010 1.414L32 25.25 21.221 36.029a1 1 0 01-1.428-.014L9.443 25.25l-.763-.793a1 1 0 01.013-1.4L22.75 9zM6 42h36" stroke="#4E5969" stroke-width="4"/><path d="M11.791 25.25c-.881 0-1.332 1.058-.72 1.693l8.722 9.072a1 1 0 001.428.014L32 25.25H11.791z" fill="#4E5969" stroke="#4E5969" stroke-width="4"/><path fill-rule="evenodd" clip-rule="evenodd" d="M40.013 29.812L37.201 27l-2.812 2.812a4 4 0 105.624 0z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M13 24h12a8 8 0 100-16H13.2a.2.2 0 00-.2.2V24zm0 0h16a8 8 0 110 16H13.2a.2.2 0 01-.2-.2V24z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M24 13L7 7v28l17 6 17-6V7l-17 6zm0 0v27.5M19 18l-7-2.5M19 25l-7-2.5M19 32l-7-2.5M29 18l7-2.5M29 25l7-2.5M29 32l7-2.5" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M19 10a4 4 0 11-8 0 4 4 0 018 0zM38 10a4 4 0 11-8 0 4 4 0 018 0zM19 38a4 4 0 11-8 0 4 4 0 018 0zM15 15v15m0 3.5V30m0 0c0-5 19-7 19-15" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M33 13h7a1 1 0 011 1v12.14a1 1 0 01-.85.99l-21.3 3.24a1 1 0 00-.85.99V43" stroke="#4E5969" stroke-width="4"/><path d="M7 18V8c0-.552.444-1 .997-1H32.01c.552 0 .99.447.99 1v10.002A.998.998 0 0132 19H8a1 1 0 01-1-1z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M35 27h8M5 27h8m0-9h22v13c0 6.075-4.925 11-11 11s-11-4.925-11-11V18z" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/><path d="M7 42v-.5a6.5 6.5 0 016.5-6.5M7 42v-.5M41 42v-.5a6.5 6.5 0 00-6.5-6.5M13 18h22M7 14a4 4 0 004 4h26a4 4 0 004-4M24 42V23M17 14a7 7 0 1114 0" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M30.8 32.465c.585-2.576 2.231-4.75 3.77-6.897A12.94 12.94 0 0037 18c0-7.18-5.82-13-13-13s-13 5.82-13 13c0 2.823.9 5.437 2.43 7.568 1.539 2.147 3.185 4.32 3.77 6.897l.623 2.756A1 1 0 0018.8 36H29.2a1 1 0 00.976-.779l.624-2.756zM17 42h14" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M7 22h34M8 41h32a1 1 0 001-1V10a1 1 0 00-1-1H8a1 1 0 00-1 1v30a1 1 0 001 1zM34 5v8M14 5v8" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M7 22h34V10a1 1 0 00-1-1H8a1 1 0 00-1 1v30a1 1 0 001 1h18M34 5v8M14 5v8" stroke="#4E5969" stroke-width="4"/><path fill-rule="evenodd" clip-rule="evenodd" d="M36 44a9 9 0 100-18 9 9 0 000 18zm1.5-9.75V29h-3v8.25H42v-3h-4.5z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M6 13a1 1 0 011-1h34a1 1 0 011 1v26a1 1 0 01-1 1H7a1 1 0 01-1-1V13z" stroke="#4E5969" stroke-width="4"/><path d="M31 26a7 7 0 11-14 0 7 7 0 0114 0zM33 12l-1.862-3.724A.5.5 0 0030.691 8H17.309a.5.5 0 00-.447.276L15 12" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M24.937 34.829a1.2 1.2 0 01-1.874 0L9.56 17.949C8.93 17.165 9.49 16 10.497 16h27.006c1.007 0 1.566 1.164.937 1.95L24.937 34.829z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M13.171 24.937a1.2 1.2 0 010-1.874L30.051 9.56c.785-.629 1.949-.07 1.949.937v27.006c0 1.007-1.164 1.566-1.95.937L13.171 24.937z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M34.829 23.063c.6.48.6 1.394 0 1.874L17.949 38.44c-.785.629-1.949.07-1.949-.937V10.497c0-1.006 1.164-1.566 1.95-.937l16.879 13.503z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M23.063 13.171a1.2 1.2 0 011.874 0l13.503 16.88c.629.785.07 1.949-.937 1.949H10.497c-1.006 0-1.566-1.164-.937-1.95l13.503-16.879z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" fill="#4E5969" stroke="#4E5969" stroke-width="4"/><path d="M15 22l7 7 11.5-11.5" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" stroke="#4E5969" stroke-width="4"/><path d="M15 22l7 7 11.5-11.5" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M7 8a1 1 0 011-1h32a1 1 0 011 1v32a1 1 0 01-1 1H8a1 1 0 01-1-1V8z" stroke="#4E5969" stroke-width="4"/><path d="M34.603 16.672L21.168 30.107l-7.778-7.779" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M41.678 11.05L19.05 33.678 6.322 20.95" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M22 21h-5v4.094h5V21zM26 25.094V21h5v4.094h-5z" fill="#4E5969"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 4C12.954 4 4 12.954 4 24s8.954 20 20 20 20-8.954 20-20S35.046 4 24 4zm2 13v-5h-4v5h-6.5a2.5 2.5 0 00-2.5 2.5v7.094a2.5 2.5 0 002.5 2.5H22V36h4v-6.906h6.5a2.5 2.5 0 002.5-2.5V19.5a2.5 2.5 0 00-2.5-2.5H26z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" stroke="#4E5969" stroke-width="4"/><path d="M24 14v10h9.5" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" fill="#4E5969" stroke="#4E5969" stroke-width="4"/><path d="M17.643 17.643l6.363 6.364m0 0l6.364 6.364m-6.364-6.364l6.364-6.364m-6.364 6.364l-6.363 6.364" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18zM17.643 17.643l6.364 6.364 6.364 6.364" stroke="#4E5969" stroke-width="4"/><path d="M30.37 17.643l-6.363 6.364-6.364 6.364" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M38.142 9.858L24 24 9.858 38.142M9.858 9.858L24 24l14.142 14.142" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M43 22c0-7.732-6.492-14-14.5-14S14 14.268 14 22v.055A9.001 9.001 0 0015 40h13" stroke="#4E5969" stroke-width="4"/><path d="M44.142 34.071l-7.07 7.071L30 34.071M37.07 26v15" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M5 29a9 9 0 009 9h19c5.523 0 10-4.477 10-10 0-5.312-4.142-9.657-9.373-9.98C32.3 12.833 27.598 9 22 9c-6.606 0-11.965 5.338-12 11.935A9 9 0 005 29z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M29 6h4a3 3 0 013 3v10c0 3 4.343 5 6 5-1.657 0-6 2-6 5v10a3 3 0 01-3 3h-4M19 6h-4a3 3 0 00-3 3v10c0 3-4.343 5-6 5 1.657 0 6 2 6 5v10a3 3 0 003 3h4" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M39 6H9a1 1 0 00-1 1v34a1 1 0 001 1h30a1 1 0 001-1V7a1 1 0 00-1-1z" stroke="#4E5969" stroke-width="4"/><path d="M8 7a1 1 0 011-1h30a1 1 0 011 1v34a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM32.072 16.518l-4.14 15.454" stroke="#4E5969" stroke-width="4"/><path d="M23.071 17L16 24.071l7.071 7.071" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M27.2 6.28l-6.251 35.453M16.734 12.686L5.42 24l11.314 11.314M31.255 12.686L42.57 24 31.255 35.314" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M29 19v10H19V19h10zM13 29a6 6 0 106 6v-6h-6zM35 29a6 6 0 11-6 6v-6h6zM13 19a6 6 0 116-6v6h-6zM35 19a6 6 0 10-6-6v6h6z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M24 23L7.652 14.345M24 23l16.366-8.664M24 23v19.438M7 14v20l17 9 17-9V14L24 5 7 14z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" stroke="#4E5969" stroke-width="4"/><path d="M21.177 21.183l10.108-4.717a.2.2 0 01.266.265L26.834 26.84l-10.109 4.717a.2.2 0 01-.266-.266l4.718-10.108z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg" class="arco-icon arco-icon-computer" style="font-size: 40px;" stroke-width="4" stroke-linecap="butt" stroke-linejoin="miter" filter="" data-v-249840b0=""><path d="M41 7H7v22h34V7Z"></path><path d="M23.778 29v10"></path><path d="M16 39h16"></path><path d="m20.243 14.657 5.657 5.657M15.414 22.314l7.071-7.071M24.485 21.728l7.071-7.071"></path></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M20 6h18a2 2 0 012 2v22" stroke="#4E5969" stroke-width="4"/><path d="M8 40V16a2 2 0 012-2h20c1.105 0 2 .892 2 1.997v24.011A1.99 1.99 0 0130.003 42H9.996A1.996 1.996 0 018 40z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18zM29.292 18a8 8 0 100 12" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M11 31V20c0-7.18 5.82-13 13-13s13 5.82 13 13v8c0 5.784-3.778 10.686-9 12.373" stroke="#4E5969" stroke-width="4"/><path d="M24 41c1.396 0 2.74-.22 4-.627V38a1 1 0 00-1-1h-6a1 1 0 00-1 1v2a1 1 0 001 1h3zM11 21H8a1 1 0 00-1 1v6a1 1 0 001 1h3M37 20v8m0-7h3a1 1 0 011 1v6a1 1 0 01-1 1h-3v-8z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M36.597 37c3.725-3.667 5.33-8.37 5.211-13-.112-4.38-1.767-8.694-4.627-12C34.07 8.404 29.531 6 24 6c-5.724 0-10.384 2.574-13.5 6.38C6.99 16.662 5.44 22.508 6.53 28c.646 3.258 2.223 6.391 4.873 9M10.5 12.38L17 17.5M6.53 28l8.97-3.5M41.808 24H33.5M37.181 12L31 17.5M24 6v7.5" stroke="#4E5969" stroke-width="4"/><path d="M24 32a5 5 0 100 10 5 5 0 000-10zm0 0V19" stroke="#4E5969" stroke-width="4" stroke-linejoin="round"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M5 11h5.5m0 0v29a1 1 0 001 1h25a1 1 0 001-1V11m-27 0H16m21.5 0H43m-5.5 0H32m-16 0V7h16v4m-16 0h16M20 18v15m8-15v15" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M24 32v8m0 0h-9m9 0h9M7 32h34a1 1 0 001-1V9a1 1 0 00-1-1H7a1 1 0 00-1 1v22a1 1 0 001 1z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="6.998" y="7" width="34" height="34" rx="1.5" stroke="#4E5969" stroke-width="4"/><circle cx="16" cy="16" r="2" stroke="#4E5969" stroke-width="4"/><circle cx="24" cy="24" r="2" stroke="#4E5969" stroke-width="4"/><circle cx="16" cy="32" r="2" stroke="#4E5969" stroke-width="4"/><circle cx="32" cy="16" r="2" stroke="#4E5969" stroke-width="4"/><circle cx="32" cy="32" r="2" stroke="#4E5969" stroke-width="4"/><circle cx="16" cy="16" r="2" fill="#4E5969"/><circle cx="24" cy="24" r="2" fill="#4E5969"/><circle cx="16" cy="32" r="2" fill="#4E5969"/><circle cx="32" cy="16" r="2" fill="#4E5969"/><circle cx="32" cy="32" r="2" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M9.9 22.456l14.142 14.142 14.142-14.142" stroke="#4E5969" stroke-width="4"/><path d="M9.9 11.142l14.142 14.142 14.142-14.142" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M25.544 9.9L11.402 24.042l14.142 14.142" stroke="#4E5969" stroke-width="4"/><path d="M36.858 9.9L22.716 24.042l14.142 14.142" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M22.456 38.1l14.142-14.142L22.456 9.816" stroke="#4E5969" stroke-width="4"/><path d="M11.142 38.1l14.142-14.142L11.142 9.816" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M38.1 25.544L23.958 11.402 9.816 25.544" stroke="#4E5969" stroke-width="4"/><path d="M38.1 36.858L23.958 22.716 9.816 36.858" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="18" transform="rotate(-180 24 24)" stroke="#4E5969" stroke-width="4"/><path d="M32.484 20.515L24 29l-8.485-8.485" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M39.6 17.444L24.044 33 8.487 17.444" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M33.072 22.071l-9.07 9.071-9.072-9.071M40 35v6H8v-6M24 5v26" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M7 24h34M24 7v34M30 12l-6-6-6 6M36 30l6-6-6-6M12 30l-6-6 6-6M18 36l6 6 6-6" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M17 8h2v2h-2V8zM17 23h2v2h-2v-2zM17 38h2v2h-2v-2zM29 8h2v2h-2V8zM29 23h2v2h-2v-2zM29 38h2v2h-2v-2z" fill="#4E5969"/><path d="M17 8h2v2h-2V8zM17 23h2v2h-2v-2zM17 38h2v2h-2v-2zM29 8h2v2h-2V8zM29 23h2v2h-2v-2zM29 38h2v2h-2v-2z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M40 17v2h-2v-2h2zM25 17v2h-2v-2h2zM10 17v2H8v-2h2zM40 29v2h-2v-2h2zM25 29v2h-2v-2h2zM10 29v2H8v-2h2z" fill="#4E5969"/><path d="M40 17v2h-2v-2h2zM25 17v2h-2v-2h2zM10 17v2H8v-2h2zM40 29v2h-2v-2h2zM25 29v2h-2v-2h2zM10 29v2H8v-2h2z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M10 42h28a1 1 0 001-1V17L28 6H10a1 1 0 00-1 1v34a1 1 0 001 1z" stroke="#4E5969" stroke-width="4"/><path d="M38.5 17H29a1 1 0 01-1-1V6.5" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M13 15.528C14.32 12.386 18.403 6.977 23.556 7c7.944.036 14.514 8.528 10.116 15.71-4.399 7.181-5.718 10.323-6.598 14.363-.82 3.766-9.288 7.143-11.498-1.515" stroke="#4E5969" stroke-width="4"/><path d="M20 18.5c1-3.083 4.5-4.5 6.5-2 2.85 3.562-3.503 8.312-5.5 12.5" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M30.479 19.038l5.734-5.734a1 1 0 000-1.414l-5.586-5.586a1 1 0 00-1.414 0l-5.734 5.734m7 7L15.763 33.754a1 1 0 01-.591.286l-6.047.708a1 1 0 01-1.113-1.069l.477-6.31a1 1 0 01.29-.631l14.7-14.7m7 7l-7-7M5.999 42h36" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="6" y="8" width="36" height="32" rx="1" stroke="#4E5969" stroke-width="4"/><path d="M37 17l-12.43 8.606a1 1 0 01-1.14 0L11 17" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M24 5v6m7 1l4-4m-18 4l-4-4m27 33H8a2 2 0 01-2-2v-8.46a2 2 0 01.272-1.007l6.15-10.54A2 2 0 0114.148 18H33.85a2 2 0 011.728.992l6.149 10.541A2 2 0 0142 30.541V39a2 2 0 01-2 2z" stroke="#4E5969" stroke-width="4"/><path d="M41.5 30H28s-1 3-4 3-4-3-4-3H6.5" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M23.2 4C12.596 4 4 12.596 4 23.2v1.6C4 35.404 12.596 44 23.2 44h1.6C35.404 44 44 35.404 44 24.8v-1.6C44 12.596 35.404 4 24.8 4h-1.6zm-9.086 10A2.114 2.114 0 0012 16.114v15.772c0 1.167.947 2.114 2.114 2.114H25v-4h-9v-4h7.778v-4H16v-4h9v-4H14.114zM32.4 22a5.4 5.4 0 00-5.4 5.4V34h4v-6.6a1.4 1.4 0 012.801 0V34h4v-6.6a5.4 5.4 0 00-5.4-5.4z" fill="#4E5969"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M25.5 40.503L14.914 40.5a1 1 0 01-.707-.293l-9-9a1 1 0 010-1.414L13.5 21.5 26.793 8.207a1 1 0 011.414 0l14.086 14.086a1 1 0 010 1.414L29 37l-3.5 3.503zm0 0L44 40.5M13.5 21.5L29 37" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M42 24c0 9.941-8.059 18-18 18S6 33.941 6 24 14.059 6 24 6s18 8.059 18 18z" fill="#4E5969" stroke="#4E5969" stroke-width="4"/><path d="M24 28V14M24 30v4" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M6 24c0-9.941 8.059-18 18-18s18 8.059 18 18-8.059 18-18 18S6 33.941 6 24zM24 28V14M24 30v4" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M16 6h16l10 11v14L32 42H16L6 31V17L16 6z" fill="#4E5969" stroke="#4E5969" stroke-width="4"/><path d="M24 28V14m0 16v4" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path stroke="#4E5969" stroke-width="4" d="M23 9h2v21h-2z"/><path fill="#4E5969" d="M23 9h2v21h-2z"/><path stroke="#4E5969" stroke-width="4" d="M23 37h2v2h-2z"/><path fill="#4E5969" d="M23 37h2v2h-2z"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M41 22V8c0-.552-.444-1-.996-1H26M7 26v14c0 .552.444 1 .996 1H22" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M10.5 7h6m0 0v10.5l-5.25 14-2.344 6.853A2 2 0 0010.798 41h26.758a2 2 0 001.86-2.737L37 32.167 31.5 17.5V7m-15 0h15m0 0h6M26 22.5v.01" stroke="#4E5969" stroke-width="4"/><path d="M11.25 31.5c1.917 1.833 7.05 4.4 12.25 0s11.167-1.389 13.5.667" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M31 41H7V7h24M32.071 33.142l9.071-9.07L32.071 15M17 24.07h24" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path d="M14 14.5c-2.69 2-5.415 5.33-8 9.5 5.373 8.667 11.373 13 18 13 3.325 0 6.491-1.09 9.5-3.271M17.463 12.5C19 11 21.75 11 24 11c6.627 0 12.627 4.333 18 13-1.766 2.848-3.599 5.228-5.5 7.14" stroke="#4E5969" stroke-width="4"/><path d="M29 24a5 5 0 11-10 0 5 5 0 0110 0zM6.853 7.103l34.294 34.294" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><path clip-rule="evenodd" d="M24 37c6.627 0 12.627-4.333 18-13-5.373-8.667-11.373-13-18-13-6.627 0-12.627 4.333-18 13 5.373 8.667 11.373 13 18 13z" stroke="#4E5969" stroke-width="4"/><path d="M29 24a5 5 0 11-10 0 5 5 0 0110 0z" stroke="#4E5969" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="20" fill="#4E5969"/><path d="M18 17v6M30 17v6M16.582 34a8 8 0 0114.837 0" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="20" fill="#4E5969"/><path d="M18 17v6M32 32H16M30 17v6" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
<svg width="48" height="48" viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="20" fill="#4E5969"/><path d="M18 17v6M30 17v6M16.582 28.105a8 8 0 0014.837 0" stroke="#fff" stroke-width="4"/></svg>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册