Initial commit: HZHub project setup with RuoYi-AI base

This commit is contained in:
2026-03-26 09:47:46 +00:00
commit 3584e491cc
5005 changed files with 318595 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is **ruoyi-web**, a Vue 3 AI chat application built with TypeScript, Vite, and Element Plus. It provides a chat interface for AI interactions with support for sessions, models, and various authentication methods.
## Commands
```bash
# Development
pnpm dev # Start dev server
# Build
pnpm build # Type-check and build for production
# Linting
pnpm lint # Run ESLint
pnpm lint:stylelint # Run Stylelint
pnpm fix # Auto-fix ESLint issues
# Preview production build
pnpm preview
```
## Architecture
### Tech Stack
- **Vue 3** with Composition API (`<script setup>`)
- **TypeScript** for type safety
- **Pinia** for state management with persistence (`pinia-plugin-persistedstate`)
- **Vue Router** for routing with navigation guards
- **Element Plus** for UI components
- **UnoCSS** for atomic CSS
- **hook-fetch** for HTTP requests with SSE support
### Directory Structure
```
src/
├── api/ # API modules (auth, chat, model, session) with types
├── assets/ # Static assets (SVG icons organized by category)
├── components/ # Reusable components (LoginDialog, ModelSelect, etc.)
├── config/ # App configuration constants
├── constants/ # Enum definitions
├── hooks/ # Custom Vue composables
├── layouts/ # Layout components (LayoutVertical, LayoutMobile)
├── pages/ # Page components (chat, error pages)
├── routers/ # Route definitions and guards
├── stores/ # Pinia stores (user, chat, session, model, design)
├── styles/ # Global SCSS styles and variables
├── utils/ # Utilities (request wrapper, markdown renderers)
└── main.ts # App entry point
```
### Key Patterns
**API Layer** (`src/api/`):
- Each module has `index.ts` for API calls and `types.ts` for TypeScript interfaces
- Uses `hook-fetch` with JWT plugin for authentication
- Base URL configured via `VITE_API_URL` environment variable
**State Management** (`src/stores/`):
- Stores use Composition API style with `defineStore`
- User store persists token and userInfo
- Session store handles chat sessions with pagination
- Chat store manages messages and deep thinking state
**Routing** (`src/routers/`):
- Static routes defined in `modules/staticRouter.ts`
- Route guard checks token and handles auth redirect
- White list routes bypass auth check
**HTTP Requests** (`src/utils/request.ts`):
- Auto-injects `Bearer` token and `ClientID` headers
- Handles 401 (logout) and 403 (redirect) responses
- Supports SSE streaming via `sseTextDecoderPlugin`
### Environment Variables
Configure in `.env.development`:
- `VITE_API_URL` - Backend API base URL
- `VITE_CLIENT_ID` - Client identifier for auth
- `VITE_WEB_TITLE` - Page title
### Code Style
- ESLint with `@antfu/eslint-config`
- Vue blocks order: script → template → style
- Single quotes, semicolons, 2-space indent
- Commit messages follow conventional commits with commitlint

View File

@@ -0,0 +1,44 @@
# 构建阶段
FROM node:22-alpine AS builder
# 接收构建参数
ARG VITE_API_URL
ARG VITE_APP_ENV=production
# 设置环境变量
ENV VITE_API_URL=${VITE_API_URL}
ENV VITE_APP_ENV=${VITE_APP_ENV}
# 设置工作目录
WORKDIR /app
# 复制 package 文件
COPY package.json pnpm-lock.yaml ./
# 安装 pnpm 并安装依赖
RUN npm install -g pnpm && \
pnpm install --frozen-lockfile
# 复制源代码
COPY . .
# 构建生产版本(使用 production 模式)
RUN pnpm build
# 生产阶段
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 设置后端地址环境变量(默认指向本机 6039 端口)
ENV UPSTREAM_URL=http://127.0.0.1:6039
# 复制 Nginx 配置并使用 envsubst 替换环境变量
COPY nginx.conf /etc/nginx/templates/default.conf.template
# 暴露端口
EXPOSE 5137
# 启动 Nginxdocker-compose 中可通过环境变量 UPSTREAM_URL 覆盖后端地址)
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -0,0 +1,150 @@
# RuoYi-AI 用户端
<div align="center">
<img src="https://github.com/ageerle/ruoyi-ai/raw/main/docs/image/logo.png" alt="RuoYi AI Logo" width="120" height="120">
### 企业级AI助手平台 - 用户前端
*RuoYi-AI 的用户前端,提供 AI 对话、智能体交互、知识库问答等功能*
**[在线体验](https://web.pandarobot.chat)** | **[后端服务](https://github.com/ageerle/ruoyi-ai)** | **[管理后台](https://github.com/ageerle/ruoyi-admin)**
</div>
## 技术栈
- **框架**: Vue 3 + TypeScript
- **UI组件**: Ant Design Vue
- **状态管理**: Pinia
- **构建工具**: Vite
## Docker 部署
本用户端支持两种 Docker 部署方式:
### 方式一:一键启动所有服务(推荐)
使用 `docker-compose-all.yaml` 可以一键启动所有服务(包括后端、管理端、用户端及依赖服务):
```bash
# 克隆后端仓库
git clone https://github.com/ageerle/ruoyi-ai.git
cd ruoyi-ai
# 启动所有服务(从镜像仓库拉取预构建镜像)
docker-compose -f docker-compose-all.yaml up -d
# 访问用户端
# 地址: http://localhost:25137
# 账号: admin / admin123
```
### 方式二:分步部署(源码编译)
如果您需要从源码构建,请按照以下步骤操作:
#### 第一步:部署后端服务
```bash
# 进入后端项目目录
cd ruoyi-ai
# 启动后端服务(源码编译构建)
docker-compose up -d --build
# 等待后端服务启动完成
docker-compose logs -f backend
```
#### 第二步:部署用户端
```bash
# 进入用户端项目目录
cd ruoyi-web
# 构建并启动用户端
docker-compose up -d --build
# 访问用户端
# 地址: http://localhost:5137
```
#### 第三步:部署管理端(可选)
```bash
# 进入管理端项目目录
cd ruoyi-admin
# 构建并启动管理端
docker-compose up -d --build
# 访问管理端
# 地址: http://localhost:5666
```
### 服务端口说明
| 服务 | 端口 | 说明 |
|------|------|------|
| 用户端 | 5137 | 用户前端访问地址 |
| 管理端 | 5666 | 管理后台访问地址 |
| 后端服务 | 6039 | 后端 API 服务 |
| MySQL | 23306 | 数据库服务 |
| Redis | 6379 | 缓存服务 |
| Weaviate | 28080 | 向量数据库 |
| MinIO | 9000/9090 | 对象存储 |
### 镜像仓库
所有镜像托管在阿里云容器镜像服务:
```
crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
```
可用镜像:
- `mysql:v3` - MySQL 数据库(包含初始化 SQL
- `redis:6.2` - Redis 缓存
- `weaviate:1.30.0` - 向量数据库
- `minio:latest` - 对象存储
- `ruoyi-ai-backend:latest` - 后端服务
- `ruoyi-ai-admin:latest` - 管理端前端
- `ruoyi-ai-web:latest` - 用户端前端
## 本地开发
```bash
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
# 构建生产版本
pnpm build
```
## 常见问题
**Q: 用户端无法连接后端服务?**
A: 请确保后端服务已启动,并检查环境变量 `UPSTREAM_URL` 配置是否正确。
**Q: 一键启动和分步部署有什么区别?**
A: 一键启动使用预构建的镜像,部署速度快;分步部署从源码编译,适合需要自定义修改的场景。
## 开源协议
本项目采用 **MIT 开源协议**,详情请查看 [license](license) 文件。
---
<div align="center">
**[⭐ 点个Star支持一下](https://github.com/ageerle/ruoyi-web)** • **[Fork 开始贡献](https://github.com/ageerle/ruoyi-web/fork)**
*用 ❤️ 打造,由 RuoYi AI 开源社区维护*
</div>

View File

@@ -0,0 +1,181 @@
# RuoYi-AI 一键启动全部服务
# 使用方式: docker-compose up -d
#
# 包含服务:
# - MySQL 8.0 (数据库包含初始化SQL)
# - Redis 6.2 (缓存)
# - Weaviate (向量数据库)
# - MinIO (对象存储)
# - RuoYi-Backend (后端服务)
# - RuoYi-Admin (管理端前端)
# - RuoYi-Web (用户端前端)
#
# 镜像仓库地址: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
version: '3.8'
services:
# ==================== MySQL 数据库 ====================
mysql:
# 阿里云镜像地址包含初始化SQL
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/mysql:v3
container_name: ruoyi-ai-mysql
restart: always
ports:
- "23306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: ruoyi-ai-agent
TZ: Asia/Shanghai
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"]
interval: 15s
timeout: 10s
retries: 10
start_period: 60s
networks:
- ruoyi-net
# ==================== Redis 缓存 ====================
redis:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/redis:6.2
container_name: ruoyi-ai-redis
restart: always
ports:
- "26379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- ruoyi-net
# ==================== Weaviate 向量数据库 ====================
weaviate:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/weaviate:1.30.0
container_name: ruoyi-ai-weaviate
restart: always
ports:
- "28080:8080"
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: true
PERSISTENCE_DATA_PATH: /var/lib/weaviate
DEFAULT_VECTORIZER_MODULE: none
ENABLE_MODULES: text2vec-cohere,text2vec-huggingface,text2vec-palm,text2vec-openai,generative-openai,generative-cohere,generative-palm,ref2vec-centroid,reranker-cohere,qna-openai
CLUSTER_HOSTNAME: node1
volumes:
- weaviate-data:/var/lib/weaviate
networks:
- ruoyi-net
# ==================== MinIO 对象存储 ====================
minio:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/minio:latest
container_name: ruoyi-ai-minio
restart: always
ports:
- "29000:9000"
- "29090:9090"
environment:
MINIO_ROOT_USER: ruoyi
MINIO_ROOT_PASSWORD: ruoyi123
volumes:
- minio-data:/data
command: server /data --console-address ":9090"
networks:
- ruoyi-net
# ==================== RuoYi-AI 后端服务 ====================
backend:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-backend:latest
container_name: ruoyi-ai-backend
restart: always
ports:
- "26039:6039"
environment:
TZ: Asia/Shanghai
# MySQL 配置
SPRING_DATASOURCE_DYNAMIC_PRIMARY: master
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_DRIVERCLASSNAME: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL: jdbc:mysql://mysql:3306/ruoyi-ai-agent?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_USERNAME: root
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_PASSWORD: root
# Redis 配置
SPRING_DATA_REDIS_HOST: redis
SPRING_DATA_REDIS_PORT: 6379
SPRING_DATA_REDIS_DATABASE: 0
# 日志配置
LOGGING_LEVEL_ORG_RUOYI: info
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK: warn
SYS_UPLOAD_PATH: /ruoyi/upload
volumes:
- logs-data:/ruoyi/server/logs
- upload-data:/ruoyi/upload
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
networks:
- ruoyi-net
# ==================== RuoYi-AI 管理端前端 ====================
admin-frontend:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-admin:latest
container_name: ruoyi-ai-admin
restart: always
ports:
- "25666:5666"
environment:
# 后端 API 地址 - 运行时动态配置(无需重新构建镜像)
# 在完整 docker-compose 中应设置为: http://backend:6039
# 独立运行时可设置为实际后端地址,如: 192.168.1.100:6039
UPSTREAM_HOST: backend:6039
# 资源限制 - 防止 CPU 和内存耗尽
deploy:
resources:
limits:
cpus: '2'
memory: 3G
reservations:
cpus: '1'
memory: 1G
depends_on:
- backend
networks:
- ruoyi-net
# ==================== RuoYi-AI 用户端前端 ====================
web-frontend:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-web:latest
container_name: ruoyi-ai-web
restart: always
ports:
- "25137:5137"
environment:
UPSTREAM_URL: http://backend:6039
depends_on:
- backend
networks:
- ruoyi-net
# ==================== 网络配置 ====================
networks:
ruoyi-net:
driver: bridge
# ==================== 数据卷配置 ====================
volumes:
mysql-data:
redis-data:
weaviate-data:
minio-data:
logs-data:
upload-data:

View File

@@ -0,0 +1,24 @@
version: '3.8'
services:
# ==================== RuoYi-AI 前端服务 ====================
frontend:
build:
context: .
dockerfile: Dockerfile.frontend
container_name: ruoyi-ai-web
restart: always
ports:
- "5137:5137"
environment:
# 后端 API 地址 - 运行时通过 nginx 代理
# 在完整 docker-compose 中应设置为: http://backend:6039
# 独立运行时可设置为实际后端地址
UPSTREAM_URL: http://host.docker.internal:26039
networks:
- ruoyi-net
# ==================== 网络配置 ====================
networks:
ruoyi-net:
driver: bridge

View File

@@ -0,0 +1,38 @@
import antfu from "@antfu/eslint-config";
// 使用 antfu 配置
export default antfu({
vue: {
"vue/block-order": [
"error",
{
// 块顺序
order: ["script", "template", "style"],
},
],
},
typescript: true,
stylistic: {
indent: 2, // 缩进
semi: true, // 语句分号
quotes: "single", // 单引号
},
rules: {
"new-cap": ["off", { newIsCap: true, capIsNew: false }],
"no-console": "off", // 忽略console
},
ignores: [
"**/dist/**",
"**/node_modules/**",
"**/build/**",
"**/lib/**",
"**/es/**",
"**/types/**",
"**/public/**",
"**/vite.config.ts",
"**/eslint.config.js",
"./*.cjs",
"./*.js",
"./package.json",
],
});

View File

@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>%VITE_WEB_TITLE%</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 ruoyi-ai
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,75 @@
server {
listen 5137;
server_name localhost;
# gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_disable "MSIE [1-6]\.";
# 静态文件目录
root /usr/share/nginx/html;
index index.html;
# 访问日志
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 前端路由 fallback
location / {
try_files $uri $uri/ /index.html;
}
# API 代理 - 代理所有后端 API 请求
# 匹配常见的后端 API 路径前缀
location ~ ^/(system|chat|auth|resource|agent|knowledge|workflow)/ {
proxy_pass ${UPSTREAM_URL};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 支持 WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 兼容 /api 前缀的请求
location /api {
proxy_pass ${UPSTREAM_URL};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 支持 WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
}

17297
hzhub-portal-company/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
{
"name": "ruoyi-web",
"type": "module",
"version": "0.0.0",
"private": true,
"description": "ruoyi-web open-source PC AI template",
"author": {
"name": "HeJiaYue520",
"email": "2834007710@qq.com",
"url": "https://github.com/HeJiaYue520/HeJiaYue520"
},
"license": "MIT",
"homepage": "https://github.com/element-plus-x/ruoyi-element-ai",
"repository": {
"type": "git",
"url": "git@github.com:element-plus-x/ruoyi-element-ai.git"
},
"bugs": {
"url": "https://github.com/element-plus-x/ruoyi-element-ai/issues"
},
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview",
"prepare": "husky",
"lint": "eslint .",
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"fix": "eslint . --fix"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@floating-ui/core": "^1.7.2",
"@floating-ui/dom": "^1.7.2",
"@floating-ui/vue": "^1.1.7",
"@jsonlee_12138/enum": "^1.0.4",
"@vueuse/core": "^13.5.0",
"@vueuse/integrations": "^13.5.0",
"echarts": "^6.0.0",
"element-plus": "^2.10.4",
"hook-fetch": "2.0.4-beta.1",
"nprogress": "^0.2.0",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"qrcode": "^1.5.4",
"radash": "^12.1.1",
"reset-css": "^5.0.2",
"vue": "^3.5.17",
"vue-element-plus-x": "1.3.0",
"vue-router": "4"
},
"devDependencies": {
"@antfu/eslint-config": "^4.16.2",
"@changesets/cli": "^2.29.5",
"@commitlint/config-conventional": "^19.8.1",
"@vitejs/plugin-vue": "^6.0.0",
"@vue/tsconfig": "^0.7.0",
"commitlint": "^19.8.1",
"cz-git": "^1.12.0",
"eslint": "^9.31.0",
"husky": "^9.1.7",
"lint-staged": "^16.1.2",
"postcss": "8.4.31",
"postcss-html": "1.5.0",
"prettier": "^3.6.2",
"sass-embedded": "^1.89.2",
"stylelint": "^16.21.1",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recess-order": "^7.1.0",
"stylelint-config-recommended-scss": "^15.0.1",
"stylelint-config-recommended-vue": "^1.6.1",
"stylelint-config-standard": "^38.0.0",
"stylelint-config-standard-scss": "^15.0.1",
"typescript": "~5.8.3",
"typescript-api-pro": "^0.0.7",
"unocss": "66.3.3",
"unplugin-auto-import": "^19.3.0",
"unplugin-vue-components": "^28.8.0",
"vite": "6.0.0",
"vite-plugin-env-typed": "^0.0.2",
"vite-plugin-svg-icons": "^2.0.1",
"vue-tsc": "^3.0.1"
},
"config": {
"commitizen": {
"path": "node_modules/cz-git"
}
}
}

9935
hzhub-portal-company/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve"> <image id="image0" width="32" height="32" x="0" y="0"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAIGNIUk0AAHomAACAhAAA+gAAAIDo
AAB1MAAA6mAAADqYAAAXcJy6UTwAAAAGYktHRAD/AP8A/6C9p5MAAAW1SURBVFjD7ZZdjF1VGYbf
b6299t7n/8ycOZ1OO+m0FSkFKVjpBSogTY20EocwiT+ICojaqMC0kaBoMI0RApW2JNUE00TShGoI
NcGCFrCmMaMQbYq2QinD37Sd/86cnjPn7N+11ue1sad2vOFmntu1kvfJu76sfMACC3zA0IUOpXTx
9I+O4Ivb1uDlR6fgCBdWWTS5iYIq4Z8TRzCjInSvuhE6mAFlizCSEMgEe5/9FgY2bMPjm9chTcL/
T+Dgw6dQ13VcmrsMk8nZjO9kSkZxPDp35Fyl+zqObBOzrgCrPMYmXqTysuvLRgovRFiPuqphNHkC
5OexvX9Z2wznQgJj6Rl8quNaTMSNG8tO+QEjsFQIhD2dn3gjsno/rPkTMwDW67uXbhhIiC63knzj
qnGOgsc6Fq8+VBt9DUQSzOb8LbcL33z7z7B+yWcwl4bLPOnvZYHxFGanFvaoFlhuHHl36nqfto77
eSPEF1jgfQ3z61Ty7xNXrDau/HKkWy+IfKWu2MX7xw7PrwFrLTzhwcKuBUTBUPygA2c4EYzTyZnn
ym7vrpTE3Y3mNITn7ZGuvU/45SBRjBDRSZD/knGctUTylEnT+T+BAIGIQEwZMCfamlYiDZo26VyU
6X3YCOcma8ItJIVSufJgKq3WHDzI7NQE25YGYkOUISIYMNrntGFlXx+MsLCCR1hQTgqnr8XNUkbm
dzsQm4yJ7kHg7zp9zmzXNr7XEN1s3dxuN4xKLFUfiHIMPsWwuHLtx9oKtJ2BidEYm9b1w8I0Jan+
hHWVhL9RSrUhQfLNxaXi8zPxOFTBotDXfWJurjVsPPXdxJUrEpiPsFIFpmQnsY2e+ckP0Jp5e34N
HH/vdxhunUROlGqazW+0tXfNBbWbwXpwSab4h+EzJ6BbLYQmxtg7w9DV0vMp0q2pFLdEc/U706Cx
z5wNaq3xf2Hq5MH5P8GOwRewprgOb82+iTONUyNBGijPzb472Rr/40h9Er7XgeNvD+H144eRFkto
1iZRb4y9NHdu4l2ZL3qWzYjJSODKa3HH06/OX+DD3atRS2fQUahUFxWXDqacDCsvt6pY7Nk6lYxK
60hcc00/Vn2yH2AGTZ6WfkfvoMwWVljot2S5vFXkVVXVGhA9vfMXmNCnUXUqyIjsVxyhPlTMl+80
0uyA49xX7Vh1z2z9DREKhjKEeOSocHtX3wsptzh+bhf58q5EYmXq+7dzqYjM1PT8hvD+b+zBxxet
R2Siqiv9xy3xy9cvzj/5j3D6CEm3yzjOFlHsYZMRf0+CuuMtveJ77LgPGTK/itPaTzNXL3pvrpGu
SJX8XKyb+9POzqCMIkaOHvqvrPP+A77nwyMPTPYqYiyzMN9/ZTyEyGbDIKr9kPKVxAh6oDY7fYkq
V6HJHWCT/pKjuR9n/Hw4PhoBsAeslLdZqdZYIQ6pTOa8DZxXoFKoQAgJA14CQBpOa4mQcLQAZavN
uq4/EsR6uaNyX9daI2hMP4esfMR0drYaMgIZAy24ZgmSSfRACJRXLL94gaDZhKkYWPAYCVLS8b7d
4pAZglknH/WcwgB5Yp1A+ueJ1hhUd88Nadbdp23yLMi+5sQWJud9hwW5sHacLWDj5OIFUp0ioghs
zSueEHtJyK95yN3Kkq0VAAkcZ5j7dVz/baHShUTJAUt0BztqOykFVhAQUDD6KUTBq0JImDYCbfeB
v+4MoMmgxc2cJ/PXpSQuiyXCWJjXI4qP2XxXoxlNo5kjcLEL59LpYpL11ySevCJRlEkde0InrSGb
zbZYAPuuKlx8AwBwbOpvuLTnakjjtATJg0qog5oYBAZA+OptwC+eOItZ30FpYxfoADWIxBBJd4gc
ARYxWEoQA3R4qF3MhTciAHjmsZMwVmNl3+WYDUNs+/kt2HTDZjy049b/uPelR/fjnT1P4rN/eRFO
FRg78CZIKezeeMn/ilhggQU+WP4Ne/S05BHkAUAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjYtMDMt
MTlUMDk6MDA6NDArMDA6MDCEOXtUAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDI2LTAzLTE5VDA5OjAw
OjQwKzAwOjAw9WTD6AAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyNi0wMy0xOVQwOTowMDo0MCsw
MDowMKJx4jcAAAAASUVORK5CYII=" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,7 @@
<script setup lang="ts"></script>
<template>
<router-view />
</template>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,10 @@
import type { EmailCodeDTO, LoginDTO, LoginVO, RegisterDTO } from './types';
import { post } from '@/utils/request';
export const login = (data: LoginDTO) => post<LoginVO>('/auth/login', data).json();
// 邮箱验证码
export const emailCode = (data: EmailCodeDTO) => post('/resource/email/code', data).json();
// 注册账号
export const register = (data: RegisterDTO) => post('/auth/register', data).json();

View File

@@ -0,0 +1,150 @@
export interface LoginDTO {
username: string;
password: string;
code?: string;
clientId?: string;
grantType?: string;
tenantId?: string;
uuid?: string;
// 二次确认密码
confirmPassword?: string;
}
export interface LoginVO {
access_token?: string;
token?: string;
userInfo?: LoginUser;
}
/**
* LoginUser登录用户身份权限
*/
export interface LoginUser {
/**
* 微信头像
*/
avatar?: string;
/**
* 浏览器类型
*/
browser?: string;
/**
* 部门ID
*/
deptId?: number;
/**
* 部门名
*/
deptName?: string;
/**
* 过期时间
*/
expireTime?: number;
/**
* 登录IP地址
*/
ipaddr?: string;
/**
* 获取登录id
*/
loginId?: string;
/**
* 登录地点
*/
loginLocation?: string;
/**
* 登录时间
*/
loginTime?: number;
/**
* 菜单权限
*/
menuPermission?: string[];
/**
* 用户名
*/
nickName?: string;
/**
* 操作系统
*/
os?: string;
/**
* 数据权限 当前角色ID
*/
roleId?: number;
/**
* 角色权限
*/
rolePermission?: string[];
/**
* 角色对象
*/
roles?: RoleDTO[];
/**
* 租户ID
*/
tenantId?: string;
/**
* 用户唯一标识
*/
token?: string;
/**
* 用户ID
*/
userId?: number;
/**
* 用户名
*/
username?: string;
/**
* 用户类型
*/
userType?: string;
}
/**
* RoleDTO角色
*/
export interface RoleDTO {
/**
* 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限
*/
dataScope?: string;
/**
* 角色ID
*/
roleId?: number;
/**
* 角色权限
*/
roleKey?: string;
/**
* 角色名称
*/
roleName?: string;
}
// 邮箱验证码
export interface EmailCodeDTO {
username?: string;
}
// 邮箱注册
export interface RegisterDTO {
/**
* 邮箱
*/
username: string;
/**
* 密码
*/
password: string;
/**
* 验证码
*/
code: string;
/**
* 确认密码
*/
confirmPassword?: string;
}

View File

@@ -0,0 +1,30 @@
import type { ChatMessageVo, GetChatListParams, SendDTO, workflowVo } from './types';
import { get, post } from '@/utils/request';
// 发送消息
export const send = (data: SendDTO) => post('/chat/send', data);
// 新增对应会话聊天记录
export function addChat(data: ChatMessageVo) {
return post('/system/message', data).json();
}
// 获取当前会话的聊天记录
export function getChatList(params: GetChatListParams) {
return get<ChatMessageVo[]>('/system/message/list', params).json();
}
// 获取知识库列表
export function getKnowledgeList() {
return get('/system/info/list').json();
}
// 获取工作流列表
export function getWorkflowList(params: workflowVo) {
// 将参数转换为查询字符串
const queryString = new URLSearchParams(params as Record<string, string>).toString();
// 拼接 URL
const url = `/admin/workflow/search?${queryString}`;
// 发送 POST 请求
return post<workflowVo[]>(url, {}).json();
}

View File

@@ -0,0 +1,283 @@
/**
* 工作流请求体
*/
export interface WorkFlowRunner {
workflowId?: string;
inputs?: {
name: string;
type: string;
content: {
value: string;
type: string;
};
}[];
}
/**
* 人机交互信息体
*/
export interface ReSumeRunner {
runtimeUuid?: string;
feedbackContent?: string;
}
/**
* SSE 事件类型
*/
export type SseEventType = 'content' | 'reasoning' | 'done' | 'error' | 'message';
/**
* SSE 事件数据
*/
export interface SseEventData {
/**
* 事件类型
*/
event: SseEventType;
/**
* 消息内容
*/
content?: string;
/**
* 推理内容(深度思考模式)
*/
reasoningContent?: string;
/**
* 错误信息
*/
error?: string;
/**
* 是否完成
*/
done?: boolean;
}
/**
* ChatRequest描述对话请求对象
*/
export interface SendDTO {
/**
* 传入的模型(必填)
*/
model: string;
/**
* 对话消息(必填)
*/
content: string;
/**
* 工作流请求体
*/
workFlowRunner?: WorkFlowRunner;
/**
* 人机交互信息体
*/
reSumeRunner?: ReSumeRunner;
/**
* 是否为人机交互用户继续输入
*/
isResume?: boolean;
/**
* 是否启用工作流
*/
enableWorkFlow?: boolean;
/**
* 会话id
*/
sessionId?: string;
/**
* 知识库id
*/
knowledgeId?: string;
/**
* 应用ID
*/
appId?: string;
/**
* 对话id(每个聊天窗口都不一样)
*/
uuid?: number;
/**
* 是否启用深度思考
*/
enableThinking?: boolean;
/**
* 是否支持联网
*/
enableInternet?: boolean;
}
/**
* Message描述
*/
export interface Message {
content?: string;
name?: string;
reasoning_content?: string;
/**
* 目前支持四个中角色参考官网,进行情景输入:
* https://platform.openai.com/docs/guides/chat/introduction
*/
role?: 'system' | 'user' | 'assistant' | 'function' | 'tool';
tool_call_id?: string;
/**
* The tool calls generated by the model, such as function calls.
*/
tool_calls?: ToolCalls[];
}
/**
* ToolCallsThe tool calls generated by the model, such as function calls.
*/
export interface ToolCalls {
function?: ToolCallFunction;
/**
* The ID of the tool call.
*/
id?: string;
/**
* The type of the tool. Currently, only function is supported.
*/
type?: string;
}
/**
* ToolCallFunctionToolCall 的 Function参数
* The function that the model called.
*/
export interface ToolCallFunction {
/**
* 方法参数
*/
arguments?: string;
/**
* 方法名
*/
name?: string;
}
export interface GetChatListParams {
/**
* 消息内容
*/
content?: string;
/**
* 创建者
*/
createBy?: number;
/**
* 创建部门
*/
createDept?: number;
/**
* 创建时间
*/
createTime?: Date;
/**
* 扣除金额
*/
deductCost?: number;
/**
* 主键
*/
id?: number;
/**
* 排序的方向desc或者asc
*/
isAsc?: string;
/**
* 模型名称
*/
modelName?: string;
/**
* 排序列
*/
orderByColumn?: string;
/**
* 当前页数
*/
pageNum?: number;
/**
* 分页大小
*/
pageSize?: number;
/**
* 请求参数
*/
params?: { [key: string]: { [key: string]: any } };
/**
* 备注
*/
remark?: string;
/**
* 对话角色
*/
role?: string;
/**
* 会话id
*/
sessionId?: string;
/**
* 累计 Tokens
*/
totalTokens?: number;
/**
* 更新者
*/
updateBy?: number;
/**
* 更新时间
*/
updateTime?: Date;
/**
* 用户id
*/
userId?: number;
}
/**
* ChatMessageVo聊天消息视图对象 chat_message
*/
export interface ChatMessageVo {
/**
* 消息内容
*/
content?: string;
/**
* 扣除金额
*/
deductCost?: number;
/**
* 主键
*/
id?: number;
/**
* 模型名称
*/
modelName?: string;
/**
* 备注
*/
remark?: string;
/**
* 对话角色
*/
role?: string;
/**
* 会话id
*/
sessionId?: string;
/**
* 累计 Tokens
*/
totalTokens?: number;
/**
* 用户id
*/
userId?: number;
}
export interface workflowVo {
currentPage?: number;
pageSize?: number;
}

View File

@@ -0,0 +1,4 @@
export * from './auth';
export * from './chat';
export * from './model';
export * from './session';

View File

@@ -0,0 +1,7 @@
import type { GetSessionListVO } from './types';
import { get } from '@/utils/request';
// 获取当前用户的模型列表
export function getModelList() {
return get<GetSessionListVO[]>('/system/model/modelList').json();
}

View File

@@ -0,0 +1,14 @@
// 查询用户模型列表返回的数据结构
export interface GetSessionListVO {
id?: number;
category?: string;
modelName?: string;
modelDescribe?: string;
modelPrice?: number;
modelType?: string;
modelShow?: string;
systemPrompt?: string;
apiHost?: string;
apiKey?: string;
remark?: string;
}

View File

@@ -0,0 +1,27 @@
import type {
ChatSessionVo,
CreateSessionDTO,
// CreateSessionVO,
GetSessionListParams,
} from './types';
import { del, get, post, put } from '@/utils/request';
export function get_session_list(params: GetSessionListParams) {
return get<ChatSessionVo[]>('/system/session/list', params).json();
}
export function create_session(data: CreateSessionDTO) {
return post('/system/session', data).json();
}
export function update_session(data: ChatSessionVo) {
return put('/system/session', data).json();
}
export function get_session(id: string) {
return get<ChatSessionVo>(`/system/session/${id}`).json();
}
export function delete_session(ids: string[]) {
return del(`/system/session/${ids}`).json();
}

View File

@@ -0,0 +1,154 @@
import type { Component } from 'vue';
export interface GetSessionListParams {
/**
* 创建者
*/
createBy?: number;
/**
* 创建部门
*/
createDept?: number;
/**
* 创建时间
*/
createTime?: Date;
/**
* 主键
*/
id?: number;
/**
* 排序的方向desc或者asc
*/
isAsc?: string;
/**
* 排序列
*/
orderByColumn?: string;
/**
* 当前页数
*/
pageNum?: number;
/**
* 分页大小
*/
pageSize?: number;
/**
* 请求参数
*/
params?: { [key: string]: { [key: string]: any } };
/**
* 备注
*/
remark?: string;
/**
* 会话内容
*/
sessionContent?: string;
/**
* 会话标题
*/
sessionTitle?: string;
/**
* 更新者
*/
updateBy?: number;
/**
* 更新时间
*/
updateTime?: Date;
/**
* 用户id
*/
userId: number;
}
/**
* ChatSessionVo会话管理视图对象 chat_session
*/
export interface ChatSessionVo {
/**
* 主键
*/
// id?: number
id?: string;
/**
* 备注
*/
remark?: string;
/**
* 会话内容
*/
sessionContent?: string;
/**
* 会话标题
*/
sessionTitle?: string;
/**
* 用户id
*/
userId?: number;
/**
* 创建时间
*/
createTime?: Date;
/**
* 自定义的消息前缀图标字段
*/
prefixIcon?: Component;
}
/**
* ChatSessionBo会话管理业务对象 chat_session
*/
export interface CreateSessionDTO {
/**
* 创建者
*/
createBy?: number;
/**
* 创建部门
*/
createDept?: number;
/**
* 创建时间
*/
createTime?: Date;
/**
* 主键
*/
// id?: number;
id?: string;
/**
* 请求参数
*/
params?: { [key: string]: { [key: string]: any } };
/**
* 备注
*/
remark?: string;
/**
* 会话内容
*/
sessionContent?: string;
/**
* 会话标题
*/
sessionTitle: string;
/**
* 更新者
*/
updateBy?: number;
/**
* 更新时间
*/
updateTime?: Date;
/**
* 用户id
*/
userId: number;
}
// export interface CreateSessionVO {
// id: number;
// }

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M18.901 10a2.999 2.999 0 0 0 4.075 1.113 3.5 3.5 0 0 1-1.975 3.55L21 21h-6v-2a3 3 0 0 0-5.995-.176L9 19v2H3v-6.336a3.5 3.5 0 0 1-1.979-3.553A2.999 2.999 0 0 0 5.098 10h13.803zm-1.865-7a3.5 3.5 0 0 0 4.446 2.86 3.5 3.5 0 0 1-3.29 3.135L18 9H6a3.5 3.5 0 0 1-3.482-3.14A3.5 3.5 0 0 0 6.964 3h10.072z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 448 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M18.901 10a2.999 2.999 0 0 0 4.075 1.113 3.5 3.5 0 0 1-1.975 3.55L21 21h-7v-2a2 2 0 0 0-1.85-1.995L12 17a2 2 0 0 0-1.995 1.85L10 19v2H3v-6.336a3.5 3.5 0 0 1-1.979-3.553A2.999 2.999 0 0 0 5.098 10h13.803zm-.971 2H6.069l-.076.079c-.431.42-.935.76-1.486 1.002l-.096.039.589.28-.001 5.6 3.002-.001v-.072l.01-.223c.149-2.016 1.78-3.599 3.854-3.698l.208-.005.223.01a4 4 0 0 1 3.699 3.787l.004.201L19 19l.001-5.6.587-.28-.095-.04a5.002 5.002 0 0 1-1.486-1.001L17.93 12zm-.894-9a3.5 3.5 0 0 0 4.446 2.86 3.5 3.5 0 0 1-3.29 3.135L18 9H6a3.5 3.5 0 0 1-3.482-3.14A3.5 3.5 0 0 0 6.964 3h10.072zM15.6 5H8.399a5.507 5.507 0 0 1-1.49 1.816L6.661 7h10.677l-.012-.008a5.518 5.518 0 0 1-1.579-1.722L15.6 5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 860 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12.513 2.001a9.004 9.004 0 0 0 9.97 5.877A4.501 4.501 0 0 1 19 11.888V19l2 .001v2H3v-2h2v-7.113a4.503 4.503 0 0 1-3.484-4.01 9.004 9.004 0 0 0 9.972-5.876h1.025zM17 12H7V19h10v-7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 332 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M12.513 2.001a9.004 9.004 0 0 0 9.97 5.877A4.501 4.501 0 0 1 19 11.888V19l2 .001v2H3v-2h2v-7.113a4.503 4.503 0 0 1-3.484-4.01 9.004 9.004 0 0 0 9.972-5.876h1.025zM17 12H7V19h10v-7zm-5-6.673l-.11.155A11.012 11.012 0 0 1 5.4 9.736l-.358.073.673.19h12.573l.668-.19-.011-.002a11.01 11.01 0 0 1-6.836-4.326L12 5.326z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 483 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 20h20v2H2v-2zm2-8h2v7H4v-7zm5 0h2v7H9v-7zm4 0h2v7h-2v-7zm5 0h2v7h-2v-7zM2 7l10-5 10 5v4H2V7zm10 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 281 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 20h20v2H2v-2zm2-8h2v7H4v-7zm5 0h2v7H9v-7zm4 0h2v7h-2v-7zm5 0h2v7h-2v-7zM2 7l10-5 10 5v4H2V7zm2 1.236V9h16v-.764l-8-4-8 4zM12 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 19h2V6l6.394 2.74a1 1 0 0 1 .606.92V19h2v2H1v-2h2V5.65a1 1 0 0 1 .594-.914l7.703-3.424A.5.5 0 0 1 12 1.77V19z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 265 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 19V5.7a1 1 0 0 1 .658-.94l9.671-3.516a.5.5 0 0 1 .671.47v4.953l6.316 2.105a1 1 0 0 1 .684.949V19h2v2H1v-2h2zm2 0h7V3.855L5 6.401V19zm14 0v-8.558l-5-1.667V19h5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 314 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M10 10.111V1l11 6v14H3V7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 177 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M10 10.111V1l11 6v14H3V7l7 3.111zm2-5.742v8.82l-7-3.111V19h14V8.187L12 4.37z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20h2v2H1v-2h2V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v17zM8 11v2h3v-2H8zm0-4v2h3V7H8zm0 8v2h3v-2H8zm5 0v2h3v-2h-3zm0-4v2h3v-2h-3zm0-4v2h3V7h-3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 292 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20h2v2H1v-2h2V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v17zm-2 0V4H5v16h14zM8 11h3v2H8v-2zm0-4h3v2H8V7zm0 8h3v2H8v-2zm5 0h3v2h-3v-2zm0-4h3v2h-3v-2zm0-4h3v2h-3V7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 308 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 19h2v2H1v-2h2V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v15h2V9h3a1 1 0 0 1 1 1v9zM7 11v2h4v-2H7zm0-4v2h4V7H7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 256 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 19h2v2H1v-2h2V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v15h4v-8h-2V9h3a1 1 0 0 1 1 1v9zM5 5v14h8V5H5zm2 6h4v2H7v-2zm0-4h4v2H7V7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 275 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M9 19h3v-6.058L8 9.454l-4 3.488V19h3v-4h2v4zm12 2H3a1 1 0 0 1-1-1v-7.513a1 1 0 0 1 .343-.754L6 8.544V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1zm-5-10v2h2v-2h-2zm0 4v2h2v-2h-2zm0-8v2h2V7h-2zm-4 0v2h2V7h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 364 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 21H3a1 1 0 0 1-1-1v-7.513a1 1 0 0 1 .343-.754L6 8.544V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1zM9 19h3v-6.058L8 9.454l-4 3.488V19h3v-4h2v4zm5 0h6V5H8v2.127c.234 0 .469.082.657.247l5 4.359a1 1 0 0 1 .343.754V19zm2-8h2v2h-2v-2zm0 4h2v2h-2v-2zm0-8h2v2h-2V7zm-4 0h2v2h-2V7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 434 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 19V8H1V6h3V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2h3v2h-1v11h1v2H1v-2h1zm11 0v-7h-2v7h2zm-5 0v-7H6v7h2zm10 0v-7h-2v7h2zM6 5v1h12V5H6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 283 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 6h3v2h-1v11h1v2H1v-2h1V8H1V6h3V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2zm0 2H4v11h3v-7h2v7h2v-7h2v7h2v-7h2v7h3V8zM6 5v1h12V5H6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 277 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 236 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12V9.157l-6-5.454-6 5.454V19z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 271 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zM8 15v2h8v-2H8z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 251 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12V9.157l-6-5.454-6 5.454V19zm2-4h8v2H8v-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zm-9-7v6h2v-6h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 252 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zm-6-2h5V9.157l-6-5.454-6 5.454V19h5v-6h2v6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 279 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.49a1 1 0 0 1 .386-.79l8-6.222a1 1 0 0 1 1.228 0l8 6.222a1 1 0 0 1 .386.79V20zm-10-7v6h2v-6h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M13 19h6V9.978l-7-5.444-7 5.444V19h6v-6h2v6zm8 1a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.49a1 1 0 0 1 .386-.79l8-6.222a1 1 0 0 1 1.228 0l8 6.222a1 1 0 0 1 .386.79V20z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.49a1 1 0 0 1 .386-.79l8-6.222a1 1 0 0 1 1.228 0l8 6.222a1 1 0 0 1 .386.79V20zM7 15v2h10v-2H7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 284 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.49a1 1 0 0 1 .386-.79l8-6.222a1 1 0 0 1 1.228 0l8 6.222a1 1 0 0 1 .386.79V20zm-2-1V9.978l-7-5.444-7 5.444V19h14zM7 15h10v2H7v-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 319 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-9H0l10.327-9.388a1 1 0 0 1 1.346 0L22 11h-3v9zm-8-5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12V9.157l-6-5.454-6 5.454V19zm6-4a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zM9 10v6h6v-6H9zm2 2h2v2h-2v-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 266 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12V9.157l-6-5.454-6 5.454V19zm3-9h6v6H9v-6zm2 2v2h2v-2h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 300 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.49a1 1 0 0 1 .386-.79l8-6.222a1 1 0 0 1 1.228 0l8 6.222a1 1 0 0 1 .386.79V20z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 268 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zM8.592 13.808l-.991.572 1 1.733.993-.573a3.5 3.5 0 0 0 1.405.811v1.145h2.002V16.35a3.5 3.5 0 0 0 1.405-.81l.992.572L16.4 14.38l-.991-.572a3.504 3.504 0 0 0 0-1.62l.991-.573-1-1.733-.993.573A3.5 3.5 0 0 0 13 9.645V8.5h-2.002v1.144a3.5 3.5 0 0 0-1.405.811l-.992-.573L7.6 11.616l.991.572a3.504 3.504 0 0 0 0 1.62zm3.408.69a1.5 1.5 0 1 1-.002-3.001 1.5 1.5 0 0 1 .002 3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 602 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12V9.157l-6-5.454-6 5.454V19zm2.591-5.191a3.508 3.508 0 0 1 0-1.622l-.991-.572 1-1.732.991.573a3.495 3.495 0 0 1 1.404-.812V8.5h2v1.144c.532.159 1.01.44 1.404.812l.991-.573 1 1.731-.991.573a3.508 3.508 0 0 1 0 1.622l.991.572-1 1.731-.991-.572a3.495 3.495 0 0 1-1.404.811v1.145h-2V16.35a3.495 3.495 0 0 1-1.404-.811l-.991.572-1-1.73.991-.573zm3.404.688a1.5 1.5 0 1 0 0-2.998 1.5 1.5 0 0 0 0 2.998z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 638 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zm-8-3l3.359-3.359a2.25 2.25 0 1 0-3.182-3.182l-.177.177-.177-.177a2.25 2.25 0 1 0-3.182 3.182L12 17z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 336 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zm-2-1V9.157l-6-5.454-6 5.454V19h12zm-6-2l-3.359-3.359a2.25 2.25 0 1 1 3.182-3.182l.177.177.177-.177a2.25 2.25 0 1 1 3.182 3.182L12 17z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 390 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.49a1 1 0 0 1 .386-.79l8-6.222a1 1 0 0 1 1.228 0l8 6.222a1 1 0 0 1 .386.79V20zm-2-1V9.978l-7-5.444-7 5.444V19h14z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 303 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.314a1 1 0 0 1 .38-.785l8-6.311a1 1 0 0 1 1.24 0l8 6.31a1 1 0 0 1 .38.786V20zM7 12a5 5 0 0 0 10 0h-2a3 3 0 0 1-6 0H7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 307 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M19 19V9.799l-7-5.522-7 5.522V19h14zm2 1a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9.314a1 1 0 0 1 .38-.785l8-6.311a1 1 0 0 1 1.24 0l8 6.31a1 1 0 0 1 .38.786V20zM7 12h2a3 3 0 0 0 6 0h2a5 5 0 0 1-10 0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 340 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zM7.5 13a4.5 4.5 0 1 0 9 0h-2a2.5 2.5 0 1 1-5 0h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M6 19h12V9.157l-6-5.454-6 5.454V19zm13 2H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM7.5 13h2a2.5 2.5 0 1 0 5 0h2a4.5 4.5 0 1 1-9 0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9zM7 11v2a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7zm0 4v3h3a3 3 0 0 0-3-3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 297 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M6 19h12V9.157l-6-5.454-6 5.454V19zm13 2H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM8 10a7 7 0 0 1 7 7h-2a5 5 0 0 0-5-5v-2zm0 4a3 3 0 0 1 3 3H8v-3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 20h2v2H1v-2h2V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v17zM11 8H9v2h2v2h2v-2h2V8h-2V6h-2v2zm3 12h2v-6H8v6h2v-4h4v4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 263 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M8 20v-6h8v6h3V4H5v16h3zm2 0h4v-4h-4v4zm11 0h2v2H1v-2h2V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v17zM11 8V6h2v2h2v2h-2v2h-2v-2H9V8h2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 297 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M17 19h2v-8h-6v8h2v-6h2v6zM3 19V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5h2v10h1v2H2v-2h1zm4-8v2h2v-2H7zm0 4v2h2v-2H7zm0-8v2h2V7H7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 276 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M22 21H2v-2h1V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5h2v10h1v2zm-5-2h2v-8h-6v8h2v-6h2v6zm0-10V5H5v14h6V9h6zM7 11h2v2H7v-2zm0 4h2v2H7v-2zm0-8h2v2H7V7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 296 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M22 20v2H2v-2h1v-6.758A4.496 4.496 0 0 1 1 9.5c0-.827.224-1.624.633-2.303L4.345 2.5a1 1 0 0 1 .866-.5H18.79a1 1 0 0 1 .866.5l2.702 4.682A4.496 4.496 0 0 1 21 13.242V20h1zM5.789 4L3.356 8.213a2.5 2.5 0 0 0 4.466 2.216c.335-.837 1.52-.837 1.856 0a2.5 2.5 0 0 0 4.644 0c.335-.837 1.52-.837 1.856 0a2.5 2.5 0 1 0 4.457-2.232L18.21 4H5.79z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 486 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 13.242V20h1v2H2v-2h1v-6.758A4.496 4.496 0 0 1 1 9.5c0-.827.224-1.624.633-2.303L4.345 2.5a1 1 0 0 1 .866-.5H18.79a1 1 0 0 1 .866.5l2.702 4.682A4.496 4.496 0 0 1 21 13.242zm-2 .73a4.496 4.496 0 0 1-3.75-1.36A4.496 4.496 0 0 1 12 14.001a4.496 4.496 0 0 1-3.25-1.387A4.496 4.496 0 0 1 5 13.973V20h14v-6.027zM5.789 4L3.356 8.213a2.5 2.5 0 0 0 4.466 2.216c.335-.837 1.52-.837 1.856 0a2.5 2.5 0 0 0 4.644 0c.335-.837 1.52-.837 1.856 0a2.5 2.5 0 1 0 4.457-2.232L18.21 4H5.79z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 623 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 13v7a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-7H2v-2l1-5h18l1 5v2h-1zM5 13v6h14v-6H5zm1 1h8v3H6v-3zM3 3h18v2H3V3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 259 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 13v7a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-7H2v-2l1-5h18l1 5v2h-1zM5 13v6h14v-6H5zm-.96-2h15.92l-.6-3H4.64l-.6 3zM6 14h8v3H6v-3zM3 3h18v2H3V3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 291 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 11.646V21a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-9.354A3.985 3.985 0 0 1 2 9V3a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v6c0 1.014-.378 1.94-1 2.646zM14 9a1 1 0 0 1 2 0 2 2 0 1 0 4 0V4H4v5a2 2 0 1 0 4 0 1 1 0 1 1 2 0 2 2 0 1 0 4 0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 368 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 11.646V21a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-9.354A3.985 3.985 0 0 1 2 9V3a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v6c0 1.014-.378 1.94-1 2.646zm-2 1.228a4.007 4.007 0 0 1-4-1.228A3.99 3.99 0 0 1 12 13a3.99 3.99 0 0 1-3-1.354 3.99 3.99 0 0 1-4 1.228V20h14v-7.126zM14 9a1 1 0 0 1 2 0 2 2 0 1 0 4 0V4H4v5a2 2 0 1 0 4 0 1 1 0 1 1 2 0 2 2 0 1 0 4 0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 487 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M21 3a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h18zM9.399 8h-2l-3.2 8h2.154l.4-1h3.29l.4 1h2.155L9.399 8zM19 8h-2v2h-1a3 3 0 0 0-.176 5.995L16 16h3V8zm-2 4v2h-1l-.117-.007a1 1 0 0 1 0-1.986L16 12h1zm-8.601-1.115L9.244 13H7.552l.847-2.115z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 411 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M21 3a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h18zm-1 2H4v14h16V5zM9.399 8l3.199 8h-2.155l-.4-1h-3.29l-.4 1H4.199l3.2-8h2zM19 8v8h-3a3 3 0 0 1 0-6h.999L17 8h2zm-2 4h-1a1 1 0 0 0-.117 1.993L16 14h1v-2zm-8.601-1.115L7.552 13h1.692l-.845-2.115z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 435 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 13h18v8.002c0 .551-.445.998-.993.998H3.993A.995.995 0 0 1 3 21.002V13zM3 2.998C3 2.447 3.445 2 3.993 2h16.014c.548 0 .993.446.993.998V11H3V2.998zM9 5v2h6V5H9zm0 11v2h6v-2H9z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 328 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 331 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 10h18v10.004c0 .55-.445.996-.993.996H3.993A.994.994 0 0 1 3 20.004V10zm6 2v2h6v-2H9zM2 4c0-.552.455-1 .992-1h18.016c.548 0 .992.444.992 1v4H2V4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 299 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 10H2V4.003C2 3.449 2.455 3 2.992 3h18.016A.99.99 0 0 1 22 4.003V10h-1v10.001a.996.996 0 0 1-.993.999H3.993A.996.996 0 0 1 3 20.001V10zm16 0H5v9h14v-9zM4 5v3h16V5H4zm5 7h6v2H9v-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 333 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm8-10a8 8 0 1 0-3.968 6.911l-1.008-1.727A6 6 0 1 1 18 12v1a1 1 0 0 1-2 0V9h-1.354a4 4 0 1 0 .066 5.94A3 3 0 0 0 20 13v-1zm-8-2a2 2 0 1 1 0 4 2 2 0 0 1 0-4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 380 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 12a8 8 0 1 0-3.562 6.657l1.11 1.664A9.953 9.953 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10v1.5a3.5 3.5 0 0 1-6.396 1.966A5 5 0 1 1 15 8H17v5.5a1.5 1.5 0 0 0 3 0V12zm-8-3a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 374 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20.997 2.992L21 21.008a1 1 0 0 1-.993.992H3.993A.993.993 0 0 1 3 21.008V2.992A1 1 0 0 1 3.993 2h16.01c.549 0 .994.444.994.992zM9 13V9a1 1 0 1 1 2 0v4a1 1 0 0 0 2 0V9a3 3 0 0 0-6 0v4a5 5 0 0 0 10 0V8h-2v5a3 3 0 0 1-6 0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 371 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M14 13.5V8a4 4 0 1 0-8 0v5.5a6.5 6.5 0 1 0 13 0V4h2v9.5a8.5 8.5 0 1 1-17 0V8a6 6 0 1 1 12 0v5.5a3.5 3.5 0 0 1-7 0V8h2v5.5a1.5 1.5 0 0 0 3 0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 292 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M17 15.245v6.872a.5.5 0 0 1-.757.429L12 20l-4.243 2.546a.5.5 0 0 1-.757-.43v-6.87a8 8 0 1 1 10 0zM12 15a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm0-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 319 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M17 15.245v6.872a.5.5 0 0 1-.757.429L12 20l-4.243 2.546a.5.5 0 0 1-.757-.43v-6.87a8 8 0 1 1 10 0zm-8 1.173v3.05l3-1.8 3 1.8v-3.05A7.978 7.978 0 0 1 12 17a7.978 7.978 0 0 1-3-.582zM12 15a6 6 0 1 0 0-12 6 6 0 0 0 0 12z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 368 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 13h6v8H2v-8zM9 3h6v18H9V3zm7 5h6v13h-6V8z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 196 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 13h6v8H2v-8zm14-5h6v13h-6V8zM9 3h6v18H9V3zM4 15v4h2v-4H4zm7-10v14h2V5h-2zm7 5v9h2v-9h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 243 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm4 10v4h2v-4H7zm4-6v10h2V7h-2zm4 3v7h2v-7h-2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 268 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm3 8h2v4H7v-4zm4-6h2v10h-2V7zm4 3h2v7h-2v-7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 12h4v9H3v-9zm14-4h4v13h-4V8zm-7-6h4v19h-4V2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 199 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 12h2v9H2v-9zm3 2h2v7H5v-7zm11-6h2v13h-2V8zm3 2h2v11h-2V10zM9 2h2v19H9V2zm3 2h2v17h-2V4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 242 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M2 12h2v9H2v-9zm3 2h2v7H5v-7zm11-6h2v13h-2V8zm3 2h2v11h-2V10zM9 2h2v19H9V2zm3 2h2v17h-2V4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 242 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 3v4H3V3h9zm4 14v4H3v-4h13zm6-7v4H3v-4h19z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 197 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 3v2H3V3h9zm4 16v2H3v-2h13zm6-8v2H3v-2h19z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 197 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g>
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 12h2v9H3v-9zm16-4h2v13h-2V8zm-8-6h2v19h-2V2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 199 B

Some files were not shown because too many files have changed in this diff Show More