[feat] initialize

This commit is contained in:
He
2026-03-16 19:20:34 +08:00
commit 188de67562
16 changed files with 3267 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules/
.vitepress/cache/

35
.vitepress/config.mts Normal file
View File

@@ -0,0 +1,35 @@
import { defineConfig } from 'vitepress'
import generateSidebarByPath from './sidebar.mts'
import type { SidebarAutoItem } from './sidebar.mts'
const sidebarAuto: SidebarAutoItem[] = [
{
text: 'Kinesin',
path: '/kinesin',
}
]
const sidebarByPath = generateSidebarByPath(sidebarAuto)
// https://vitepress.dev/reference/site-config
export default defineConfig({
title: 'KeDocs',
description: '代码跃海 世界同潮',
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: '知识库', link: 'https://kegongteng.cn' },
{ text: '联系', link: 'mailto:i@kegongteng.cn' },
],
logo: {
dark: "/avatar-dark.png",
light: "/avatar.png",
},
sidebar: sidebarByPath,
socialLinks: [
{ icon: 'github', link: 'https://github.com/gtxykn0504' }
]
}
})

140
.vitepress/sidebar.mts Normal file
View File

@@ -0,0 +1,140 @@
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const docsRoot = path.resolve(__dirname, '..')
export type SidebarAutoItem = {
text: string
path: string
}
export type SidebarItem = {
text: string
link: string
}
export type SidebarGroup = {
text: string
items: SidebarItem[]
}
function normalizeLink(link: string) {
if (!link.startsWith('/')) return `/${link}`
return link
}
type ResolvedPath = {
scopePath: string
scopeKey: string
absDir: string
isRoot: boolean
}
function resolvePathConfig(rawPath: string): ResolvedPath {
const normalized = rawPath.trim().replace(/\\/g, '/')
if (!normalized) {
throw new Error('path cannot be empty.')
}
if (!normalized.startsWith('/')) {
throw new Error(`path must start with '/'. Received: ${rawPath}`)
}
const scopePath = normalized === '/'
? '/'
: `/${normalized.replace(/^\/+/, '').replace(/\/+$/, '')}`
const scopeKey = scopePath === '/' ? '/' : `${scopePath}/`
const relative = scopePath === '/' ? '' : scopePath.slice(1)
return {
scopePath,
scopeKey,
absDir: path.resolve(docsRoot, relative),
isRoot: scopePath === '/'
}
}
function toLink(relativePath: string) {
return normalizeLink(relativePath ? `/${relativePath}` : '/')
}
function readFrontmatterAndTitle(filePath: string) {
const raw = fs.readFileSync(filePath, 'utf8')
const fmMatch = raw.match(/^---\s*([\s\S]*?)\s*---/)
let order = Number.POSITIVE_INFINITY
if (fmMatch) {
const fm = fmMatch[1]
const orderMatch = fm.match(/^\s*order\s*:\s*([-+]?\d+(?:\.\d+)?)/m)
if (orderMatch) order = Number(orderMatch[1])
}
const h1 = raw.match(/^#\s+(.+)$/m)
const title = h1 ? h1[1].trim() : path.basename(filePath, '.md')
return { order, title }
}
function generateSidebarGroup(entry: SidebarAutoItem): SidebarGroup {
const { absDir, isRoot } = resolvePathConfig(entry.path)
if (!fs.existsSync(absDir)) {
return { text: entry.text, items: [] }
}
const relativeDir = path.relative(docsRoot, absDir).split(path.sep).join('/')
const files = fs.readdirSync(absDir).filter((name) => {
if (!name.endsWith('.md')) return false
// When scanning docs root '/', do not include root index.md in sidebar.
if (isRoot && name.toLowerCase() === 'index.md') return false
return true
})
const items = files
.map((name) => {
const full = path.join(absDir, name)
const { order, title } = readFrontmatterAndTitle(full)
const baseName = path.basename(name, '.md')
const rel = relativeDir ? `${relativeDir}/${baseName}` : baseName
// index.md -> 目录根路径
const link = baseName === 'index' ? toLink(relativeDir) : toLink(rel)
return {
order,
text: title,
link
}
})
.sort((a, b) => {
if (a.order === b.order) return a.text.localeCompare(b.text)
return a.order - b.order
})
return {
text: entry.text,
items: items.map(({ text, link }): SidebarItem => ({ text, link }))
}
}
export function generateSidebarByPath(sidebarAuto: SidebarAutoItem[]) {
const sidebarConfig: Record<string, SidebarGroup[]> = {}
for (const entry of sidebarAuto) {
const { scopeKey } = resolvePathConfig(entry.path)
const group = generateSidebarGroup(entry)
if (!sidebarConfig[scopeKey]) {
sidebarConfig[scopeKey] = []
}
sidebarConfig[scopeKey].push(group)
}
return sidebarConfig
}
export default generateSidebarByPath

17
.vitepress/theme/index.ts Normal file
View File

@@ -0,0 +1,17 @@
// https://vitepress.dev/guide/custom-theme
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import './style.css'
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
},
enhanceApp({ app, router, siteData }) {
// ...
}
} satisfies Theme

139
.vitepress/theme/style.css Normal file
View File

@@ -0,0 +1,139 @@
/**
* Customize default theme styling by overriding CSS variables:
* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
*/
/**
* Colors
*
* Each colors have exact same color scale system with 3 levels of solid
* colors with different brightness, and 1 soft color.
*
* - `XXX-1`: The most solid color used mainly for colored text. It must
* satisfy the contrast ratio against when used on top of `XXX-soft`.
*
* - `XXX-2`: The color used mainly for hover state of the button.
*
* - `XXX-3`: The color for solid background, such as bg color of the button.
* It must satisfy the contrast ratio with pure white (#ffffff) text on
* top of it.
*
* - `XXX-soft`: The color used for subtle background such as custom container
* or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
* on top of it.
*
* The soft color must be semi transparent alpha channel. This is crucial
* because it allows adding multiple "soft" colors on top of each other
* to create a accent, such as when having inline code block inside
* custom containers.
*
* - `default`: The color used purely for subtle indication without any
* special meanings attached to it such as bg color for menu hover state.
*
* - `brand`: Used for primary brand colors, such as link text, button with
* brand theme, etc.
*
* - `tip`: Used to indicate useful information. The default theme uses the
* brand color for this by default.
*
* - `warning`: Used to indicate warning to the users. Used in custom
* container, badges, etc.
*
* - `danger`: Used to show error, or dangerous message to the users. Used
* in custom container, badges, etc.
* -------------------------------------------------------------------------- */
:root {
--vp-c-default-1: var(--vp-c-gray-1);
--vp-c-default-2: var(--vp-c-gray-2);
--vp-c-default-3: var(--vp-c-gray-3);
--vp-c-default-soft: var(--vp-c-gray-soft);
--vp-c-brand-1: var(--vp-c-indigo-1);
--vp-c-brand-2: var(--vp-c-indigo-2);
--vp-c-brand-3: var(--vp-c-indigo-3);
--vp-c-brand-soft: var(--vp-c-indigo-soft);
--vp-c-tip-1: var(--vp-c-brand-1);
--vp-c-tip-2: var(--vp-c-brand-2);
--vp-c-tip-3: var(--vp-c-brand-3);
--vp-c-tip-soft: var(--vp-c-brand-soft);
--vp-c-warning-1: var(--vp-c-yellow-1);
--vp-c-warning-2: var(--vp-c-yellow-2);
--vp-c-warning-3: var(--vp-c-yellow-3);
--vp-c-warning-soft: var(--vp-c-yellow-soft);
--vp-c-danger-1: var(--vp-c-red-1);
--vp-c-danger-2: var(--vp-c-red-2);
--vp-c-danger-3: var(--vp-c-red-3);
--vp-c-danger-soft: var(--vp-c-red-soft);
}
/**
* Component: Button
* -------------------------------------------------------------------------- */
:root {
--vp-button-brand-border: transparent;
--vp-button-brand-text: var(--vp-c-white);
--vp-button-brand-bg: var(--vp-c-brand-3);
--vp-button-brand-hover-border: transparent;
--vp-button-brand-hover-text: var(--vp-c-white);
--vp-button-brand-hover-bg: var(--vp-c-brand-2);
--vp-button-brand-active-border: transparent;
--vp-button-brand-active-text: var(--vp-c-white);
--vp-button-brand-active-bg: var(--vp-c-brand-1);
}
/**
* Component: Home
* -------------------------------------------------------------------------- */
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
#bd34fe 30%,
#41d1ff
);
--vp-home-hero-image-background-image: linear-gradient(
-45deg,
#bd34fe 50%,
#47caff 50%
);
--vp-home-hero-image-filter: blur(44px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
/**
* Component: Custom Block
* -------------------------------------------------------------------------- */
:root {
--vp-custom-block-tip-border: transparent;
--vp-custom-block-tip-text: var(--vp-c-text-1);
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
}
/**
* Component: Algolia
* -------------------------------------------------------------------------- */
.DocSearch {
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}

21
index.md Normal file
View File

@@ -0,0 +1,21 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
hero:
name: ":) Hello"
text: "Kegongteng's Docs"
tagline: 代码跃海 世界同潮
features:
- title: Kinesin
icon: 🛠️
details: 通过Kinesin您可以轻松地自定义URL重定向规则帮助您避免记忆长链接或根据您的需求自定义更多用处
link: /kinesin
linkText: 查看文档
- title: 隐私协议
icon: 📜
details: 隐私保护并非可有可无,与我们一起尊重并保护您的隐私
link: /privacy
linkText: 点击阅读
---

30
kinesin/index.md Normal file
View File

@@ -0,0 +1,30 @@
---
outline: deep
order: 1
---
# 何为 Kinesin
不知道您在上网的时候,会不会想用`blog.ke`这样独特的域名来访问网站或者将深而不可测的长链接转化为短链接来使用而Kinesin就是为了实现这些想法而诞生的。
Kinesin 是一款轻量级的浏览器扩展,无需复杂的 Hosts 配置,即可轻松自定义 URL 重定向规则。它帮助您告别记忆长链接的烦恼,并根据您的需求实现各种个性化跳转。通过可选的服务器同步功能,您还可以在多个设备和浏览器之间享受一致的规则体验。
## 产品亮点
☁️ 简单高效:操作逻辑简单,具有干净,极简主义的界面
🚀 跨平台支持Google Chrome Edge Firefox等主流浏览器您还可以将其适用于Pad等移动端
📦 开源:代码开源,公开透明
🧐 安全:我们不记录您的浏览历史,同步服务由你自部署,保证隐私安全
## 立刻使用
Kinesin已上架主流浏览器插件商店您可一键安装使用。
1. [Edge](https://microsoftedge.microsoft.com/addons/detail/kinesin/bfnnclfgealppofiiimocnpiombnoolg)
2. [Firefox](https://addons.mozilla.org/zh-CN/firefox/addon/kinesin/)
## 与我们一起
个人的力量总是有限的Kinesin 仍有许多可以改进之处。如果您有任何建议、想法或遇到了问题,欢迎在 [GitHub 仓库](https://github.com/gtxykn0504/kinesin-redirector) 中提出 Issue 或通过 Pull Request 贡献代码。

45
kinesin/online.md Normal file
View File

@@ -0,0 +1,45 @@
---
outline: deep
order: 3
---
# 同步功能
通过服务器同步规则,您可以在多个设备和浏览器之间共享自定义的重定向规则,实现无缝的浏览体验。
## 配置同步服务器
Kinesin 的服务器端使用 PHP 编写,您可以按照以下步骤自行部署同步服务。
### 1. 下载服务器端代码
访问 [GitHub 仓库](https://github.com/gtxykn0504/kinesin-redirector/tree/main/server) 下载 `redirect.php` 文件。
### 2. 编辑配置文件
打开 `redirect.php`,根据您的实际情况修改以下两处配置:
- **设置 API 密钥**
找到 `define('API_KEY', 'your-secret-key-here');`
`your-secret-key-here` 替换为您自定义的密码,用于保证同步请求的安全性。
- **指定规则存储文件**
找到 `$storageFile = __DIR__ . '/rules.json';`
您可以修改 `rules.json` 的存储路径(例如 `/var/data/kinesin-rules.json`),请确保 PHP 进程对该文件及其所在目录拥有读写权限。
### 3. 部署到服务器
- 配置一个支持 PHP 的 Web 服务器(如 Apache、Nginx
- 将编辑后的 `redirect.php` 上传到服务器上的合适目录。
- 手动创建 `rules.json` 文件并设置正确的权限。
### 4. 插件端配置
1. 点击浏览器工具栏中的 Kinesin 图标。
2. 在弹出窗口中,点击右上角的 ⚙️ 图标进入设置页面。
3. 找到 同步设置 区域,输入您的 服务器 URL例如 `https://example.com/redirect.php`)和 API 密钥。
4. 启用“启用同步”开关,然后点击“保存”即可。
## 自动下载规则
如果您开启“启动时自动下载规则”选项Kinesin 将在每次浏览器启动或点击插件图标时自动从服务器拉取最新的规则,您可以在插件弹窗或设置页面中查看当前的同步状态。

37
kinesin/use.md Normal file
View File

@@ -0,0 +1,37 @@
---
outline: deep
order: 2
---
# 使用指南
## 添加跳转规则
### 有效顶级域名
如果您希望将 `blog.kgthe.top` 这样的有效顶级域名重定向到另一个地址,请按以下步骤操作:
1. 点击浏览器工具栏中的 Kinesin 图标。
2. 在弹出窗口中,将 `blog.kgthe.top` 填入 源 URL将目标地址`https://kegongteng.cn`)填入 目标 URL。
3. 点击 添加 按钮。
4. 在浏览器地址栏输入 `blog.kgthe.top` 并访问,即可验证跳转是否生效。
### 自定义短域名
如果您希望使用 `blog.ke``bing` 等非规范的短域名作为源地址,操作略有不同:
1. 点击 Kinesin 图标,将 `bing` 填入 源 URL目标地址填入 目标 URL。
2. 点击 添加。
3. 在浏览器地址栏输入 `bing/` 并访问,即可验证跳转是否生效。
::: danger 重要提示
对于非规范顶级域名,首次访问时**必须加上末尾的斜杠 `/`**,否则浏览器会将其作为搜索词处理。首次成功访问后,浏览器地址栏会自动补全斜杠,后续即可直接输入短域名。
:::
## 分组管理规则
随着规则数量增多,分组功能可以帮助您更好地组织和管理。
在使用该功能之前请您事先添加组。首先点击浏览器的Kinesin插件。在弹出的页面中点击右上角的 ⚙️ 图标,进入设置页面。在规则列表中,您可以点击分组标题旁的 图标,新增分组。
您可以手动设定分组或者通过自动分组功能。自动分组依据源URL 目标URL是否包含某种特定字符来分类它可在添加分组时或者点击已有组标题旁的 ✏️ 图标进入编辑分组选项来设定。在添加规则时,将 分组 选项调至 自动分组 即可按设定的规则分类。

2682
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

16
package.json Normal file
View File

@@ -0,0 +1,16 @@
{
"scripts": {
"docs:dev": "vitepress dev",
"docs:build": "vitepress build",
"docs:preview": "vitepress preview"
},
"dependencies": {
"fs": "^0.0.1-security",
"path": "^0.12.7",
"url": "^0.11.4",
"vitepress": "^1.6.4"
},
"devDependencies": {
"@types/node": "^25.5.0"
}
}

97
privacy.md Normal file
View File

@@ -0,0 +1,97 @@
# 隐私协议
欢迎使用 Kegongteng以下简称“我们”“本项目”或“我”提供的相关网络服务。本隐私协议旨在向您说明我们如何收集、使用、存储和保护您的个人信息以及您如何管理这些信息。
## 1. 我们的信息收集
### 1.1 自动收集的信息
在您使用我们的服务时,系统会自动收集您的以下信息:
1.IP地址我们会收集您的IP地址以了解您的大致地理位置、网络来源等并以此规避网络攻击以及统计网站数据。
2.用户代理:我们会收集您的用户代理以获取诸如操作系统版本、浏览器版本等信息,并据此实现针对不同设备差异化的服务提供,如针对不同平台提供不同的软件下载链接。同时我们还会据此分析用户设备信息的趋势,优化应用程序。
3.Cookie或类似技术我们会收集Cookie实现鉴权、用户甄别等功能。您可以根据浏览器的提示禁用所有Cookie或清除已有的Cookie同时您也可以指示浏览器在发送Cookie时通知您或选择性地发送Cookie但这可能导致某些功能无法正常使用。
3.日志信息:我们会收集部分应用程序运行时的日志,用以分析应用程序运行时的性能表现、出现的错误等,以提高应用程序的稳定性。
### 1.2 您主动提供的信息
下列信息系统并不会自动收集,在您主动提供后我们才会进行收集:
1.电子邮件:我们收集您的电子邮件地址,并通过`spircape.com`域名下的邮箱向您发送包括但不限于评论回复提醒、安全提醒等信息。
2.用户名:我们会收集您在我们提供的服务下的用户名用以鉴别您的身份。
## 2.基础信息的使用
我们通过Matomo飞书lark等平台对您提供的基础信息进行使用
- 服务优化与性能分析通过统计IP地址、Cookie、浏览器User Agent及访问设备信息我们可以分析用户访问情况优化服务器配置提升网站或应用的加载速度和整体性能。
- 安全防护利用IP地址、User Agent等信息我们能够监控异常的访问行为预防恶意攻击并及时采取措施保护系统和用户数据的安全。
- 地域服务优化依据IP地址及其对应的地区我们可为用户提供更符合地区特点和需求的内容和服务与提升使用体验。
- 用户体验提升Cookie数据有助于记录您的浏览状态和偏好设置使您在重复访问时能够享受到更为个性化与便捷的服务。
- 设备兼容性检测通过收集访问设备和浏览器User-Agent信息我们可以不断优化网站在不同设备和浏览器上的展示效果。
## 3. 我们如何保护您的信息
我们使用业内常用的安全措施,以防止您的个人信息遭受未经授权的访问、泄露、篡改或破坏,包括但不限于:
- HTTPS 超文本传输协议安全:用于阻止我们的网站在用户访问期间的中间人攻击,保障数据的传输安全。
- Salt 加盐:用于对关键信息加密结果的混淆,防止数据被篡改与破解。
- MD5 信息摘要算法:用于数据完整性校验与敏感数据的单向加密,防止数据被篡改与泄露。
- 访问控制与权限管理:确保仅授权人员能够访问您的个人信息。
- 安全审计:对系统和数据存储进行检查。
但请您理解,由于技术的局限性以及可能的恶意攻击,我们无法保证信息 100% 安全。若发生安全事件,我们将第一时间通知您并采取补救措施。
## 4.适用于中国大陆居民的相关条例(参照《中华人民共和国个人信息保护法》)
我们承诺严格遵守《中华人民共和国个人信息保护法》及其实施条例的相关规定,在处理您的个人信息时,遵循合法、正当、必要和诚信原则。具体规定如下:
- 合规性承诺:我们确保所有的个人信息处理活动均符合《中华人民共和国个人信息保护法》的要求,依法明确处理目的、范围及方式,并保障信息主体的合法权益。
### 6.1 数据处理依据
我们处理您的个人信息的法律依据包括但不限于:
- 您的明确同意;
- 履行与您之间合同所必需;
- 遵守法律法规的要求;
- 保护您或他人重要利益所必需;
- 基于公共利益的需要或其他法律规定的情形。
### 6.2 您的权利
根据《中华人民共和国个人信息保护法》,您享有如下权利:
- 查询和访问权:您有权了解我们是否在处理您的个人信息,以及处理的具体内容。
- 更正权:若您的个人信息存在错误或不完整,您有权要求我们进行更正。
- 删除权:在符合相关法律规定的情况下,您有权请求删除您的个人信息。
- 限制处理权:在特定情形下,您有权要求限制我们对您个人信息的处理。
- 撤回同意权:在您基于同意而进行信息处理的前提下,您有权随时撤回该同意,但撤回同意不影响此前基于同意所开展的处理活动。
- 投诉权:如认为我们的信息处理活动侵犯您的合法权益,您有权向有关监管机构投诉。
### 6.3 跨境数据传输
如果您的个人信息需要跨境传输,我们将采取严格措施,确保数据传输符合《中华人民共和国个人信息保护法》等法律法规的要求,并保障您的信息安全。
## 7.适用于欧盟居民的相关条款(参照《欧盟通用数据保护条例》)
如果您为欧盟国家的居民,以下条款将适用于您:
- 合规性承诺我们致力于遵守欧盟《一般数据保护条例》GDPR的相关要求并在处理您的个人数据时确保所有操作符合数据合法性、公正性、透明性及数据最小化原则。
### 7.1 数据处理依据
我们处理您的个人数据所依据的法律基础包括但不限于:
- 您的明确同意;
- 履行与您之间合同所必需;
- 遵守法律义务;
- 我们或第三方的合法利益(在不损害您基本权利与自由的前提下)。
### 7.2 您的权利
根据GDPR您享有以下权利
- 查阅权:有权访问我们存储的您的个人数据;
- 更正权:有权要求更正不准确或不完整的个人数据;
- 删除权(被遗忘权):在特定情况下,您有权要求删除您的个人数据;
- 限制处理权:在某些情况下,您有权要求限制我们对您个人数据的处理;
- 数据可携带权:有权以结构化、常用和机器可读的格式接收您的个人数据,并可将其传输给其他数据控制者;
- 反对权:在特定情况下,您有权反对我们对您个人数据的处理;
- 投诉权若认为我们对您的个人数据处理违反GDPR规定您有权向相关主管部门提出投诉。
### 7.3 跨境数据传输
若您的个人数据需要转移至欧盟以外的地区我们将采取适当的措施确保数据传输符合GDPR要求并保障您的数据安全。
### 7.4 行使权力
如需行使上述权利或对我们处理您的个人数据有任何疑问,请通过下述联系方式与我们联系。
## 8.您的其他权利
无论您位于何处,您均享有以下权利:
- 查询和访问:您有权访问我们存储的您的个人信息。
- 更正和删除:您可以联系我们请求更正或删除您的个人信息(法律规定的例外情况除外)。
- 撤回同意:您可随时撤回您对个人信息处理的同意。
## 9.隐私协议的更新
我们可能会不时更新本隐私协议,以适应法律法规的变化或服务的调整。由于服务对象的不确定性,若有变更,您需要自行阅读。
## 10.生效范围
除特别声明外,本隐私政策适用于本项目开发、运营的网站、在线服务、交互式应用程序等服务。如您使用了上述服务,则代表您同意我们根据本隐私政策中的条款收集、储存、使用、分享您的个人信息。

BIN
public/avatar-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

5
readme.md Normal file
View File

@@ -0,0 +1,5 @@
# Kedocs
1. Build Commandnpm run docs:build
2. Output Directory.vitepress/dist
3. Install Commandnpm install