同步完整源码至远程:扁平化重构现状 + 未入库源文件

- 补入库:server/internal/db/dump.go、redis 分页/扫描预算测试、opsxdb-mcp main_test、
  packages/opsxdb-mcp package-lock、docs 审计与对比文档等 37 个新文件
- 含结构扁平化进行中的 80 处修改与 155 处旧结构删除(server/ src/ src-tauri/ 为当前有效源)
- 构建产物(bin/target/dist)与签名私钥仍按规则排除
This commit is contained in:
logan committed 2026-10-16 03:47:33 +08:00
1 parent 5c0be49217
commit 2c0bfafd8d
269 files changed
+10372 -16435

No files matched your search

+9 -6
View File
@@ -23,7 +23,7 @@ jobs:
run: cd server && go test ./...
web:
name: Web + core packages
name: Desktop UI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -33,12 +33,10 @@ jobs:
cache: npm
- name: Install dependencies
run: npm ci
- name: Build web
run: npm run build:web
- name: Test core
run: npm run test:core
- name: Build desktop UI
run: npm run build:ui
- name: Test UI
run: npm run test:ui --if-present
run: npm test
rust:
name: Desktop (Tauri) cargo check
@@ -58,5 +56,10 @@ jobs:
libgtk-3-dev \
libxdo-dev
- uses: dtolnay/rust-toolchain@stable
- uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Prepare native sidecar
run: bash ./run.sh prepare
- name: Cargo check
run: cd src-tauri && cargo check
+10 -10
View File
@@ -7,26 +7,26 @@
```text
浏览器 → 只看官网 + 文档(Gin :8788)
操作 → 只走桌面 Tauri(./run.sh gui)
apps/web (:5174) → 仅桌面 Vite 源 / 打包 frontendDist,不是浏览器产品
src (:5174) → 仅桌面 Vite 源 / 打包 frontendDist,不是浏览器产品
```
- **不要**把工作台做成浏览器 SaaS,或把 `:5174` 当对外入口。
- Gin(`apps/server`)= 官网 / docs / health / 驱动相关 API;**不是**「远程多人协作后端」。
- Gin(`server`)= 官网 / docs / health / 驱动相关 API;**不是**「远程多人协作后端」。
- 连接与查询数据默认在本机;密钥与连接串按现有桌面安全实践处理。
同族:`opsxapi` 同形态;`opsxshell` 同样「浏览器=官网/docs,操作=桌面」(Gin 在 `apps/server`,**无**操作 API,原生全在 Rust)。
同族:`opsxapi` 同形态;`opsxshell` 同样「浏览器=官网/docs,操作=桌面」(Gin 在 `server`,**无**操作 API,原生全在 Rust)。
## 架构
```text
packages/ui + apps/web → packages/transport(tauri-native | gin) → 桌面 / 本机 Gin
apps/desktop → Tauri 2 壳
apps/server → Gin 官网 + docs + 驱动 API
src/ → React 桌面 UI / 本机 API
src-tauri/ → Tauri 2 壳
server/ → Gin 官网 + docs + 驱动 API
connection-types/ → 引擎注册表(ready / verified / notes)
agents/ → JDBC agent 桥(Java 单文件桥 + 协议文档;Go 侧在 apps/server/internal/db/agent.go)
agents/ → JDBC agent 桥(Java 单文件桥 + 协议文档;Go 侧在 server/internal/db/agent.go)
```
改驱动能力:先动注册表与 server/desktop 对应路径,再补 UI;未 `ready` 的引擎界面须灰态,勿标成可用。
改驱动能力:先动注册表与 server/src-tauri 对应路径,再补 UI;未 `ready` 的引擎界面须灰态,勿标成可用。
## 怎么跑
@@ -37,10 +37,10 @@ npm install
./run.sh stop | status | restart
```
改 `apps/server` 后需重编(`./run.sh restart`)。清单与验收见 `docs/BACKLOG.md`。
改 `server` 后需重编(`./run.sh restart`)。清单与验收见 `docs/BACKLOG.md`。
## 给 AI
- 跟现有 monorepo 分包,勿平行造第二套客户端。
- 沿用根级 src / src-tauri / server 架构,勿重建 apps 或第二套客户端;homepage 保持独立。
- 需求清楚就直接改;细节以邻近代码与 BACKLOG 为准,不必先扩写长规范。
- 少加「仅 AI 可读」的重复文档;用户可见文案与 docs 内容保持同步即可。
+1 -1
View File
@@ -2,7 +2,7 @@
请使用中文。规则以 [AGENTS.md](./AGENTS.md) 为准。
**浏览器 = Gin 官网 + `/docs`(:8788);操作只走桌面 Tauri。** `apps/web` 只是桌面打包源。
**浏览器 = Gin 官网 + `/docs`(:8788);操作只走桌面 Tauri。** `src` 只是桌面打包源。
```bash
./run.sh web # 官网/文档
+2 -3
View File
@@ -2,7 +2,6 @@
install:
npm install
npm --prefix apps/desktop install
web:
./run.sh web
@@ -26,7 +25,7 @@ desktop:
./run.sh desktop
build-web:
npm run build:web
npm run build:ui
# test = Go 后端用例 + UI 回归
test:
@@ -37,4 +36,4 @@ test-go:
cd server && go test ./...
test-ui:
npm run test:ui --if-present
npm test
+4 -4
View File
@@ -3,7 +3,7 @@
纯 JDK + gson 的通用 JDBC 桥:Go 服务端通过 stdin/stdout 的 JSON Lines 协议驱动一个
本机 JVM 进程,由它加载**官方 JDBC 驱动**(用户自备 jar,许可合规)连接数据库。
设计对标 DBX 的 agent 模式;v1 先接达梦,新增驱动在
`apps/server/internal/db/agent.go` 的 `agentDriverSpecs` 登记一行即可。
`server/internal/db/agent.go` 的 `agentDriverSpecs` 登记一行即可。
## 组成
@@ -11,9 +11,9 @@
agents/jdbc/OpsxJdbcAgent.java JDBC 通用桥(达梦等官方 JDBC 驱动)
agents/jdbc/OpsxZkAgent.java ZooKeeper 专属桥(官方客户端,NIO socket 免 netty 全家桶之外还需 6 个 netty jar 供 SSL 类初始化)
agents/jdbc/OpsxMongoAgent.java MongoDB 专属桥(官方 sync driver + 迷你 DSL)
apps/server/internal/db/agent.go Go 侧:进程池 / 协议客户端 / 元数据与执行入口(注册表 agentDriverSpecs)
apps/server/internal/db/es.go Elasticsearch 原生接入(HTTP + SQL API)
apps/server/internal/db/influx.go InfluxDB 2.x 原生接入(HTTP + Flux)
server/internal/db/agent.go Go 侧:进程池 / 协议客户端 / 元数据与执行入口(注册表 agentDriverSpecs)
server/internal/db/es.go Elasticsearch 原生接入(HTTP + SQL API)
server/internal/db/influx.go InfluxDB 2.x 原生接入(HTTP + Flux)
```
> Elasticsearch 曾评估走 agent + x-pack-sql-jdbc,实测 basic 许可报
-220
View File
@@ -1,220 +0,0 @@
{
"name": "@opsxdb/desktop",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@opsxdb/desktop",
"version": "0.1.0",
"devDependencies": {
"@tauri-apps/cli": "^2.4.0"
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.4.tgz",
"integrity": "sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==",
"dev": true,
"bin": {
"tauri": "tauri.js"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.11.4",
"@tauri-apps/cli-darwin-x64": "2.11.4",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.11.4",
"@tauri-apps/cli-linux-arm64-gnu": "2.11.4",
"@tauri-apps/cli-linux-arm64-musl": "2.11.4",
"@tauri-apps/cli-linux-riscv64-gnu": "2.11.4",
"@tauri-apps/cli-linux-x64-gnu": "2.11.4",
"@tauri-apps/cli-linux-x64-musl": "2.11.4",
"@tauri-apps/cli-win32-arm64-msvc": "2.11.4",
"@tauri-apps/cli-win32-ia32-msvc": "2.11.4",
"@tauri-apps/cli-win32-x64-msvc": "2.11.4"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.4.tgz",
"integrity": "sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.4.tgz",
"integrity": "sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.4.tgz",
"integrity": "sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.4.tgz",
"integrity": "sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.4.tgz",
"integrity": "sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.4.tgz",
"integrity": "sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.4.tgz",
"integrity": "sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.4.tgz",
"integrity": "sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.4.tgz",
"integrity": "sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.4.tgz",
"integrity": "sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.11.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.4.tgz",
"integrity": "sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
}
}
}
-11
View File
@@ -1,11 +0,0 @@
{
"name": "@opsxdb/desktop",
"version": "0.1.0",
"private": true,
"scripts": {
"tauri": "tauri"
},
"devDependencies": {
"@tauri-apps/cli": "^2.4.0"
}
}
-29
View File
@@ -1,29 +0,0 @@
[package]
name = "opsxdb-desktop"
version = "0.1.0"
description = "OpsxDB Tauri desktop shell"
authors = ["OpsxDB"]
edition = "2021"
default-run = "OpsxDB"
[lib]
name = "opsxdb_desktop_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[[bin]]
name = "OpsxDB"
path = "src/main.rs"
[build-dependencies]
tauri-build = { version = "2", features = [] }
[dependencies]
tauri = { version = "2", features = [] } # path via Manager
tauri-plugin-single-instance = "2" # 二次启动聚焦已有窗口
serde = { version = "1", features = ["derive"] }
serde_json = "1"
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json", "blocking"] }
tokio = { version = "1", features = ["time"] }
url = "2"
rand = "0.8"
tauri-plugin-window-state = "2"
-3
View File
@@ -1,3 +0,0 @@
fn main() {
tauri_build::build()
}
@@ -1,12 +0,0 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Default capabilities for the OpsxDB main window",
"windows": [
"main"
],
"permissions": [
"core:default",
"window-state:default"
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<background android:drawable="@color/ic_launcher_background"/>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#fff</color>
</resources>
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

-7
View File
@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#E11D2E"/>
<g transform="rotate(-20 256 256)">
<path d="M256 108 L290 216 L404 216 L312 286 L344 398 L256 332 L168 398 L200 286 L108 216 L222 216 Z"
fill="none" stroke="#FFFFFF" stroke-width="30" stroke-linejoin="round" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

@@ -1,10 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#0B182C"/>
<ellipse cx="256" cy="156" rx="128" ry="40" fill="#60A5FA"/>
<path d="M128 156v64c0 22 57 40 128 40s128-18 128-40v-64" fill="#3B82F6"/>
<ellipse cx="256" cy="220" rx="128" ry="40" fill="#93C5FD"/>
<path d="M128 220v64c0 22 57 40 128 40s128-18 128-40v-64" fill="#3B82F6"/>
<ellipse cx="256" cy="284" rx="128" ry="40" fill="#BFDBFE"/>
<path d="M128 284v88c0 22 57 40 128 40s128-18 128-40v-88" fill="#2563EB"/>
<ellipse cx="256" cy="372" rx="128" ry="40" fill="#3B82F6"/>
</svg>

Before

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#EF4444"/>
<g transform="rotate(8 256 256)">
<path d="M256 88 L298 214 L432 214 L324 292 L364 420 L256 344 L148 420 L188 292 L80 214 L214 214 Z"
fill="none" stroke="#FFFFFF" stroke-width="36" stroke-linejoin="round" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#EF4444"/>
<g transform="rotate(12 256 256)">
<path d="M256 96 L294 214 L420 214 L318 288 L354 408 L256 336 L158 408 L194 288 L92 214 L218 214 Z"
fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linejoin="round" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 408 B

-170
View File
@@ -1,170 +0,0 @@
mod sidecar;
use tauri::Manager;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{Duration, Instant};
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct BodySpec {
mode: String,
raw: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct HttpSpec {
method: String,
url: String,
#[serde(default)]
headers: HashMap<String, String>,
query: Option<HashMap<String, String>>,
body: Option<BodySpec>,
timeout_ms: Option<u64>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct HttpResult {
status: u16,
headers: HashMap<String, String>,
body: String,
time_ms: u128,
size: usize,
}
#[derive(Debug, Deserialize)]
struct WsSpec {
url: String,
protocols: Option<Vec<String>>,
headers: Option<HashMap<String, String>>,
}
fn validate_http_url(raw: &str) -> Result<url::Url, String> {
let parsed = url::Url::parse(raw).map_err(|e| format!("invalid URL: {e}"))?;
match parsed.scheme() {
"http" | "https" => {}
_ => return Err("only http/https schemes are allowed".into()),
}
match parsed.host_str().unwrap_or("").to_ascii_lowercase().as_str() {
"169.254.169.254" | "metadata.google.internal" => {
return Err("blocked metadata host".into())
}
_ => {}
}
Ok(parsed)
}
#[tauri::command]
async fn http_send(spec: HttpSpec) -> Result<HttpResult, String> {
let mut url = validate_http_url(&spec.url)?;
if let Some(query) = &spec.query {
let mut pairs = url.query_pairs_mut();
for (key, value) in query {
pairs.append_pair(key, value);
}
}
let method = reqwest::Method::from_bytes(spec.method.as_bytes())
.map_err(|e| format!("invalid method: {e}"))?;
let timeout = Duration::from_millis(spec.timeout_ms.unwrap_or(30_000));
let client = reqwest::Client::builder()
.timeout(timeout)
.build()
.map_err(|e| e.to_string())?;
let mut request = client.request(method, url);
for (key, value) in spec.headers {
request = request.header(&key, &value);
}
if let Some(body) = spec.body {
if body.mode != "none" {
request = request.body(body.raw.unwrap_or_default());
}
}
let started = Instant::now();
let response = request.send().await.map_err(|e| e.to_string())?;
let status = response.status().as_u16();
let headers = response
.headers()
.iter()
.map(|(k, v)| (k.to_string(), v.to_str().unwrap_or("").to_string()))
.collect();
let bytes = response.bytes().await.map_err(|e| e.to_string())?;
let size = bytes.len();
let body = String::from_utf8_lossy(&bytes).into_owned();
Ok(HttpResult {
status,
headers,
body,
time_ms: started.elapsed().as_millis(),
size,
})
}
#[tauri::command]
async fn ws_connect(spec: WsSpec) -> Result<String, String> {
let _ = (&spec.protocols, &spec.headers);
// TODO(week2): hold WebSocket sessions in managed state and emit messages.
Err(format!(
"WebSocket native tunnel is not implemented yet for {} (use browser WS in MVP)",
spec.url
))
}
#[tauri::command]
async fn ws_send(session_id: String, data: String) -> Result<(), String> {
let _ = (session_id, data);
Err("WebSocket native send is a Week 2 stub".into())
}
#[tauri::command]
async fn ws_close(session_id: String) -> Result<(), String> {
let _ = session_id;
Ok(())
}
/// 前端启动时拉取后端地址与 token(注入 window.__OPSXDB_API__/__OPSXDB_TOKEN__)。
#[tauri::command]
fn get_backend_config(
state: tauri::State<'_, sidecar::SidecarState>,
) -> Result<sidecar::BackendConfig, String> {
state
.backend_config()
.ok_or_else(|| "后端尚未就绪".to_string())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
// 二次启动聚焦已有窗口
if let Some(w) = app.get_webview_window("main") {
let _ = w.show();
let _ = w.unminimize();
let _ = w.set_focus();
}
}))
.plugin(tauri_plugin_window_state::Builder::default().build())
.manage(sidecar::SidecarState::default())
.setup(|app| {
let state = app.state::<sidecar::SidecarState>();
sidecar::ensure_backend(app.handle(), &state);
Ok(())
})
.invoke_handler(tauri::generate_handler![
http_send,
ws_connect,
ws_send,
ws_close,
get_backend_config
])
.build(tauri::generate_context!())
.expect("error while building OpsxDB desktop")
.run(|app, event| {
let state = app.state::<sidecar::SidecarState>();
sidecar::on_run_event(app, &event, &state);
});
}
-3
View File
@@ -1,3 +0,0 @@
fn main() {
opsxdb_desktop_lib::run();
}
-212
View File
@@ -1,212 +0,0 @@
//! 桌面启动时拉起本机 OpsxDB Gin 后端。
//! - 动态端口:TcpListener 绑 127.0.0.1:0 选空闲端口,OPSXDB_ADDR 传子进程;
//! - 每次自起生成随机 token,OPSXDB_TOKEN 传子进程,与 addr 一起经 get_backend_config 注入前端;
//! - 复用 8788 上已运行后端前先比对 /health 版本主版本,不匹配则换端口自起;
//! - 失败时 emit "opsxdb://backend-failed",后端 stdout/stderr 重定向到 app_log_dir/opsxdb-server.log。
use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
use tauri::{AppHandle, Emitter, Manager, RunEvent};
const DEFAULT_ADDR: &str = "127.0.0.1:8788";
/// 与服务端 cmd/opsxdb main.go Version 保持一致,复用前比对主版本。
const BACKEND_VERSION: &str = "0.1.0";
const EVENT_BACKEND_FAILED: &str = "opsxdb://backend-failed";
#[derive(Clone, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BackendConfig {
pub addr: String,
pub token: String,
}
pub struct SidecarState {
child: Mutex<Option<Child>>,
config: Mutex<Option<BackendConfig>>,
}
impl Default for SidecarState {
fn default() -> Self {
Self {
child: Mutex::new(None),
config: Mutex::new(None),
}
}
}
impl SidecarState {
fn set_config(&self, cfg: BackendConfig) {
if let Ok(mut g) = self.config.lock() {
*g = Some(cfg);
}
}
pub fn backend_config(&self) -> Option<BackendConfig> {
self.config.lock().ok().and_then(|g| g.clone())
}
}
fn version_major(v: &str) -> &str {
v.split('.').next().unwrap_or("")
}
/// GET /health 并解析版本;失败或非 200 返回 None。
fn health_version(addr: &str) -> Option<String> {
let resp = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(1))
.build()
.ok()?
.get(format!("http://{addr}/health"))
.send()
.ok()?;
if !resp.status().is_success() {
return None;
}
let v: serde_json::Value = resp.json().ok()?;
v.get("version")?.as_str().map(|s| s.to_string())
}
fn health_ok(addr: &str) -> bool {
health_version(addr).is_some()
}
/// 尝试复用 8788 上已在运行的后端:仅当主版本一致才复用,
/// 否则换端口自起而非静默连上旧版本。
fn try_reuse_existing(state: &SidecarState) -> bool {
match health_version(DEFAULT_ADDR) {
Some(v) if version_major(&v) == version_major(BACKEND_VERSION) => {
// 复用路径拿不到对方 token,按本机 dev 无鉴权处理
state.set_config(BackendConfig {
addr: format!("http://{DEFAULT_ADDR}"),
token: String::new(),
});
true
}
Some(v) => {
eprintln!(
"opsxdb: 已有后端版本 {v} 与期望 {BACKEND_VERSION} 主版本不匹配,改自动态端口自起"
);
false
}
None => false,
}
}
/// 绑 127.0.0.1:0 选一个空闲端口(立即释放,交给子进程绑定)。
fn pick_free_port() -> Option<u16> {
let ln = std::net::TcpListener::bind("127.0.0.1:0").ok()?;
ln.local_addr().ok().map(|a| a.port())
}
fn gen_token() -> String {
use rand::RngCore;
let mut b = [0u8; 32];
rand::thread_rng().fill_bytes(&mut b);
b.iter().map(|x| format!("{x:02x}")).collect()
}
fn candidate_bins(app: &AppHandle) -> Vec<PathBuf> {
// Windows 产物为 opsxdb-server.exe
let bin = format!("opsxdb-server{}", std::env::consts::EXE_EXTENSION);
let mut out = Vec::new();
// 打包资源:externalBin → 与可执行文件同级的 binaries 或 resource
if let Ok(dir) = app.path().resource_dir() {
out.push(dir.join(&bin));
out.push(dir.join("binaries").join(&bin));
}
if let Ok(exe) = app.path().executable_dir() {
out.push(exe.join(&bin));
out.push(exe.join("binaries").join(&bin));
}
// 开发态:仓库 apps/server/bin
out.push(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../server/bin").join(&bin));
out.push(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../../apps/server/bin").join(&bin));
out
}
/// 后端 stdout/stderr 重定向到 app_log_dir/opsxdb-server.log。
fn server_log_file(app: &AppHandle) -> Option<std::fs::File> {
let dir = app.path().app_log_dir().ok()?;
std::fs::create_dir_all(&dir).ok()?;
std::fs::File::create(dir.join("opsxdb-server.log")).ok()
}
fn spawn_server(
bin: &PathBuf,
addr: &str,
token: &str,
log_file: Option<&std::fs::File>,
) -> std::io::Result<Child> {
let mut cmd = Command::new(bin);
cmd.env("OPSXDB_ADDR", addr)
.env("OPSXDB_TOKEN", token)
.env("GIN_MODE", "release");
match log_file {
Some(f) => {
let err_f = f.try_clone()?;
cmd.stdout(Stdio::from(f.try_clone()?)).stderr(Stdio::from(err_f));
}
None => {
cmd.stdout(Stdio::null()).stderr(Stdio::null());
}
}
cmd.spawn()
}
pub fn ensure_backend(app: &AppHandle, state: &SidecarState) {
if try_reuse_existing(state) {
return;
}
let Some(port) = pick_free_port() else {
let _ = app.emit(EVENT_BACKEND_FAILED, "无法分配空闲端口");
return;
};
let addr = format!("127.0.0.1:{port}");
let token = gen_token();
let log_file = server_log_file(app);
let mut last_err = String::from("未找到后端二进制");
for bin in candidate_bins(app) {
if !bin.exists() {
continue;
}
match spawn_server(&bin, &addr, &token, log_file.as_ref()) {
Ok(child) => {
*state.child.lock().unwrap() = Some(child);
for _ in 0..30 {
if health_ok(&addr) {
state.set_config(BackendConfig {
addr: format!("http://{addr}"),
token: token.clone(),
});
return;
}
thread::sleep(Duration::from_millis(100));
}
last_err = format!("后端启动后健康检查超时({})", bin.display());
}
Err(e) => {
last_err = format!("启动 {} 失败: {e}", bin.display());
continue;
}
}
}
let _ = app.emit(EVENT_BACKEND_FAILED, last_err);
}
pub fn stop_backend(state: &SidecarState) {
if let Ok(mut g) = state.child.lock() {
if let Some(mut child) = g.take() {
let _ = child.kill();
let _ = child.wait();
}
}
}
pub fn on_run_event(app: &AppHandle, event: &RunEvent, state: &SidecarState) {
if matches!(event, RunEvent::Exit | RunEvent::ExitRequested { .. }) {
stop_backend(state);
let _ = app;
}
}
-43
View File
@@ -1,43 +0,0 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "OpsxDB",
"version": "0.1.0",
"identifier": "com.opsx.db",
"build": {
"beforeDevCommand": "bash -lc 'curl -fsS http://127.0.0.1:5174 >/dev/null 2>&1 || npm --prefix ../.. run dev:web'",
"devUrl": "http://127.0.0.1:5174",
"beforeBuildCommand": "bash -lc 'cd ../.. && npm run build:web'",
"frontendDist": "../../web/dist"
},
"app": {
"windows": [
{
"title": "OpsxDB",
"width": 1280,
"height": 800,
"minWidth": 960,
"minHeight": 640,
"resizable": true,
"fullscreen": false,
"label": "main"
}
],
"security": {
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:* ipc://localhost; object-src 'none'; base-uri 'self'"
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"externalBin": [
"binaries/opsxdb-server"
]
}
}
-14
View File
@@ -1,14 +0,0 @@
<!doctype html>
<html lang="zh-CN" class="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#0e1116" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>OpsxDB</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
-28
View File
@@ -1,28 +0,0 @@
{
"name": "@opsxdb/web",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --host 127.0.0.1 --port 5174",
"build": "tsc -b && vite build",
"preview": "vite preview --host 127.0.0.1 --port 5174"
},
"dependencies": {
"@opsxdb/ui": "*",
"@tauri-apps/api": "^2.5.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/node": "^22.20.3",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.4.1",
"autoprefixer": "^10.4.21",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "^5.8.2",
"vite": "^6.2.2"
}
}
-6
View File
@@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
-7
View File
@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#E11D2E"/>
<g transform="rotate(-20 256 256)">
<path d="M256 108 L290 216 L404 216 L312 286 L344 398 L256 332 L168 398 L200 286 L108 216 L222 216 Z"
fill="none" stroke="#FFFFFF" stroke-width="30" stroke-linejoin="round" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 411 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#ea4646" d="M295.526 392.14c19.456-16.486 40.704-33.177 62.67-47.615-16.692 55.04-19.866 173.568 106.905 193.536 95.232 15.001 119.296 45.21 108.083 195.942-19.558 9.216-39.014 16.896-58.88 24.064 12.544-62.464 26.47-174.592-64.307-192.819-110.541-22.272-167.936-36.864-154.47-173.107"/><path fill="#ea4646" d="M373.248 334.643a889 889 0 0 1 58.368-33.536c-21.504 100.864-14.336 188.416 103.782 206.848 69.99 10.957 124.263 36.25 110.234 186.368a714 714 0 0 1-54.374 31.027c10.393-59.904 10.65-180.838-72.192-193.587-124.57-19.2-162.253-53.248-145.818-197.12"/><path fill="#ea4646" d="M449.075 292.71c19.61-8.755 47.053-20.48 57.856-23.552-21.35 75.93-10.496 195.994 86.835 211.968 90.983 14.9 132.813 65.69 123.188 162.356-18.484 14.694-35.482 27.238-54.426 39.936 16.128-93.082-18.432-172.237-82.79-181.556-138.138-20.07-153.6-77.875-130.663-209.152"/><path fill="#1a2781" d="M267.008 418.918c-89.702 84.685-137.78 197.786-100.915 280.064 41.984 93.799 195.891 111.002 315.494 68.71 25.395-110.796 38.298-172.338-63.488-191.897-148.173-28.57-149.913-87.193-151.091-156.877m484.3 193.536c87.758-85.81 148.583-202.547 104.346-289.075-50.022-97.792-207.974-100.454-316.006-64.46-31.744 86.527-23.04 194.355 65.946 207.308 129.228 18.74 134.348 72.858 145.715 146.227"/><path fill="#de1a1b" d="M295.526 392.09c19.456-16.538 40.704-33.178 62.67-47.668-16.692 55.092-19.866 173.62 106.905 193.536 95.232 15.053 119.296 45.261 108.083 195.994-19.558 9.216-39.014 16.896-58.88 24.064 12.544-62.515 26.47-174.592-64.307-192.87-110.541-22.221-167.936-36.864-154.47-173.056"/><path fill="#de1a1b" d="M373.248 334.643c18.842-11.98 37.427-22.323 58.368-33.536-21.504 100.864-14.336 188.416 103.782 206.848 69.99 10.957 124.263 36.25 110.234 186.368-18.534 11.879-35.533 21.095-54.374 31.027 10.393-59.904 10.65-180.838-72.192-193.587-124.57-19.2-162.253-53.248-145.818-197.12"/><path fill="#de1a1b" d="M449.075 292.71c19.61-8.755 47.053-20.48 57.856-23.552-21.35 75.93-10.496 195.994 86.835 211.968 90.983 14.9 132.813 65.69 123.188 162.407-18.484 14.592-35.482 27.136-54.426 39.885 16.128-93.03-18.432-172.237-82.79-181.556-138.138-20.07-153.6-77.875-130.663-209.152"/></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" preserveAspectRatio="xMinYMin meet" viewBox="0 0 256 256"><path fill="#FFF" d="M255.96 134.393c0-21.521-13.373-40.117-33.223-47.43a75 75 0 0 0 1.253-13.791c0-39.909-32.386-72.295-72.295-72.295-23.193 0-44.923 11.074-58.505 30.088-6.686-5.224-14.835-7.94-23.402-7.94-21.104 0-38.446 17.133-38.446 38.446 0 4.597.836 9.194 2.298 13.373C13.582 81.739 0 100.962 0 122.274c0 21.522 13.373 40.327 33.431 47.64q-1.253 6.582-1.253 13.79c0 39.7 32.386 72.087 72.086 72.087 23.402 0 44.924-11.283 58.505-30.088 6.686 5.223 15.044 8.149 23.611 8.149 21.104 0 38.446-17.134 38.446-38.446 0-4.597-.836-9.194-2.298-13.373 19.64-7.104 33.431-26.327 33.431-47.64z"/><path fill="#F4BD19" d="m100.085 110.364 57.043 26.119 57.669-50.565a64.3 64.3 0 0 0 1.253-12.746c0-35.52-28.834-64.355-64.355-64.355-21.313 0-41.162 10.447-53.072 27.998l-9.612 49.73 11.074 23.82z"/><path fill="#3CBEB1" d="M40.953 170.75c-.835 4.179-1.253 8.567-1.253 12.955 0 35.52 29.043 64.564 64.564 64.564 21.522 0 41.372-10.656 53.49-28.208l9.403-49.729-12.746-24.238-57.251-26.118z"/><path fill="#E9478C" d="m40.536 71.918 39.073 9.194 8.775-44.506c-5.432-4.179-11.91-6.268-18.805-6.268-16.925 0-30.924 13.79-30.924 30.924 0 3.552.627 7.313 1.88 10.656z"/><path fill="#2C458F" d="M37.192 81.32c-17.551 5.642-29.67 22.567-29.67 40.954 0 17.97 11.074 34.059 27.79 40.327l54.953-49.73-10.03-21.52-43.043-10.03z"/><path fill="#95C63D" d="M167.784 219.852c5.432 4.18 11.91 6.478 18.596 6.478 16.925 0 30.924-13.79 30.924-30.924q0-5.642-1.88-10.657l-39.073-9.193z"/><path fill="#176655" d="m175.724 165.317 43.043 10.03c17.551-5.85 29.67-22.566 29.67-40.954 0-17.97-11.074-33.849-27.79-40.326l-56.415 49.311 11.492 21.94z"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="209.961" height="200" class="icon" viewBox="0 0 1075 1024"><path fill="#9f53e6" d="M170.24 333.005a20.5 20.5 0 0 0-3.84 8.601h-.205v84.122a19.87 19.87 0 0 0 11.367 16.691l269.363 158.26a136.45 136.45 0 0 0 125.542 0l269.517-157.697a19.87 19.87 0 0 0 11.366-16.742l1.024-83.968-217.241-116.838-160.461 92.979a19.35 19.35 0 0 0-11.315 16.691v83.814c2.048 5.888 6.093 10.957 11.315 14.336 2.56-35.84 42.496-58.265 42.496-58.265l116.94-66.765 152.577 82.893-216.218 128.307a137.47 137.47 0 0 1-125.491 0l-226.509-133.58 226.407-133.53a126.5 126.5 0 0 1 62.873-15.207V153.6a126.8 126.8 0 0 0-62.873 15.155l-269.21 158.31a20.5 20.5 0 0 0-7.373 5.94zm679.22 236.851a19.9 19.9 0 0 0 3.378-9.882l-.307-83.302a19.87 19.87 0 0 1-11.366 16.691L572.109 651.571a136.5 136.5 0 0 1-125.491 0L177.05 492.75a19.87 19.87 0 0 1-11.367-16.691v83.456a19.87 19.87 0 0 0 11.367 16.69l269.568 158.414a137.42 137.42 0 0 0 125.49 0l269.364-157.901a19.97 19.97 0 0 0 7.987-6.81zm3.378 119.654a19.92 19.92 0 0 1-11.366 16.692L572.109 863.949a136.5 136.5 0 0 1-125.491 0L177.05 705.74a19.87 19.87 0 0 1-11.367-16.743v-83.456a19.71 19.71 0 0 0 11.367 16.692l269.568 158.412a137.47 137.47 0 0 0 125.49 0l269.057-157.9a19.56 19.56 0 0 0 11.366-16.692z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 512 512"><path d="M507.2 308.1 458.3 96c-2.7-11.4-13.2-23.3-25.1-26.5L210.5.9c-2.8-.9-6-.9-9.6-.9-9.6 0-19.2 3.6-26.1 9.6L15.3 158.2C6.6 166 2 181.5 4.8 192.4l52.1 227.2c2.7 11.4 13.2 23.3 25.1 26.5L290.5 511c2.7.9 5.9.9 9.6.9 9.6 0 19.2-3.6 26-9.6l170.5-158.6c8.8-9.1 13.4-23.7 10.6-35.6M233.8 51.2 387 98.3c6 1.8 6 4.6 0 6l-80.4 18.3c-6 1.8-14.6-.9-18.8-5.5L232 56.7c-5-5.1-4.1-7.3 1.8-5.5m95.6 274.3c1.8 6-2.3 9.6-8.2 7.8l-165-51.2c-6-1.8-7.3-6.8-2.8-11l126.2-117.5c4.6-4.6 9.6-2.8 11 3.2zM57.4 176 191.3 51.2c4.6-4.6 11.4-3.6 16 .4l67.2 72.7c4.6 4.6 3.6 11.4-.5 16L140.1 265.2c-4.6 4.6-11.4 3.6-16-.5L56.9 192c-4.5-5-4.1-12.4.5-16m32.5 197.5L54.7 218c-1.8-5.9.9-7.3 5-2.7l55.8 60.3c4.6 4.6 5.9 13.3 4.6 19.2l-24.2 78.6c-1.9 6.5-4.7 6.5-6 .1M286 464.9l-175.1-54.4c-6.1-2-9.6-8.5-7.8-14.6l29.3-94.2c2-6.1 8.4-9.6 14.6-7.8l175.1 53.9c6 1.8 9.6 8.2 7.8 14.6l-29.3 94.2c-2.1 6.1-8.4 9.6-14.6 8.3m155.4-127.5-117 108.8c-4.6 4.6-6.9 2.8-5-3.2l24.2-78.6c1.8-6 8.2-12.4 14.6-13.3l80.5-18.3c5.9-2.3 6.8.4 2.7 4.6m12.8-23.8-96.4 22c-6 1.8-12.4-2.3-13.7-8.2L302.9 149c-1.8-6 2.3-12.4 8.2-13.7l96.5-22c5.9-1.8 12.3 2.3 13.7 8.2l41.2 178.3c1.3 7-2.4 12.9-8.3 13.8" style="fill:#4aabf4"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#c9151e" d="M339.2 204.8v236.083l-148.531 73.421 148.48 69.99v239.104h130.457V650.342L833.28 823.398V687.872L469.606 514.304 833.28 338.381V209.05L469.606 377.702V204.8z"/></svg>

Before

Width:  |  Height:  |  Size: 292 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 85.79 512.01 340.29"><style>.st0{fill-rule:evenodd;clip-rule:evenodd}.st0,.st3{fill:#002b64}</style><path d="M500.7 86.5c-7.9.3-5.4 2.5-22.5 6.7-17.3 4.2-38.4 2.9-57 10.7-55.5 23.3-66.6 102.8-117.1 131.3-37.6 21.3-75.8 23-109.9 33.6-22.5 7.1-47 21.5-67.5 39-15.8 13.6-16.2 25.6-32.8 42.7C76.3 368.9 23.6 351 0 379c7.7 7.7 11.1 9.9 26.2 7.9-3.1 5.9-21.6 10.9-18 19.7 3.8 9.2 48.4 15.4 88.9-9.1 18.9-11.4 33.9-27.9 63.2-31.9 38.2-5.1 82 3.2 125.9 9.6-6.6 19.5-19.7 32.5-30.2 47.8-3.2 3.5 6.6 3.9 17.7 1.8 20.1-5 34.5-9 49.8-17.8 18.6-10.9 21.4-38.7 44.4-44.7 12.7 19.6 47.3 24.2 68.9 8.5-18.9-5.4-24.1-45.6-17.7-63.2 6-16.7 12-43.6 18.1-65.8 6.5-23.8 8.9-53.8 16.8-65.8 11.9-18.2 25-24.5 36.5-34.7C501.9 131 512.3 121 512 97.4c-.1-7.6-4-11.8-11.2-11.6z" class="st0"/><path d="M16.5 405.5c28.8 4.1 46.4 0 69.8-10.1 19.7-8.6 38.7-26.2 62.1-33.6 34.2-11 71.8 0 108.5 2.2 8.9.5 17.8.5 26.5-.4 13.6-8.4 13.4-39.6 26.6-42.7-.4 43.9-18.4 70.3-37.3 95.7 39.9-7 63.5-29.9 79.5-60.7 4.9-9.3 9-19.3 12.7-29.9 5.7 4.4 2.5 17.7 5.3 24.8 27.4-15.2 43-50.1 53.5-85.2 12-40.7 16.9-82 24.7-94 7.5-11.8 19.3-19 30.2-26.5 12.2-8.6 23.1-17.5 24.9-33.9-12.9-1.2-15.8-4.2-17.7-10.7-6.4 3.6-12.4 4.4-19.1 4.6-5.8.2-12.2-.1-20 .7-64.4 6.6-72.6 77.8-113.9 117.9-3 2.9-6.3 5.7-9.7 8.2-14.5 10.8-32.2 18.5-48.4 24.7-26.4 10.1-51.5 10.8-76.3 19.5-18.2 6.4-36.7 15.7-51.5 25.9-3.7 2.6-7.3 5.2-10.5 7.8-8.8 7.2-14.5 15.1-20.1 23.3-5.8 8.4-11.3 17.1-19.7 25.4-13.7 13.4-64.9 3.9-82.9 16.4-2 1.4-3.6 3-4.7 5 9.8 4.5 16.4 1.7 27.7 3 1.5 10.7-23.3 17.1-19.7 22z" style="fill:#c49a6c"/><path d="M406.7 325.8c.8 12.3 7.9 36.7 14.2 42.7-12.4 3-33.6-2-39-10.7 2.8-12.6 17.4-24.1 24.9-31.9z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#c49a6c"/><path d="M423.8 132.1c9.1 7.9 28.3 1.6 24.8-14.2-14.1-1.2-22.3 3.7-24.8 14.2" class="st0"/><path d="M486.5 112.2c-2.4 5.1-7.1 11.6-7.1 24.6 0 2.2-1.7 3.8-1.7.3.1-12.7 3.5-18.1 7-25.3 1.7-3 2.7-1.8 1.8.4" class="st3"/><path d="M486.5 112.2c-2.8 4.8-9.7 13.7-10.9 26.6-.2 2.2-2 3.6-1.7.2 1.2-12.6 6.7-20.5 10.9-27.3 1.9-2.9 2.8-1.6 1.7.5m-2.9-2.9c-3.2 4.6-13.9 15.2-16.1 28-.4 2.2-2.3 3.4-1.7 0 2.3-12.4 11.4-22.2 16.2-28.8 2.1-2.6 2.9-1.2 1.6.8m-2.8-2.8c-3.9 4.1-16.5 17.7-20.5 29.9-.7 2.1-2.8 3-1.7-.2 4-12 15.1-24.9 20.7-30.8 2.5-2.3 3-.8 1.5.9z" class="st3"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="141.14 0 229.74 512.1"><path d="M366.8 203.8c-27-119-83.2-150.7-97.5-173.1-5.9-9.9-11.2-20.1-15.7-30.7-.8 10.6-2.1 17.2-11.1 25.2-18 16.1-94.7 78.5-101.1 213.7-6 126.1 92.7 203.8 105.7 211.8 10 4.9 22.2.1 28.2-4.4 47.5-32.6 112.5-119.6 91.5-242.5" style="fill:#10aa50"/><path d="M257.7 383.7c-2.5 31.2-4.3 49.3-10.6 67.2 0 0 4.1 29.7 7 61.2h10.3c2.5-22.2 6.2-44.2 11.2-65.9-13.2-6.6-17.4-35.2-17.9-62.5" style="fill:#b8c4c2"/><path d="M275.7 446.1c-13.5-6.2-17.4-35.3-18-62.5 3.3-44.8 4.3-89.7 2.9-134.5-.7-23.5.3-218-5.8-246.5 4.2 9.6 9 19 14.5 28 14.3 22.4 70.6 54.1 97.5 173.1 21 122.8-43.6 209.6-91.1 242.4" style="fill:#12924f"/></svg>

Before

Width:  |  Height:  |  Size: 710 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="800" width="1200" viewBox="-58.46985 -50.32625 506.7387 301.9575"><path d="M0 183.354h12.842v-50.711l19.88 44.208c2.346 5.35 5.557 7.244 11.854 7.244 6.298 0 9.385-1.893 11.732-7.244l19.88-44.208v50.71H89.03v-50.627c0-4.94-1.976-7.327-6.05-8.561-9.755-3.046-16.3-.412-19.264 6.174l-19.51 43.63-18.892-43.63c-2.84-6.586-9.508-9.22-19.263-6.174C1.976 125.399 0 127.787 0 132.725v50.629zm99.708-41.276h12.838v27.938c-.12 1.518.487 5.08 7.522 5.19 3.589.057 27.7 0 27.925 0v-33.264h12.868c.059 0-.013 45.364-.012 45.557.07 11.188-13.882 13.618-20.313 13.806h-40.55v-8.64c.072 0 40.52.009 40.622-.001 8.265-.873 7.289-4.981 7.288-6.364v-3.368H120.6c-12.7-.117-20.786-5.66-20.886-12.035-.01-.591.274-28.54-.007-28.82z" fill="#00618a"/><path d="M170.758 183.354h36.92c4.322 0 8.52-.905 11.855-2.47 5.556-2.551 8.273-6.008 8.273-10.537v-9.384c0-3.705-3.087-7.163-9.138-9.467-3.211-1.236-7.162-1.894-10.99-1.894h-15.56c-5.184 0-7.654-1.564-8.271-5.021-.124-.412-.124-.742-.124-1.153v-5.844c0-.33 0-.66.124-1.071.617-2.634 1.976-3.376 6.544-3.787.37 0 .864-.083 1.235-.083H228.3v-8.56h-36.057c-5.186 0-7.903.329-10.372 1.069-7.656 2.388-10.99 6.175-10.99 12.76v7.492c0 5.763 6.545 10.702 17.534 11.854 1.236.082 2.47.164 3.704.164h13.336c.495 0 .989 0 1.359.083 4.075.33 5.803 1.07 7.039 2.552.74.74.987 1.482.987 2.305v7.49c0 .907-.617 2.06-1.851 3.047-1.112.988-2.964 1.647-5.434 1.812-.494 0-.864.082-1.358.082h-35.44v8.56zm137.16-14.9c0 8.808 6.544 13.748 19.757 14.736 1.234.082 2.47.164 3.704.164h33.464v-8.561h-33.711c-7.532 0-10.372-1.894-10.372-6.421v-44.29h-12.842v44.372zm-71.916.449V138.38c0-7.754 5.445-12.457 16.209-13.942a24.63 24.63 0 013.465-.247h24.376c1.237 0 2.352.083 3.589.247 10.765 1.485 16.209 6.188 16.209 13.942v30.522c0 6.29-2.312 9.658-7.641 11.852l12.65 11.418h-14.911l-10.234-9.238-10.303.653h-13.735c-2.351 0-4.825-.331-7.548-1.073-8.166-2.227-12.126-6.517-12.126-13.612zm13.86-.742c0 .413.124.825.248 1.32.742 3.547 4.083 5.527 9.156 5.527h11.667l-10.717-9.675h14.91l9.348 8.438c1.722-.918 2.856-2.322 3.252-4.125.123-.412.123-.825.123-1.237v-29.285c0-.33 0-.743-.123-1.156-.743-3.3-4.084-5.196-9.033-5.196h-19.427c-5.691 0-9.403 2.475-9.403 6.352v29.037z" fill="#e48e00"/><path d="M376.14 109.88c-7.893-.214-13.923.52-19.078 2.694-1.465.618-3.801.634-4.04 2.47.805.844.93 2.104 1.57 3.142 1.23 1.992 3.309 4.661 5.163 6.061 2.026 1.53 4.114 3.165 6.286 4.49 3.863 2.355 8.176 3.7 11.896 6.06 2.192 1.391 4.37 3.143 6.509 4.713 1.057.776 1.768 1.983 3.142 2.47v-.225c-.722-.919-.908-2.183-1.571-3.143l-2.918-2.918c-2.853-3.787-6.475-7.113-10.325-9.876-3.07-2.204-9.942-5.18-11.223-8.754l-.225-.225c2.177-.245 4.726-1.033 6.735-1.57 3.375-.906 6.39-.672 9.876-1.572 1.57-.449 3.142-.899 4.714-1.347v-.898c-1.762-1.808-3.018-4.2-4.94-5.836-5.025-4.28-10.511-8.556-16.16-12.121-3.133-1.978-7.005-3.263-10.325-4.939-1.117-.563-3.08-.856-3.817-1.796-1.744-2.223-2.694-5.042-4.04-7.632-2.817-5.425-5.584-11.351-8.08-17.06-1.703-3.892-2.815-7.73-4.938-11.223-10.192-16.757-21.163-26.87-38.158-36.812-3.616-2.114-7.97-2.95-12.571-4.04l-7.407-.45c-1.507-.63-3.075-2.473-4.49-3.367-5.63-3.556-20.07-11.293-24.24-1.122-2.633 6.42 3.935 12.685 6.284 15.938 1.649 2.282 3.76 4.84 4.938 7.407.775 1.687.909 3.378 1.572 5.163 1.632 4.397 3.05 9.18 5.162 13.243 1.067 2.056 2.243 4.222 3.592 6.06.827 1.129 2.244 1.626 2.468 3.368-1.386 1.94-1.465 4.95-2.244 7.407-3.508 11.062-2.185 24.81 2.918 32.997 1.566 2.513 5.254 7.903 10.325 5.836 4.436-1.807 3.445-7.406 4.714-12.345.287-1.12.11-1.944.673-2.694v.225l4.04 8.08c2.99 4.815 8.298 9.848 12.795 13.244 2.332 1.761 4.168 4.806 7.183 5.836v-.225h-.225c-.584-.91-1.498-1.288-2.244-2.02-1.757-1.722-3.71-3.863-5.163-5.836-4.09-5.553-7.705-11.63-10.998-17.957-1.573-3.02-2.94-6.354-4.266-9.428-.511-1.185-.505-2.977-1.57-3.592-1.452 2.253-3.591 4.075-4.714 6.735-1.796 4.252-2.028 9.437-2.693 14.814-.394.141-.22.044-.45.224-3.126-.754-4.225-3.972-5.386-6.733-2.94-6.982-3.485-18.225-.9-26.262.67-2.08 3.694-8.63 2.47-10.55-.584-1.917-2.512-3.026-3.591-4.49-1.335-1.811-2.668-4.195-3.592-6.286-2.405-5.444-3.528-11.555-6.06-17.058-1.21-2.631-3.257-5.293-4.938-7.632-1.861-2.59-3.945-4.5-5.387-7.633-.513-1.113-1.21-2.895-.45-4.04.243-.772.584-1.095 1.348-1.347 1.302-1.003 4.928.334 6.284.898 3.6 1.495 6.604 2.919 9.653 4.938 1.464.971 2.944 2.848 4.713 3.368h2.02c3.16.726 6.7.225 9.652 1.122 5.218 1.586 9.894 4.052 14.14 6.734 12.939 8.169 23.517 19.798 30.753 33.67 1.164 2.233 1.668 4.365 2.693 6.734 2.069 4.778 4.675 9.694 6.733 14.366 2.054 4.66 4.056 9.365 6.959 13.244 1.527 2.039 7.422 3.133 10.1 4.264 1.879.794 4.956 1.621 6.735 2.693 3.398 2.05 6.69 4.49 9.877 6.735 1.593 1.122 6.489 3.583 6.733 5.611z" fill="#00618a"/><path d="M275.807 24.359c-1.646-.03-2.81.18-4.041.448v.225h.225c.785 1.613 2.17 2.651 3.142 4.04a6815.3 6815.3 0 002.245 4.714l.224-.224c1.39-.98 2.027-2.547 2.02-4.938-.557-.586-.64-1.322-1.122-2.021-.642-.932-1.884-1.46-2.693-2.244z" fill="#00618a" fill-ruLine truncated

Before

Width:  |  Height:  |  Size: 5.4 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#0181fd" d="M906.598 322.509v265.113a791.9 791.9 0 0 0-333.516 39.783 1051.55 1051.55 0 0 1-418.919 54.886V416.768c96.205 9.216 195.687.82 293.53-27.034 13.21-3.788 26.726-8.09 39.936-12.39a1055 1055 0 0 1 419.225-54.886h-.256z"/><path fill="#ffa005" d="M496.589 256a591 591 0 0 1-44.851 17.05c-7.066 2.406-14.08 4.608-21.35 7.014-5.684 1.638-11.367 3.533-17.306 5.12-86.784 24.064-174.592 30.566-259.482 21.094v88.628a770.3 770.3 0 0 0 303.77-31.079l22.732-7.27a762 762 0 0 0 43.52-16.487L496.332 256z"/><path fill="#07c846" d="M563.866 748.39a616 616 0 0 1 44.902-17.05c7.014-2.406 14.029-4.607 21.35-7.014 5.632-1.587 11.316-3.481 17.255-5.12a685.6 685.6 0 0 1 259.481-21.094v-88.627a770.3 770.3 0 0 0-286.72 25.958c-5.734 1.587-11.417 3.226-17.05 5.12l-22.732 7.27a762 762 0 0 0-43.52 16.487l27.34 84.07z"/></svg>

Before

Width:  |  Height:  |  Size: 931 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#1f80c4" d="M158.208 333.005a20.5 20.5 0 0 0-3.942 8.601h-.154v84.122a19.87 19.87 0 0 0 11.366 16.691l269.364 158.26a136.45 136.45 0 0 0 125.49 0l269.569-157.697a19.92 19.92 0 0 0 11.366-16.742l1.024-83.968-217.293-116.838-160.41 92.979a19.35 19.35 0 0 0-11.366 16.691v83.814c2.1 5.888 6.144 10.957 11.367 14.336 2.56-35.84 42.496-58.265 42.496-58.265l116.94-66.765 152.577 82.893-216.27 128.307a137.47 137.47 0 0 1-125.44 0l-226.508-133.58 226.406-133.53a126.4 126.4 0 0 1 62.823-15.207V153.6a126.8 126.8 0 0 0-62.823 15.155l-269.312 158.31a20.5 20.5 0 0 0-7.321 5.94zm679.117 236.851a19.87 19.87 0 0 0 3.43-9.882l-.358-83.302a19.87 19.87 0 0 1-11.367 16.691L560.026 651.571a136.45 136.45 0 0 1-125.543 0L164.966 492.75a19.87 19.87 0 0 1-11.366-16.743v83.456a19.87 19.87 0 0 0 11.366 16.692l269.517 158.412a137.42 137.42 0 0 0 125.543 0l269.312-157.9a19.87 19.87 0 0 0 7.987-6.81m3.43 119.654a19.87 19.87 0 0 1-11.366 16.692L560.026 863.949a136.45 136.45 0 0 1-125.543 0L164.966 705.74a19.87 19.87 0 0 1-11.366-16.794v-83.456a19.71 19.71 0 0 0 11.366 16.691l269.517 158.413a137.47 137.47 0 0 0 125.543 0l269.004-157.9a19.56 19.56 0 0 0 11.367-16.692l.358 83.456z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1 +0,0 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Oracle</title><path fill="#C74634" d="M16.412 4.412h-8.82a7.588 7.588 0 0 0-.008 15.176h8.828a7.588 7.588 0 0 0 0-15.176zm-.193 12.502H7.786a4.915 4.915 0 0 1 0-9.828h8.433a4.914 4.914 0 1 1 0 9.828z"/></svg>

Before

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 0 512 512"><style>.st2{fill:none;stroke:#fff;stroke-width:12.4651;stroke-linecap:round;stroke-linejoin:round}</style><g id="Layer_x0020_3"><path d="M378.5 372.5c3.2-26.9 2.3-30.8 22.3-26.5l5.1.4c15.4.7 35.5-2.5 47.4-8 25.5-11.8 40.6-31.5 15.5-26.4-57.3 11.8-61.2-7.6-61.2-7.6 60.5-89.7 85.8-203.6 63.9-231.5C411.9-3 308.8 33 307.1 33.9l-.5.1c-11.3-2.3-24-3.8-38.2-4-25.9-.4-45.6 6.8-60.5 18.1 0 0-183.8-75.7-175.2 95.2 1.8 36.4 52.1 275.2 112.1 203 21.9-26.4 43.1-48.7 43.1-48.7 10.5 7 23.1 10.6 36.3 9.3l1-.9c-.3 3.3-.2 6.5.4 10.3-15.5 17.3-10.9 20.3-41.8 26.7-31.3 6.4-12.9 17.9-.9 20.9 14.5 3.6 48.2 8.8 70.9-23l-.9 3.6c6.1 4.9 5.7 34.9 6.5 56.3.9 21.4 2.3 41.5 6.7 53.3s9.5 42.2 50.1 33.5c34-7.3 59.9-17.7 62.3-115.1" style="stroke:#000;stroke-width:37.3953"/><path d="M468.7 312.1c-57.3 11.8-61.2-7.6-61.2-7.6C468 214.8 493.3 100.9 471.4 73 411.9-3 308.8 33 307.1 33.9l-.6.1c-11.3-2.3-24-3.7-38.2-4-25.9-.4-45.6 6.8-60.5 18.1 0 0-183.8-75.7-175.2 95.2 1.8 36.4 52.1 275.2 112.1 203 21.9-26.4 43.1-48.7 43.1-48.7 10.5 7 23.1 10.6 36.3 9.3l1-.9c-.3 3.3-.2 6.5.4 10.3-15.5 17.3-10.9 20.3-41.8 26.7-31.3 6.4-12.9 17.9-.9 20.9 14.5 3.6 48.2 8.8 70.9-23l-.9 3.6c6.1 4.9 10.3 31.6 9.6 55.8s-1.2 40.8 3.6 53.8 9.5 42.2 50.1 33.5c33.9-7.3 51.5-26.1 54-57.6 1.7-22.4 5.7-19 5.9-39l3.2-9.5c3.6-30.3.6-40.1 21.5-35.5l5.1.4c15.4.7 35.5-2.5 47.4-8 25.5-11.7 40.5-31.4 15.5-26.3" style="fill:#336791"/><path d="M256.3 329.5c-1.6 56.4.4 113.2 5.9 126.9 5.5 13.8 17.3 40.6 58 31.9 33.9-7.3 46.3-21.4 51.6-52.4 3.9-22.9 11.6-86.4 12.5-99.4M207.6 46.9S23.7-28.3 32.2 142.7c1.8 36.4 52.1 275.2 112.1 203 21.9-26.4 41.8-47.1 41.8-47.1M306.9 33.2c-6.4 2 102.3-39.7 164.1 39.2 21.8 27.9-3.5 141.8-63.9 231.5" class="st2"/><path d="M407 303.9s3.9 19.4 61.2 7.6c25.1-5.2 10 14.5-15.5 26.4-20.9 9.7-67.7 12.2-68.5-1.2-1.9-34.7 24.8-24.2 22.8-32.8-1.7-7.8-13.6-15.5-21.5-34.5-6.9-16.7-94.3-144.4 24.2-125.5 4.3-.9-30.9-112.7-141.8-114.5S160.7 165.8 160.7 165.8" style="fill:none;stroke:#fff;stroke-width:12.4651;stroke-linecap:round;stroke-linejoin:bevel"/><path d="M225.2 315.7c-15.5 17.3-10.9 20.3-41.8 26.7-31.3 6.4-12.9 17.9-.9 20.9 14.5 3.6 48.2 8.8 70.9-23 6.9-9.7 0-25.1-9.5-29.1-4.6-2-10.8-4.4-18.7 4.5" class="st2"/><path d="M224.2 315.4c-1.6-10.2 3.3-22.2 8.6-36.4 7.9-21.2 26.1-42.4 11.5-109.7-10.8-50.1-83.6-10.4-83.6-3.6s3.3 34.5-1.2 66.7c-5.9 42 26.7 77.6 64.3 73.9" class="st2"/><path d="M206.9 164.7c-.3 2.3 4.3 8.5 10.2 9.3 6 .8 11.1-4 11.4-6.3s-4.2-4.9-10.2-5.7c-6-.9-11.1.3-11.4 2.7z" style="fill:#fff;stroke:#fff;stroke-width:4.155"/><path d="M388.4 159.9c.3 2.3-4.2 8.5-10.2 9.3s-11.1-4-11.4-6.3 4.3-4.9 10.2-5.7 11.1.4 11.4 2.7z" style="fill:#fff;stroke:#fff;stroke-width:2.0775"/><path d="M409.8 143.9c1 18.2-3.9 30.6-4.5 50-.9 28.2 13.4 60.4-8.2 92.7" class="st2"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0.58 256 218.59"><path fill="#912626" d="M245.97 168.943c-13.662 7.121-84.434 36.22-99.501 44.075s-23.437 7.78-35.34 2.09c-11.902-5.69-87.216-36.112-100.783-42.597C3.566 169.271 0 166.535 0 163.951v-25.876s98.05-21.345 113.879-27.024c15.828-5.679 21.32-5.884 34.79-.95 13.472 4.936 94.018 19.468 107.331 24.344l-.006 25.51c.002 2.558-3.07 5.364-10.024 8.988"/><path fill="#C6302B" d="M245.965 143.22c-13.661 7.118-84.431 36.218-99.498 44.072-15.066 7.857-23.436 7.78-35.338 2.09-11.903-5.686-87.214-36.113-100.78-42.594-13.566-6.485-13.85-10.948-.524-16.166 13.326-5.22 88.224-34.605 104.055-40.284 15.828-5.677 21.319-5.884 34.789-.948 13.471 4.934 83.819 32.935 97.13 37.81 13.316 4.881 13.827 8.9.166 16.02"/><path fill="#912626" d="M245.97 127.074c-13.662 7.122-84.434 36.22-99.501 44.078-15.067 7.853-23.437 7.777-35.34 2.087-11.903-5.687-87.216-36.112-100.783-42.597C3.566 127.402 0 124.67 0 122.085V96.206s98.05-21.344 113.879-27.023c15.828-5.679 21.32-5.885 34.79-.95C162.142 73.168 242.688 87.697 256 92.574l-.006 25.513c.002 2.557-3.07 5.363-10.024 8.987"/><path fill="#C6302B" d="M245.965 101.351c-13.661 7.12-84.431 36.218-99.498 44.075-15.066 7.854-23.436 7.777-35.338 2.087-11.903-5.686-87.214-36.112-100.78-42.594-13.566-6.483-13.85-10.947-.524-16.167C23.151 83.535 98.05 54.148 113.88 48.47c15.828-5.678 21.319-5.884 34.789-.949 13.471 4.934 83.819 32.933 97.13 37.81 13.316 4.88 13.827 8.9.166 16.02"/><path fill="#912626" d="M245.97 83.653c-13.662 7.12-84.434 36.22-99.501 44.078-15.067 7.854-23.437 7.777-35.34 2.087-11.903-5.687-87.216-36.113-100.783-42.595C3.566 83.98 0 81.247 0 78.665v-25.88s98.05-21.343 113.879-27.021c15.828-5.68 21.32-5.884 34.79-.95C162.142 29.749 242.688 44.278 256 49.155l-.006 25.512c.002 2.555-3.07 5.361-10.024 8.986"/><path fill="#C6302B" d="M245.965 57.93c-13.661 7.12-84.431 36.22-99.498 44.074-15.066 7.854-23.436 7.777-35.338 2.09C99.227 98.404 23.915 67.98 10.35 61.497-3.217 55.015-3.5 50.55 9.825 45.331 23.151 40.113 98.05 10.73 113.88 5.05c15.828-5.679 21.319-5.883 34.789-.948s83.819 32.934 97.13 37.811c13.316 4.876 13.827 8.897.166 16.017"/><path fill="#FFF" d="m159.283 32.757-22.01 2.285-4.927 11.856-7.958-13.23-25.415-2.284 18.964-6.839-5.69-10.498 17.755 6.944 16.738-5.48-4.524 10.855zm-28.251 57.518L89.955 73.238l58.86-9.035zm-56.95-50.928c17.375 0 31.46 5.46 31.46 12.194 0 6.736-14.085 12.195-31.46 12.195s-31.46-5.46-31.46-12.195c0-6.734 14.085-12.194 31.46-12.194"/><path fill="#621B1C" d="m185.295 35.998 34.836 13.766-34.806 13.753z"/><path fill="#9A2928" d="m146.755 51.243 38.54-15.245.03 27.519-3.779 1.478z"/></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img">
<title>SQLite</title>
<rect x="4" y="4" width="120" height="120" rx="22" fill="#E8F6FC"/>
<g transform="translate(8 8) scale(0.875)">
<defs><linearGradient id="sqlite-dark-a" x1="-15.615" x2="-6.741" y1="-9.108" y2="-9.108" gradientTransform="rotate(90 -90.486 64.634) scale(9.2712)" gradientUnits="userSpaceOnUse"><stop stop-color="#B8ECFF" offset="0"/><stop stop-color="#5EC4F0" offset=".92"/><stop stop-color="#5EC4F0" offset="1"/></linearGradient></defs><path d="M69.5 99.176c-.059-.73-.094-1.2-.094-1.2S67.2 83.087 64.57 78.642c-.414-.707.043-3.594 1.207-7.88.68 1.169 3.54 6.192 4.118 7.81.648 1.824.78 2.347.78 2.347s-1.57-8.082-4.144-12.797a162.286 162.286 0 012.004-6.265c.973 1.71 3.313 5.859 3.828 7.3.102.293.192.543.27.774.023-.137.05-.274.074-.414-.59-2.504-1.75-6.86-3.336-10.082 3.52-18.328 15.531-42.824 27.84-53.754H16.9c-5.387 0-9.789 4.406-9.789 9.789v88.57c0 5.383 4.406 9.789 9.79 9.789h52.897a118.657 118.657 0 01-.297-14.652" fill="#5EC4F0"/><path d="M65.777 70.762c.68 1.168 3.54 6.188 4.117 7.809.649 1.824.781 2.347.781 2.347s-1.57-8.082-4.144-12.797a164.535 164.535 0 012.004-6.27c.887 1.567 2.922 5.169 3.652 6.872l.082-.961c-.648-2.496-1.633-5.766-2.898-8.328 3.242-16.871 13.68-38.97 24.926-50.898H16.899a6.94 6.94 0 00-6.934 6.933v82.11c17.527-6.731 38.664-12.88 56.855-12.614-.672-2.605-1.441-4.96-2.25-6.324-.414-.707.043-3.597 1.207-7.879" fill="url(#sqlite-dark-a)"/><path d="M115.95 2.781c-5.5-4.906-12.164-2.933-18.734 2.899a44.347 44.347 0 00-2.914 2.859c-11.25 11.926-21.684 34.023-24.926 50.895 1.262 2.563 2.25 5.832 2.894 8.328.168.64.32 1.242.442 1.754.285 1.207.437 1.996.437 1.996s-.101-.383-.515-1.582c-.078-.23-.168-.484-.27-.773-.043-.125-.105-.274-.172-.434-.734-1.703-2.765-5.305-3.656-6.867-.762 2.25-1.437 4.36-2.004 6.265 2.578 4.715 4.149 12.797 4.149 12.797s-.137-.523-.782-2.347c-.578-1.621-3.441-6.64-4.117-7.809-1.164 4.281-1.625 7.172-1.207 7.88.809 1.362 1.574 3.722 2.25 6.323 1.524 5.867 2.586 13.012 2.586 13.012s.031.469.094 1.2a118.653 118.653 0 00.297 14.651c.504 6.11 1.453 11.363 2.664 14.172l.828-.449c-1.781-5.535-2.504-12.793-2.188-21.156.48-12.793 3.422-28.215 8.856-44.289 9.191-24.27 21.938-43.738 33.602-53.035-10.633 9.602-25.023 40.684-29.332 52.195-4.82 12.891-8.238 24.984-10.301 36.574 3.55-10.863 15.047-15.53 15.047-15.53s5.637-6.958 12.227-16.888c-3.95.903-10.43 2.442-12.598 3.352-3.2 1.344-4.067 1.8-4.067 1.8s10.371-6.312 19.27-9.171c12.234-19.27 25.562-46.648 12.141-58.621" fill="#3BA3D8"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0.03 0 633.27 511.9"><linearGradient id="a" x1="62.23" x2="62.483" y1="81.873" y2="81.873" gradientTransform="scale(115.9464 -115.9464)rotate(30.578 187.04 -69.817)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#909ca9"/><stop offset="1" style="stop-color:#ededee"/></linearGradient><path d="m429.3 163-69.9 22.8-60.8 26.9-17 4.5c-4.3 4.1-8.9 8.3-13.8 12.5-5.4 4.7-10.4 8.9-14.3 11.9-4.3 3.4-10.6 9.7-13.8 13.7-4.8 6-8.6 12.4-10.3 17.3-2.9 8.9-1.5 17.9 4.1 26.2 7.2 10.6 21.5 21.4 38.2 28.7 8.5 3.8 22.8 8.6 33.6 11.3 17.9 4.5 52.6 9.5 71.7 10.2 3.9.2 9 .2 9.3 0 .4-.3 3.4-5.9 6.8-13 11.7-23.9 20.2-46.4 24.8-65.6 2.7-11.6 4.9-27.1 6.3-45.5.4-5.1.5-22.3.2-28.1-.5-9.5-1.3-17.2-2.6-24.8-.2-1.1-.3-2.1-.2-2.2.2-.2.8-.4 9.5-2.9zm-15.9 9.4c.6 0 2.3 16.2 2.7 26.5.1 2.2.1 3.6-.1 3.6-.4 0-8.9-5-15-8.8-5.3-3.3-15.3-10-16.9-11.3-.5-.4-.5-.4 3.9-1.9 7.4-2.5 24.8-8.1 25.4-8.1m-35.6 11.7c.5 0 1.7.7 4.6 2.5 10.9 6.8 25.7 15.1 32 17.8 2 .8 2.2.5-2.3 3.6-9.6 6.6-21.6 13-36.3 19.5-2.6 1.2-4.8 2.1-4.8 2.1-.1 0 .2-1.3.6-2.9 3.5-13.2 5.6-26.5 5.7-37.2 0-5.3 0-5.3.5-5.4-.2 0-.1 0 0 0m-7.4 2.8c.3.3.1 12.2-.3 15.4-1 7.7-2.4 14.9-4.9 23-.6 2-1.1 3.6-1.2 3.7-.2.3-7.5-6.8-9.8-9.6-4.1-4.8-7.3-9.5-9.7-14.2-1.2-2.4-3.1-7-3-7.2.8-.5 28.7-11.3 28.9-11.1m-34.6 13.6c.1 0 .1 0 .2.1s.5 1 .8 1.9c1.7 4.6 5.5 11.4 8.8 15.7 3.6 4.8 8.3 9.8 12.2 13.2 1.3 1.1 2.4 2.1 2.6 2.2.3.3.4.3-8.2 3.5-10 3.8-20.9 7.6-33.4 11.6-3 1-6 1.9-8.9 2.9-.5.2-.3-.1 1.1-2.3 6.2-9.7 15.6-28.7 20.9-42.1.9-2.3 1.8-4.7 2-5.2.2-.7.5-1 1.2-1.4.2 0 .6-.1.7-.1m-10.5 4.4c.2.1-2.5 5.8-5.2 10.9-5.1 10-10.7 19.8-18.2 31.8-1.3 2.1-2.5 4-2.6 4.2-.3.4-.4.3-1.2-1.4-1.8-3.5-3.3-8.1-4.1-12.3-.8-4.1-.6-11.3.3-15.8.7-3.3.6-3.2 2.2-4 6.7-3.4 28.5-13.6 28.8-13.4m91.1 3.7v2.2c0 11.8-1.3 28-3.1 39.8-.3 2.1-.6 3.8-.6 3.8s-1.5-.4-3.3-1c-7.9-2.5-16.5-6.1-24.3-10.4-5.1-2.8-12.6-7.4-12.4-7.6.1-.1 2.3-1.2 4.9-2.6 10.4-5.4 20.3-11.2 28.9-17 3.2-2.2 8.1-5.7 9.1-6.6zm-131.1 15.6c.2 0 .2.4-.2 2.3-.2 1.4-.5 3.9-.6 5.7-.4 7.7.8 13.4 4.7 21.3 1.1 2.2 1.9 4 1.9 4-.4.3-35.4 10.6-46.4 13.6-3.3.9-6.1 1.7-6.3 1.7-.4.1-.4.1-.3-.8 1.2-7.8 7.1-17.9 15.4-26.5 5.5-5.7 9.9-9 17.4-13.3 5.4-3.1 13.7-7.7 14.3-7.9 0-.1.1-.1.1-.1m82.5 14.8c.1-.1 1.3.6 2.9 1.5 11.3 6.6 27.1 12.6 40.5 15.8l1.2.3-1.7 1c-7 3.9-30.1 13.5-53.8 22.4-3.4 1.3-6.8 2.5-7.5 2.8-.6.3-1.2.4-1.2.4 0-.1 1-1.9 2.2-4.2 6.6-12.4 13.3-27.4 16.7-37.9zm-8.4 2.7c.1.1-.4 1.2-.9 2.4-4.6 11.2-10.6 23.3-18.3 37l-3.6 6.3c-.1 0-1.6-1-3.5-2.1-11.2-6.9-21.1-15.3-27.6-23.5l-1-1.2 4.8-1.3c17.2-4.7 31.9-9.8 46.4-16 2-.9 3.7-1.6 3.7-1.6m52.2 18.3s.1 0 0 0c.1 1.2-2.6 12.1-4.9 20-1.8 6.6-3.4 11.8-6.3 20.9-1.3 4-2.4 7.3-2.4 7.3-.1 0-.4-.1-.7-.2-15.7-2.9-29.8-6.8-43-12.1-3.7-1.5-9-3.9-9.3-4.1-.1-.1 3.1-1.6 7.1-3.3 24.1-10.5 49-22.5 57.6-27.6 1-.6 1.8-.9 1.9-.9m-120.5 4.1c.1.1-6.6 9.8-16 22.9-3.3 4.6-7.1 10-8.5 12s-3.6 5.2-4.8 7.1l-2.2 3.4-2.4-2c-2.8-2.3-7.7-7.3-9.8-10-4.5-5.7-7.6-11.6-8.8-17.1-.6-2.5-.6-3.8-.1-4 .8-.2 14.9-3.5 28.1-6.6 7.3-1.7 15.9-3.7 18.9-4.4s5.5-1.3 5.6-1.3m6.7 2.6 1.7 1.9c7.6 8.5 15.4 14.8 24.8 20.3 1.7 1 3 1.8 2.9 1.9-.4.3-32.7 11.7-47.6 16.9-8.4 3-15.3 5.3-15.4 5.3s-.5-.3-1.1-.7l-1-.7 1.5-2.2c5-7.2 11.2-15.1 24.8-31.5zm42.2 30.2c.1-.1 2.4.8 5.2 1.9 6.9 2.6 12.3 4.2 19.6 6.1 9 2.3 22 4.5 29.7 5.1 1.2.1 1.8.2 1.6.4-.4.2-8.1 2.8-13.8 4.6-9.1 2.9-36.8 11-59.5 17.6-4.2 1.2-7.8 2.2-8 2.3-.5.1-2.3-.4-2.3-.6 0-.1 1.3-1.7 2.8-3.5 7.6-9.1 15.2-19.2 21.5-28.9 1.7-2.8 3.2-5 3.2-5m-9.3.2c.1.1-3.7 6.1-10.3 16.4-2.8 4.4-5.9 9.4-7 11.1s-2.6 4.3-3.5 5.8l-1.5 2.7-.8-.2c-1.9-.5-15.3-5.2-18.8-6.7-4.4-1.7-8.9-3.9-12.3-5.7-4.2-2.3-9.5-5.7-9.1-5.8.1-.1 7.3-2 16.1-4.4 23.2-6.3 36-9.9 44.4-12.6 1.4-.2 2.8-.6 2.8-.6m65.8 15.5c.3.5-8.3 24.3-11.4 31.8-.7 1.7-.9 2.1-1.3 2.1-.9-.1-13.3-1.8-20.9-2.9-13.2-2-35.3-5.9-40.8-7.1l-1.3-.3 7.9-1.8c16.9-3.8 25.1-5.9 33.3-8.4 10.4-3.2 20.7-7.1 31.1-12 1.7-.8 3-1.4 3.4-1.4" style="fill:url(#a)"/><linearGradient id="b" x1="61.44" x2="61.693" y1="73.151" y2="73.151" gradientTransform="matrix(80.3196 0 0 -80.3196 -4653.717 5908.5)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#939fab"/><stop offset="1" style="stop-color:#dcdee1"/></linearGradient><path d="M357.2 0c-1.2-.2-19.9 6.6-32 11.5-16.3 6.7-29 13-36.8 18.5-2.9 2.1-6.6 5.7-7.1 7.1-.2.5-.3 1.2-.3 1.8l7.1 6.7L305 51l40.1 7.2 45.9 7.9.5-4c-.2 0-.3-.1-.4-.1l-6-1-1.2-2.2c-6.2-11-13.1-24.6-17.1-33.8-3.1-7.1-6.1-15.4-7.7-21.3-1.2-3.4-1.3-3.6-1.9-3.7m-.8 2.7c.1.1.3 1.5.5 3.3.9 7.4 2.5 14.5 5.1 22.3 2 5.8 2 5.5-.3 4.8-5.4-1.5-29.5-5.7-47-8.1-2.8-.4-5.2-.7-5.2-.8-.2-.2 12.6-6.9 18.3-9.6C335 11.3 354.9 3 356.4 2.7m-51 23.7 2.1.7c11.2 3.8 39.4 9.2 54.9 10.5 1.7.2 3.2.3 3.3.3.1.1-1.4.8-3.3 1.7-7.5 3.8-15.8 8.4-21.5 11.9-1.7 1.1-3.2 1.9-3.4 1.9s-1.3-.2-2.5-.4l-2.1-.3-5.3-5.2c-9.3-9-16.6-16-19.4-18.7zm-2.1 1.6 7.5 9.3c4.1 5.1 8.2 10.1 9.1 11.3.9 1.1 1.6 2 1.6 2.1-.2.2-10.8-1.9-16.4-3.2-5.8-1.3-8.1-2-11.7-3.1l-2.9-1v-.7c.1-3.5 4.5-8.8 12.2-14.2zm63.4 12.7c.2 0 .5.5 1.1 1.9 1.8 4 7.4 14.6 8.8 16.7.4.7 1.2.Line truncated

Before

Width:  |  Height:  |  Size: 14 KiB

-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0"?>
<!-- Copyright Tencent Cloud. Sourced from TencentCloud/tencentcloud-monitor-grafana-app under Apache License 2.0. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 286.65 207.43">
<defs>
<style>.cls-1{fill:#00a3ff;}.cls-2{fill:#00c8dc;}.cls-3{fill:#006eff;}</style>
</defs>
<title>Tencent Cloud</title>
<g id="&#x56FE;&#x5C42;_2" data-name="&#x56FE;&#x5C42; 2">
<g id="&#x56FE;&#x5C42;_1-2" data-name="&#x56FE;&#x5C42; 1">
<path class="cls-1" d="M248.41,169.83c-5.11,5-14.21,10.79-29.16,11.3-6.91.23-15,.26-18.67.26h-80.3l57.59-55.94c2.65-2.57,8.61-8.27,13.75-12.9,11.28-10.15,21.43-12.2,28.61-12.13a40.46,40.46,0,0,1,28.18,69.41m19.23-75.5a66.15,66.15,0,0,0-47.31-20c-16.07,0-29.91,5.54-42,15.38-5.27,4.29-10.79,9.42-17.74,16.17-3.45,3.36-103.53,100.46-103.53,100.46a156.54,156.54,0,0,0,18.9,1c6,0,121,0,125.82,0,9.69,0,16,0,22.76-.5,15.53-1.13,30.21-6.83,42.07-18.48A66.49,66.49,0,0,0,267.64,94.33Z"/>
<path class="cls-2" d="M106.18,88.09C94.42,79.28,81.25,74.36,66.32,74.38A66.5,66.5,0,0,0,20,188.44a64.54,64.54,0,0,0,37.05,17.94l25.76-25c-4.16,0-10.14-.07-15.45-.25-14.94-.51-24-6.25-29.15-11.3a40.46,40.46,0,0,1,28.18-69.41c7,0,16.62,2,27.43,11,5.16,4.28,16.62,14.36,21.65,18.89a.62.62,0,0,0,.87,0L134.11,113a.64.64,0,0,0,0-1c-8.53-7.71-20.62-18.5-27.91-23.92"/>
<path class="cls-3" d="M227.3,59.36a89.08,89.08,0,0,0-172,16,65.32,65.32,0,0,1,11-.93,64.36,64.36,0,0,1,15,1.76,2.8,2.8,0,0,1,.28.06A63,63,0,0,1,200.56,62.78a.58.58,0,0,0,.7.38,76.32,76.32,0,0,1,25.14-2.62c.85.07,1.18-.41.9-1.18"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#e80230" d="M855.654 512.154c0 56.422-.153 112.896.256 169.267 0 9.062-2.713 13.773-10.854 17.92a74510 74510 0 0 0-321.024 169.984c-7.68 3.993-13.824 4.813-22.22.358a62695 62695 0 0 0-323.84-170.7c-7.527-3.943-9.882-8.602-9.882-17.05.256-113.255.256-226.56 0-339.866 0-8.448 2.713-13.107 10.035-16.998A92518 92518 0 0 0 501.914 154.47c7.526-3.993 13.21-4.352 20.992-.256A65522 65522 0 0 0 847.462 326.4c7.783 4.096 8.295 9.267 8.295 16.538a25193 25193 0 0 0-.103 169.216M489.472 727.552V709.12c0-101.888.154-203.776-.358-305.664 0-11.622 2.713-17.971 13.363-23.194 28.774-14.182 56.832-29.696 85.248-44.697 3.174-1.946 6.246-4.096 9.216-6.349-27.648-14.643-53.402-28.672-79.616-41.83-3.482-1.741-9.728-.666-13.568 1.33a21905 21905 0 0 0-166.81 87.604c-13.517 7.168-32 11.878-38.502 23.398-6.912 12.186-2.355 31.13-2.714 47.104-.153 13.517 0 26.983 0 42.701l107.879-56.73v16.897c0 73.37 0 146.79.153 220.262 0 4.915 1.331 12.493 4.455 14.285 25.958 14.54 52.377 28.057 81.254 43.213zm85.248-22.528c4.915-2.15 8.397-3.43 11.674-5.12 20.787-11.008 41.37-22.323 62.464-32.666 8.857-4.352 12.185-9.523 12.134-19.814-.41-81.664-.205-163.328-.205-245.094 0-4.352-.46-8.704-.717-14.95-25.753 13.567-49.766 26.93-74.393 38.911-8.96 4.352-11.11 9.882-11.06 19.098.257 64.717 0 129.433 0 194.048.103 21.197.103 42.291.103 65.536v.102z"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="45.02 22.32 53.115 57.774"><style><![CDATA[.I{stroke-width:.5}.J{stroke-miterlimit:10}.K{stroke:#000}.L{fill:none}.M{fill:#f9c89a}.N{fill:#4f2e0e}.O{fill:#6d9758}.P{stroke-width:.1}]]></style><g transform="matrix(.159884 0 0 .159884 34.20631 17.28392)"><g class="K I"><ellipse cx="299.73" cy="339.813" rx="10.957" ry="5.14" fill="#331e09"/><g stroke-miterlimit="10"><path d="M217.706 319.453s4.363 18.614 4.944 24.142 11.635 8.145 12.798 1.745 5.236-22.105 5.236-22.105zm69.518 4.072s5.816 13.962 5.816 21.814 13.96 9.017 15.125 3.78 2.908-25.887 2.908-25.887z" class="M"/><path d="M234.77 336.03c-2.327.97-8.92 1.746-11.44.777s.195 9.113.97 12.217 8.92 2.52 8.92 2.52z" fill="#a15813"/></g><g class="N"><ellipse cx="220.979" cy="344.03" rx="4.872" ry="11.636"/><ellipse cx="236.249" cy="345.268" rx="5.018" ry="11.416"/></g><g stroke-miterlimit="10"><path d="M202.145 377.77L202 364.1c-.145-7.562 7.854-17.16 24.142-16.725s23.85 9.453 23.85 18.18-.728 15.707-1.6 17.452-42.6 2.327-44.2.728-2.036-5.964-2.036-5.964z" fill="#9e5613"/><path d="M202.145 389.55c-2.763-.727-3.78-3.636-3.927-6.398s2.182-5.1 3.927-5.382c1.308 1.746 3.926 2.474 6.253 2.9s32.14.727 35.63.436 4.363-2.326 4.946-3.197c2.473.87 3.5 3.488 3.635 5.96s-1.018 4.8-3.5 5.673-15.562 2.9-24.578 2.763-22.396-2.764-22.396-2.764z" class="N"/><path d="M310.638 342.43s-7.854 4.653-17.9 1.164c-6.544-.873-8.3-.873-8.145 2.327s1.02 11.926-2.035 15.56-6.255 13.1-1.6 17.452 71.988 3.927 74.607 3.2 4.218-5.382 4.218-5.382.87-9.9.58-15.124-7.562-14.834-19.925-14.397-17.45 9.162-22.978 10.325c-4.654-4.362-6.4-9.452-6.4-10.472s-.434-4.653-.434-4.653z" fill="#9e5613"/><path d="M295.585 358.355c4.363 0 7.5-1.963 7.854-6.472s-.727-6.98-3.928-7.198-7.126-.873-9.016-2.108-2.1-3.5-1.3-4.437 2.18-1.817 2.18-1.817l-.5-1.38s-7.2 2.763-6.544 10.47 4.508 12.943 11.27 12.943zm7.927-13.67c2.398.945 2.907 2.764 2.545 4.727s-1.164 7.636 2.98 7.417 5.236-8.3 4.873-11.998-2.764-7.272-3.854-8.145l-.218 1.1s.824.58.85 2.036-2.45 4.216-7.175 4.872z" class="N"/><path d="M317.473 357.556c-2.23 4.85-4.363 20.363-2.424 24.626" class="L"/><path d="M280.97 378.935s-3.346 2.036-3.054 5.234 2.763 3.928 6.4 4.8 38.103 1.9 44.356 2.18 27.632-1.3 31.268-2.763 6.836-7.854-.145-11.636c-2.765 3.055-4.945 3.637-9.454 4.22s-25.597.727-34.322.436l-31.995-.727c-2.18-.146-3.053-1.745-3.053-1.745z" class="N"/></g><g stroke-miterlimit="10" class="M"><path d="M265.554 115.412c-1.02 1.163-5.817 6.7-3.5 11.343s15.56 25.015 15.56 25.015 29.232-14.834 28.36-21.815-6.836-15.27-6.836-15.27zm71.9 105.63c.97-.97 3.1-5.72-2.618-7.466-4.556-.582-7.853 1.552-8.822 2.62s2.035 6.787 3.877 6.98 7.563-2.133 7.563-2.133z"/><path d="M341.42 226.28c.873-1.26 2.715-4.46-1.55-6.593s-9.988.098-11.442 2.327 2.424 7.175 3.2 7.175 9.792-2.9 9.792-2.9z"/><path d="M331.87 202.816l-5.38 9.454s3.005 3.927 4.168 8.87-.776 6.7.872 6.4 11.248-2.908 13.1-1.746 4.363 5.915 2.618 9.114-6.787 9.792-13.865 11.538-15.608-1.455-18.8-5.915-8.24-18.8-8.436-21.33 3.2-10.18 3.2-10.18l13.186-5.914z"/><path d="M325.035 211.542c2.423 1.357 6.303 4.363 7.27 9.502s-1.066 11.635-4.362 14.35"/><path d="M341.7 234.423s-2.328 3.298-7.758 2.52-5.04-7.562-2.424-9.404 6.786-3.296 9.6-2.812 4.167 1.745 4.167 1.745"/><path d="M334.343 228.897l2.617 4.848s-1.65 1.357-3.588.484-1.94-2.327-1.455-3.587 2.426-1.745 2.426-1.745z"/></g><g stroke-miterlimit="10" class="O"><path d="M314.466 123.992s10.764 5.672 12.5 12.653c5.235 1.745 11.392 9.428 10.8 15.052 5.623 2.327 8.12 5.587 8.12 9.27 3.104 2.715 7.744 9.678 2.12 19.76s-8.927 17.055-8.927 17.055l-22.495-1.944-1.94-6.8 10.47-19.392s-4.654-7.562-10.085-7.757c-1.356 5.817-2.714 14.155-2.714 14.155l.58 31.995-2.908 1.745-.582 7.175 7.175 14.93 2.52 2.327-6.594 10.278 1.553 2.9 8.92 21.912-.194 2.715 5.237 6.786-.195 2.908 2.9 7.175-5.624 12.798-3.5 6.98 3.297 10.083s-9.113 8.34-24.24 8.145-25.4-7.95-25.4-7.95l-2.908-1.744s3.297-19.002 2.52-29.668-3.104-26.76-3.104-30.444-.97-14.155-.97-14.155l-1.553 33.546c-.193 11.247-1.745 26.565-3.683 29.667s-4.072 4.072-4.072 4.072l2.132 3.686.582 4.458-2.327 2.9-4.267-1.165s-8.337 9.697-23.462 7.953-24.432-9.308-25.402-15.514c-3.5-2.52-3.878-4.266-3.878-4.266l9.9-11.44-5.624-3.296 4.654-8.34s3.297-8.145 3.878-10.86 2.327-9.307 2.327-9.307l-4.848.193 7.95-12.4-.58-8.533 14.542-30.83-.582-5.042-1.95-2.715-1.587-10.762 1.02-5.818s5.03-6.107 5.6-11.15-2.417-10.083-2.417-10.083l-33.98 22.3-4.87.388-13.973 6.205-3.303-1.358s-1.166-1.938-1.554-5.04-.001-17.064 1.162-19.003 3.877-1.94 3.877-1.94 4.46-.775 7.95-3.103 25.014-18.228 30.25-22.3 23.463-19.778 23.463-19.778 6.205-4.848 9.695-6 5.815-.97 5.815-.97l.195 16.677 15.706 17.8 17.065-10.23 13.574-12.604z"/><path d="M262.936 115.993l-2.327 1.455-10.036 16.724 10.9 1.02-3.927 7.562 20.65 10.907 1.744-2.036-14.98-18.47c-3.5-4.363-4.5-14.107-.582-16.725s-1.453-.437-1.453-.437"/><path d="M272.242 155.915l31.196-5.2-3.673-13.3 13.344 1.7 1.164-15.417-13.816-8.87-1.3-.145s3.34Line truncated

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

-45
View File
@@ -1,45 +0,0 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { OpsxWorkspace } from "@opsxdb/ui";
import "./styles.css";
const root = document.getElementById("root")!;
const isTauri =
typeof window !== "undefined" &&
Boolean((window as unknown as { __TAURI_INTERNALS__?: unknown }).__TAURI_INTERNALS__);
// 产品唯一形态是桌面 Tauri:生产构建被浏览器打开时展示导引页,不渲染工作台。
// (开发态的 Vite 浏览器访问保留,仅供 UI 调试。)
if (!isTauri && import.meta.env.PROD) {
ReactDOM.createRoot(root).render(
<div
style={{
minHeight: "100vh",
display: "grid",
placeItems: "center",
background: "#0c1512",
color: "#d4d4d4",
fontFamily:
'-apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif',
}}
>
<div style={{ textAlign: "center", maxWidth: 460, padding: 24 }}>
<div style={{ fontSize: 40, marginBottom: 8 }}>🗄️</div>
<h1 style={{ fontSize: 22, margin: "0 0 10px", color: "#6ee7b7" }}>OpsxDB 请在桌面应用中打开</h1>
<p style={{ fontSize: 14, lineHeight: 1.8, color: "#8aa39b", margin: 0 }}>
客户端唯一形态是桌面 App(Tauri 2),本页面仅为桌面端构建产物。
<br />
官网与文档由本地后端提供:
<a href="http://127.0.0.1:8788/" style={{ color: "#34d399" }}>官网</a> ·{" "}
<a href="http://127.0.0.1:8788/docs" style={{ color: "#34d399" }}>文档</a>
</p>
</div>
</div>,
);
} else {
ReactDOM.createRoot(root).render(
<React.StrictMode>
<OpsxWorkspace />
</React.StrictMode>,
);
}
-553
View File
@@ -1,553 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
/* Design tokens v2 — 亮暗双套同色相,4 级字号,间距/圆角/阴影/层级全令牌化 */
color-scheme: dark;
/* 背景层级:三档,编辑器不再另起第四档深色(修 V7) */
--ops-bg: #0e1116;
--ops-surface: #151a21;
--ops-surface-2: #1a212b;
--ops-editor-bg: #10151c; /* 介于 bg 与 surface 之间,取代 #070b11 "黑洞" */
/* 边框 / 文本 */
--ops-border: #2a3340;
--ops-border-soft: #1f2733;
--ops-text: #e8edf5;
--ops-muted: #8b95a5;
/* 语义色:亮暗同色相,仅调明度(修 V3) */
--ops-accent: #3b82f6;
--ops-accent-strong: #2563eb;
--ops-accent-soft: color-mix(in srgb, var(--ops-accent) 16%, transparent); /* 补齐 V1 */
--ops-danger: #ef4444;
--ops-warning: #f59e0b; /* 统一命名,已删除 --ops-warn 别名(修 V1,引用侧由 WS-C 收敛) */
--ops-success: #10b981;
/* 兼容别名:--ops-fg 是历史误引用,统一收敛为 --ops-text(修 V1) */
--ops-fg: var(--ops-text);
--ops-input-bg: var(--ops-surface-2); /* 补齐 V1 */
--ops-row-alt: rgba(26, 33, 43, 0.65);
--ops-bg-active: var(--ops-accent-soft);
/* 字号:收敛为 4 级(修 V4,废除 10/11.5/12.5px) */
--ops-text-xs: 11px; /* 徽章、分组标签、状态栏 */
--ops-text-sm: 12px; /* 网格、树、次要文本 */
--ops-text-md: 13px; /* 正文、模态、表单 */
--ops-text-lg: 15px; /* 模态标题、空态标题 */
/* v1 字号别名:映射到 4 级新令牌,WS-C 收敛引用后删除 */
--ops-font-xs: var(--ops-text-xs);
--ops-font-sm: var(--ops-text-sm);
--ops-font-md: var(--ops-text-md);
/* 间距:4 的倍数 */
--ops-space-1: 4px; --ops-space-2: 8px; --ops-space-3: 12px;
--ops-space-4: 16px; --ops-space-5: 24px; --ops-space-6: 32px;
/* 圆角:3 级(修 V5) */
--ops-radius-sm: 4px; /* 按钮、输入框、标签 */
--ops-radius-md: 6px; /* 卡片、右键菜单 */
--ops-radius-lg: 10px; /* 模态、Toast */
/* 阴影:2 级 */
--ops-shadow-pop: 0 8px 24px rgb(0 0 0 / .35);
--ops-shadow-modal: 0 16px 48px rgb(0 0 0 / .45);
/* 层级 */
--ops-z-banner: 40; /* 断连/后端未就绪横幅 */
--ops-z-ctx: 80; /* 右键菜单 */
--ops-z-toast: 90;
--ops-z-modal: 100;
--ops-z-confirm: 110;
/* 尺寸(保留 v1) */
--ops-toolbar-h: 36px; --ops-tab-h: 32px; --ops-row-h: 28px;
--ops-statusbar-h: 24px; --ops-sidebar-w: 260px;
/* 滚动条走令牌(修 V11) */
--ops-scrollbar: #334155;
}
html.light {
/* 亮色:同色相,仅调明度 */
color-scheme: light;
--ops-bg: #f1f5f9; --ops-surface: #ffffff; --ops-surface-2: #f8fafc;
--ops-editor-bg: #f1f5f9;
--ops-border: #e2e8f0; --ops-border-soft: #eef2f7;
--ops-text: #1e293b; --ops-muted: #64748b;
--ops-accent: #2563eb; /* 蓝色系,不再切换青色(修 V3) */
--ops-accent-strong: #1d4ed8;
--ops-danger: #dc2626; --ops-warning: #d97706; --ops-success: #059669;
--ops-row-alt: #f8fafc;
--ops-scrollbar: #cbd5e1;
}
* { scrollbar-color: var(--ops-scrollbar) transparent; scrollbar-width: thin; }
body {
@apply m-0 font-sans antialiased;
background: var(--ops-bg);
color: var(--ops-text);
}
button, input, select, textarea { font: inherit; }
/* 全局焦点环:覆盖按钮/树项/Tab(02-P2-3) */
:focus-visible {
outline: 2px solid var(--ops-accent);
outline-offset: 1px;
}
}
@layer components {
.ops-shell {
background: var(--ops-bg);
color: var(--ops-text);
}
.ops-input {
@apply rounded border px-2 py-1 outline-none transition;
font-size: var(--ops-text-sm);
border-color: var(--ops-border);
background: var(--ops-input-bg);
color: var(--ops-text);
}
.ops-input::placeholder { color: var(--ops-muted); opacity: 0.7; }
.ops-input:focus {
border-color: var(--ops-accent);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--ops-accent) 35%, transparent);
}
.ops-btn-primary {
@apply inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded px-2.5 font-semibold text-white shadow-sm transition disabled:cursor-not-allowed disabled:opacity-50;
height: var(--ops-row-h);
font-size: var(--ops-text-sm);
background: var(--ops-accent-strong);
}
.ops-btn-primary:hover:not(:disabled) { background: var(--ops-accent); }
/* 危险主按钮:删除/截断/无 WHERE 更新等确认场景统一红钮(修 C2/C3、G5) */
.ops-btn-danger {
@apply inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded px-2.5 font-semibold text-white shadow-sm transition disabled:cursor-not-allowed disabled:opacity-50;
height: var(--ops-row-h);
font-size: var(--ops-text-sm);
background: var(--ops-danger);
}
.ops-btn-danger:hover:not(:disabled) {
background: color-mix(in srgb, var(--ops-danger) 85%, #fff);
}
.ops-btn-secondary {
@apply inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded border px-2 transition;
height: var(--ops-row-h);
font-size: var(--ops-text-sm);
border-color: var(--ops-border);
background: var(--ops-surface-2);
color: var(--ops-text);
}
.ops-btn-secondary:hover {
border-color: color-mix(in srgb, var(--ops-accent) 45%, var(--ops-border));
background: color-mix(in srgb, var(--ops-accent) 8%, var(--ops-surface-2));
}
.ops-btn-ghost {
@apply inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded px-1.5 transition;
height: var(--ops-row-h);
font-size: var(--ops-text-sm);
color: var(--ops-muted);
}
.ops-btn-ghost:hover {
color: var(--ops-text);
background: color-mix(in srgb, var(--ops-accent) 10%, transparent);
}
.ops-btn-ai {
@apply rounded border px-1.5 py-0.5 font-medium transition;
font-size: var(--ops-text-xs);
border-color: var(--ops-border);
background: var(--ops-surface-2);
color: var(--ops-text);
}
.ops-btn-ai:hover:not(:disabled) {
border-color: color-mix(in srgb, var(--ops-accent) 50%, var(--ops-border));
color: var(--ops-accent);
}
.ops-btn-ai:disabled { opacity: 0.5; cursor: not-allowed; }
.ops-tabbar {
@apply flex shrink-0 items-stretch gap-0.5 overflow-x-auto border-b px-1;
height: var(--ops-tab-h);
border-color: var(--ops-border);
background: var(--ops-surface-2);
}
.ops-empty {
@apply flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center;
color: var(--ops-muted);
background: var(--ops-bg);
}
.ops-empty h2 {
@apply m-0 font-semibold;
font-size: var(--ops-text-lg);
color: var(--ops-text);
}
.ops-empty p {
@apply m-0 max-w-sm;
font-size: var(--ops-text-sm);
}
.ops-conn-row {
@apply flex w-full items-center gap-3 border-b px-3 text-left transition;
min-height: 44px;
border-color: var(--ops-border-soft);
background: var(--ops-surface);
}
.ops-conn-row:hover {
background: color-mix(in srgb, var(--ops-accent) 8%, var(--ops-surface));
}
.ops-section-card {
@apply space-y-2 rounded border p-3;
border-color: var(--ops-border);
background: var(--ops-surface);
}
.ops-section-title {
@apply mb-1 font-semibold uppercase;
font-size: var(--ops-text-xs);
color: var(--ops-muted);
letter-spacing: 0.04em;
}
.ops-tab {
@apply border-b-2 border-transparent px-2.5 py-1.5 font-medium transition;
font-size: var(--ops-text-sm);
color: var(--ops-muted);
}
.ops-tab:hover { color: var(--ops-text); }
.ops-tab-active {
border-color: var(--ops-accent);
color: var(--ops-accent);
}
/* 编辑器:背景走 --ops-editor-bg,不再另起深色档(修 V7) */
.ops-code {
@apply font-mono leading-[1.45] outline-none;
font-size: var(--ops-text-sm);
background: var(--ops-editor-bg);
color: var(--ops-text);
border-color: var(--ops-border);
}
.ops-panel {
background: var(--ops-surface);
border-color: var(--ops-border);
}
.ops-chrome-header {
@apply flex shrink-0 items-center gap-1.5 border-b px-2.5;
height: var(--ops-toolbar-h);
border-color: var(--ops-border);
background: color-mix(in srgb, var(--ops-surface) 92%, #000);
}
html.light .ops-chrome-header {
background: var(--ops-surface);
}
.ops-section-label {
@apply flex h-7 shrink-0 items-center px-2.5 font-semibold uppercase tracking-[0.06em];
font-size: var(--ops-text-xs);
color: var(--ops-muted);
border-color: var(--ops-border);
background: var(--ops-surface-2);
}
.ops-statusbar {
@apply flex shrink-0 items-center gap-2.5 border-t px-2.5;
font-size: var(--ops-text-xs);
height: var(--ops-statusbar-h);
border-color: var(--ops-border);
background: var(--ops-surface-2);
color: var(--ops-muted);
}
.ops-tree-item {
@apply flex w-full items-center gap-1 truncate rounded px-1.5 text-left leading-tight transition;
min-height: var(--ops-row-h);
font-size: var(--ops-text-sm);
color: color-mix(in srgb, var(--ops-text) 78%, var(--ops-muted));
}
.ops-tree-item:hover {
background: color-mix(in srgb, var(--ops-accent) 10%, transparent);
color: var(--ops-accent);
}
.ops-tree-item-active {
background: color-mix(in srgb, var(--ops-accent) 14%, transparent);
color: var(--ops-accent);
}
.ops-grid {
@apply w-full border-collapse text-left;
font-size: var(--ops-text-sm);
}
.ops-grid th {
@apply sticky top-0 border-b px-1.5 py-[3px] font-semibold whitespace-nowrap;
border-color: var(--ops-border);
background: var(--ops-surface-2);
color: var(--ops-muted);
}
.ops-grid td {
@apply border-b px-1.5 py-[2px] font-mono whitespace-nowrap;
border-color: var(--ops-border-soft);
color: var(--ops-text);
}
.ops-grid tbody tr:nth-child(even) td {
background: var(--ops-row-alt);
}
.ops-grid tbody tr:hover td {
background: color-mix(in srgb, var(--ops-accent) 8%, transparent);
}
.ops-grid tbody tr.ops-row-selected td {
background: var(--ops-bg-active) !important;
}
.ops-grid th {
position: relative;
user-select: none;
}
.ops-grid th .ops-col-resize {
position: absolute;
right: 0;
top: 0;
width: 5px;
height: 100%;
cursor: col-resize;
}
.ops-grid th.ops-sortable {
cursor: pointer;
}
.ops-driver-row {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
min-height: var(--ops-row-h);
padding: 0 10px;
border-bottom: 1px solid var(--ops-border-soft);
text-align: left;
background: transparent;
color: var(--ops-text);
font-size: var(--ops-text-sm);
transition: background 0.1s;
}
.ops-driver-row:hover {
background: var(--ops-bg-active);
}
.ops-driver-row .ops-driver-meta {
margin-left: auto;
font-size: var(--ops-text-xs);
color: var(--ops-muted);
}
.ops-tab-dirty::before {
content: "●";
margin-right: 4px;
font-size: 8px;
color: var(--ops-accent);
}
.ops-grid .ops-null {
color: var(--ops-muted);
font-style: italic;
}
.ops-grid .ops-rownum {
@apply w-7 min-w-[1.75rem] text-right select-none;
color: var(--ops-muted);
background: var(--ops-surface-2) !important;
}
/* 统一模态基件样式:圆角/阴影/字级全走令牌,页脚右对齐 */
.ops-modal-overlay {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: var(--ops-space-4);
background: rgb(0 0 0 / .55);
backdrop-filter: blur(2px);
}
.ops-modal {
@apply overflow-hidden border;
border-radius: var(--ops-radius-lg);
border-color: var(--ops-border);
background: var(--ops-surface);
color: var(--ops-text);
box-shadow: var(--ops-shadow-modal);
font-size: var(--ops-text-md);
}
.ops-modal-header {
@apply border-b px-3.5 py-2 font-semibold;
font-size: var(--ops-text-md);
border-color: var(--ops-border);
background: var(--ops-surface-2);
}
.ops-modal-body {
@apply px-3.5 py-2.5 leading-relaxed;
font-size: var(--ops-text-md);
color: color-mix(in srgb, var(--ops-text) 90%, var(--ops-muted));
}
.ops-modal-footer {
@apply flex justify-end gap-2 border-t px-3.5 py-2;
border-color: var(--ops-border);
}
/* 危险确认语句清单(前 3 条 + 折叠,修 C2) */
.ops-modal-items {
@apply mt-2 space-y-1 rounded border px-2.5 py-2 font-mono whitespace-pre-wrap break-all;
font-size: var(--ops-text-xs);
border-color: var(--ops-border-soft);
background: var(--ops-editor-bg);
color: var(--ops-muted);
}
/* Toast:圆角/阴影走令牌,分级色由调用侧以 var(--ops-*) 注入 */
.ops-toast {
pointer-events: auto;
display: flex;
width: 360px;
max-width: calc(100vw - 2rem);
align-items: flex-start;
gap: var(--ops-space-3);
padding: var(--ops-space-3) var(--ops-space-4);
border: 1px solid var(--ops-border);
border-radius: var(--ops-radius-lg);
background: var(--ops-surface);
box-shadow: var(--ops-shadow-pop);
}
.ops-card {
@apply flex flex-col items-center gap-1.5 rounded-md border p-2.5 transition;
border-color: var(--ops-border);
background: color-mix(in srgb, var(--ops-surface-2) 80%, transparent);
}
.ops-card:hover {
border-color: color-mix(in srgb, var(--ops-accent) 55%, var(--ops-border));
background: color-mix(in srgb, var(--ops-accent) 8%, var(--ops-surface-2));
}
/* 结果区分段控件(02-§4.2-5,供 ResultPane 内部 Tab 使用) */
.ops-seg {
@apply inline-flex items-center gap-0.5 rounded border p-0.5;
border-color: var(--ops-border);
background: var(--ops-surface-2);
}
.ops-seg button {
@apply rounded px-2 py-0.5 transition;
font-size: var(--ops-text-xs);
color: var(--ops-muted);
background: transparent;
}
.ops-seg button:hover { color: var(--ops-text); }
.ops-seg button.ops-seg-active {
background: var(--ops-surface);
color: var(--ops-text);
box-shadow: 0 1px 2px rgb(0 0 0 / .25);
}
/* 骨架屏基类(备用):低饱和呼吸动画 */
.ops-skel {
border-radius: var(--ops-radius-sm);
background: color-mix(in srgb, var(--ops-muted) 18%, transparent);
animation: ops-skel-pulse 1.6s ease-in-out infinite;
}
@keyframes ops-skel-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.45; }
}
details > summary .ops-tree-chevron {
display: inline-block;
transition: transform 0.12s ease;
}
details[open] > summary .ops-tree-chevron {
transform: rotate(90deg);
}
}
.ops-drop-line {
height: 2px;
margin: 1px 4px;
border-radius: 1px;
background: var(--ops-accent);
}
.ops-drop-slot {
border: 1px dashed var(--ops-border);
}
.ops-drop-slot-active {
border-color: var(--ops-accent);
background: color-mix(in srgb, var(--ops-accent) 12%, transparent);
}
.ops-split-x {
width: 5px;
cursor: col-resize;
flex-shrink: 0;
background: transparent;
}
.ops-split-x:hover,
.ops-split-x:active {
background: color-mix(in srgb, var(--ops-accent) 45%, transparent);
}
.ops-split-y {
height: 5px;
cursor: row-resize;
flex-shrink: 0;
background: transparent;
}
.ops-split-y:hover,
.ops-split-y:active {
background: color-mix(in srgb, var(--ops-accent) 45%, transparent);
}
.cm-editor {
height: 100%;
outline: none;
background: transparent;
}
/* Tab 关闭按钮:固定 18px 占位,透明度切换消除横向抖动(修 T1) */
.ops-close-faint {
display: inline-flex;
align-items: center;
justify-content: center;
flex: none;
width: 18px;
height: 18px;
border-radius: 3px;
font-size: 12px;
line-height: 1;
color: color-mix(in srgb, var(--ops-muted) 55%, transparent);
background: transparent;
}
.ops-close-faint:hover {
color: var(--ops-text);
background: color-mix(in srgb, var(--ops-muted) 18%, transparent);
}
/* 右键菜单:z-index/阴影/圆角走令牌 */
.ops-ctx {
position: fixed;
z-index: var(--ops-z-ctx);
min-width: 140px;
padding: var(--ops-space-1);
border-radius: var(--ops-radius-md);
border: 1px solid var(--ops-border);
background: var(--ops-surface);
box-shadow: var(--ops-shadow-pop);
}
.ops-ctx button {
display: block;
width: 100%;
text-align: left;
padding: 6px 10px;
border-radius: var(--ops-radius-sm);
font-size: var(--ops-text-sm);
color: var(--ops-text);
background: transparent;
}
.ops-ctx button:hover:not(:disabled) {
background: var(--ops-bg-active);
}
.ops-ctx button:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.ops-ctx-sep {
height: 1px;
margin: 4px 6px;
background: var(--ops-border);
}
.ops-tree-group {
font-size: var(--ops-text-xs);
font-weight: 600;
letter-spacing: 0.04em;
color: var(--ops-muted);
}
-73
View File
@@ -1,73 +0,0 @@
import type { Config } from "tailwindcss";
/**
* 设计令牌 v2 映射:与 apps/web/src/styles.css 的 :root 令牌同源,
* 新增组件样式优先使用 ops-* utility,避免散落硬编码色值。
*/
export default {
content: [
"./index.html",
"./src/**/*.{ts,tsx}",
"../../packages/ui/src/**/*.{ts,tsx}",
],
theme: {
extend: {
colors: {
ops: {
bg: "var(--ops-bg)",
surface: "var(--ops-surface)",
"surface-2": "var(--ops-surface-2)",
"editor-bg": "var(--ops-editor-bg)",
border: "var(--ops-border)",
"border-soft": "var(--ops-border-soft)",
text: "var(--ops-text)",
muted: "var(--ops-muted)",
accent: "var(--ops-accent)",
"accent-strong": "var(--ops-accent-strong)",
"accent-soft": "var(--ops-accent-soft)",
danger: "var(--ops-danger)",
warning: "var(--ops-warning)",
success: "var(--ops-success)",
"input-bg": "var(--ops-input-bg)",
"row-alt": "var(--ops-row-alt)",
"bg-active": "var(--ops-bg-active)",
},
},
fontSize: {
"ops-xs": "var(--ops-text-xs)",
"ops-sm": "var(--ops-text-sm)",
"ops-md": "var(--ops-text-md)",
"ops-lg": "var(--ops-text-lg)",
},
spacing: {
"ops-1": "var(--ops-space-1)",
"ops-2": "var(--ops-space-2)",
"ops-3": "var(--ops-space-3)",
"ops-4": "var(--ops-space-4)",
"ops-5": "var(--ops-space-5)",
"ops-6": "var(--ops-space-6)",
},
borderRadius: {
"ops-sm": "var(--ops-radius-sm)",
"ops-md": "var(--ops-radius-md)",
"ops-lg": "var(--ops-radius-lg)",
},
boxShadow: {
"ops-pop": "var(--ops-shadow-pop)",
"ops-modal": "var(--ops-shadow-modal)",
},
zIndex: {
"ops-banner": "var(--ops-z-banner)",
"ops-ctx": "var(--ops-z-ctx)",
"ops-toast": "var(--ops-z-toast)",
"ops-modal": "var(--ops-z-modal)",
"ops-confirm": "var(--ops-z-confirm)",
},
// 修 V6:删除 JetBrains Mono 声明,等宽栈与 SqlEditor 统一为系统栈
fontFamily: {
mono: ["ui-monospace", "SFMono-Regular", "Menlo", "Consolas", "monospace"],
},
},
},
plugins: [],
} satisfies Config;
Loaded 100 of 269 files, more files were not shown because too many files have changed in this diff. Show more