difftab 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -51
- package/README.zh-CN.md +67 -29
- package/dist/server/main.js +233 -24
- package/dist/web/app.css +1 -1
- package/dist/web/app.js +16 -16
- package/package.json +1 -1
package/dist/server/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { closeSync, mkdirSync, openSync, readFileSync, realpathSync, statSync, unlinkSync, watch, writeFileSync, writeSync } from "node:fs";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { parseArgs } from "node:util";
|
|
4
|
-
import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { basename, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { createServer, request } from "node:http";
|
|
7
7
|
import { homedir, tmpdir } from "node:os";
|
|
@@ -102,10 +102,13 @@ var GitError = class extends Error {
|
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
104
|
/**
|
|
105
|
-
* 跑一条 git
|
|
105
|
+
* 跑一条 git 命令,stdout 以**字节**返回。**非零退出不抛异常**——若干只读探测(空仓库下的
|
|
106
106
|
* `rev-parse --verify HEAD`、下限之下的 `--show-object-format`)正是靠非零退出给答案的。
|
|
107
|
+
*
|
|
108
|
+
* 绝大多数调用点要的是文本,走下面的 `runGit`;这一层单独暴露只为 `cat-file blob`——它吐的
|
|
109
|
+
* 是图片字节,而 `toString('utf8')` 对非法序列做的是替换不是保留,解码一次就再也拼不回原图。
|
|
107
110
|
*/
|
|
108
|
-
function
|
|
111
|
+
function runGitRaw(args, cwd, options = {}) {
|
|
109
112
|
const limit = Math.min(options.maxStdoutBytes ?? MAX_STDOUT_BYTES, MAX_STDOUT_BYTES);
|
|
110
113
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
111
114
|
const argv = [...GLOBAL_CONFIG, ...args];
|
|
@@ -164,13 +167,22 @@ function runGit(args, cwd, options = {}) {
|
|
|
164
167
|
return;
|
|
165
168
|
}
|
|
166
169
|
resolvePromise({
|
|
167
|
-
stdout: Buffer.concat(out)
|
|
170
|
+
stdout: Buffer.concat(out),
|
|
168
171
|
stderr,
|
|
169
172
|
code
|
|
170
173
|
});
|
|
171
174
|
});
|
|
172
175
|
});
|
|
173
176
|
}
|
|
177
|
+
/** 同 `runGitRaw`,stdout 按 utf8 解码。文本类调用一律走这里。 */
|
|
178
|
+
async function runGit(args, cwd, options = {}) {
|
|
179
|
+
const result = await runGitRaw(args, cwd, options);
|
|
180
|
+
return {
|
|
181
|
+
stdout: result.stdout.toString("utf8"),
|
|
182
|
+
stderr: result.stderr,
|
|
183
|
+
code: result.code
|
|
184
|
+
};
|
|
185
|
+
}
|
|
174
186
|
/** 同上,但非零退出即抛。用于「失败没有第二种解释」的调用点。 */
|
|
175
187
|
async function runGitStrict(args, cwd) {
|
|
176
188
|
const result = await runGit(args, cwd);
|
|
@@ -259,9 +271,9 @@ function repoNameOf(repo) {
|
|
|
259
271
|
return basename(repo.root);
|
|
260
272
|
}
|
|
261
273
|
/**
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
274
|
+
* 正常仓库的基准是 `HEAD`;空仓库(尚无任何提交)下 HEAD 不存在、`git diff HEAD` 会 fatal,
|
|
275
|
+
* 降级为空树哈希(`ref` 与 `oid` 同为它)。不做缓存:`git checkout --orphan` 之后 HEAD 会重新
|
|
276
|
+
* 变回未出生状态,缓存的正结果会让 diff 从此全部 fatal。
|
|
265
277
|
*/
|
|
266
278
|
async function resolveDiffBase(root) {
|
|
267
279
|
const head = await runGit([
|
|
@@ -270,9 +282,17 @@ async function resolveDiffBase(root) {
|
|
|
270
282
|
"--quiet",
|
|
271
283
|
"HEAD"
|
|
272
284
|
], root);
|
|
273
|
-
|
|
285
|
+
const oid = head.stdout.trim();
|
|
286
|
+
if (head.code === 0 && oid) return {
|
|
287
|
+
ref: "HEAD",
|
|
288
|
+
oid
|
|
289
|
+
};
|
|
274
290
|
const format = await runGit(["rev-parse", "--show-object-format"], root);
|
|
275
|
-
|
|
291
|
+
const empty = (format.code === 0 ? format.stdout.trim() : "sha1") === "sha256" ? EMPTY_TREE.sha256 : EMPTY_TREE.sha1;
|
|
292
|
+
return {
|
|
293
|
+
ref: empty,
|
|
294
|
+
oid: empty
|
|
295
|
+
};
|
|
276
296
|
}
|
|
277
297
|
|
|
278
298
|
//#endregion
|
|
@@ -288,6 +308,29 @@ const MAX_BYTES = 5242880;
|
|
|
288
308
|
* 同样会卡。已跟踪那一侧数的是**改动行数**(numstat 的加 + 减),读磁盘这一侧数文件行数。
|
|
289
309
|
*/
|
|
290
310
|
const MAX_LINES = 5e4;
|
|
311
|
+
/**
|
|
312
|
+
* 图片扩展名 → MIME。**图片是二进制里被放行的那一支,判据是「二进制 ∧ 扩展名在表里」**:
|
|
313
|
+
* 二进制那一半由各自的路给(已跟踪侧是 numstat 的 `-\t-`,读磁盘这一侧是 NUL 探测),这张表
|
|
314
|
+
* 只在**已判定为二进制之后**才查——单看扩展名会把一个内容是文本的 `.png`(占位符、被 LFS
|
|
315
|
+
* 换成指针的图)送去 `<img>` 里画成一张破图,而它本来有一份能看的文本 diff。
|
|
316
|
+
*
|
|
317
|
+
* **SVG 刻意不在表里**:它是文本,走文本 diff 更有信息量。表也是 `/api/blob` 的 `Content-Type`
|
|
318
|
+
* 来源——`nosniff` 之下类型错一个字浏览器就不画,所以值必须是精确的 MIME。
|
|
319
|
+
*/
|
|
320
|
+
const IMAGE_MIME = {
|
|
321
|
+
png: "image/png",
|
|
322
|
+
jpg: "image/jpeg",
|
|
323
|
+
jpeg: "image/jpeg",
|
|
324
|
+
gif: "image/gif",
|
|
325
|
+
webp: "image/webp",
|
|
326
|
+
bmp: "image/bmp",
|
|
327
|
+
ico: "image/x-icon",
|
|
328
|
+
avif: "image/avif"
|
|
329
|
+
};
|
|
330
|
+
/** 这条路径按扩展名算图片时给 MIME,否则 `null`。`posix.extname` 对 `.png` 这种点开头的名字给空串。 */
|
|
331
|
+
function imageMimeOf(path) {
|
|
332
|
+
return IMAGE_MIME[posix.extname(path).slice(1).toLowerCase()] ?? null;
|
|
333
|
+
}
|
|
291
334
|
/** 坏请求(路径非法 / 目标不在了)。**不叫 `DiffRequestError`**:三条路都会抛它。 */
|
|
292
335
|
var WorktreeError = class extends Error {
|
|
293
336
|
code;
|
|
@@ -360,7 +403,16 @@ function countLines(buffer) {
|
|
|
360
403
|
return buffer[buffer.length - 1] === 10 ? lines : lines + 1;
|
|
361
404
|
}
|
|
362
405
|
/**
|
|
363
|
-
*
|
|
406
|
+
* 工作区里一份内容的身份:体积 + mtime。**内容身份,不是时间戳**——前端拿它当 `<img>` 的
|
|
407
|
+
* `v=` 与 `key`,不变就不重取;按「取过一次」换戳的写法让每一次无关文件的 SSE 都重下两张图。
|
|
408
|
+
* 与 git 自己的 stat 缓存同一条判据(size + mtime),已知边界也一样:同体积、同一个 mtime
|
|
409
|
+
* 刻度内的改写认不出来,在 APFS / ext4 / NTFS 的纳秒级 mtime 上这是理论形态。
|
|
410
|
+
*/
|
|
411
|
+
function worktreeVersion(info) {
|
|
412
|
+
return `${info.size}-${info.mtimeMs}`;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* 读一个工作区文件并分类。顺序是固定的:符号链接 → 非普通文件 → 体积 → 二进制 → 图片 → 行数。
|
|
364
416
|
*
|
|
365
417
|
* - **`lstat` 而不是 `stat`**:未跟踪的符号链接照样进变更列表、也照样出现在目录树里,而
|
|
366
418
|
* `stat` 跟随链接——校验过的是**链接自身**的路径,读到的却是链接目标。给的因此是**链接
|
|
@@ -368,6 +420,11 @@ function countLines(buffer) {
|
|
|
368
420
|
* - **二进制走 NUL 字节探测**:这条路上没有 numstat 可依(未跟踪与被忽略的文件 git 根本不
|
|
369
421
|
* 比对),而 git 自己那套含 `.gitattributes` 的判定只对已跟踪文件给得出。
|
|
370
422
|
* - **二进制排在行数之前**:它比「太大」更具体,一个 8MB 的 PNG 说「文件过大」等于把原因说错。
|
|
423
|
+
* - **图片只在 NUL 命中之后才查扩展名**(`imageMimeOf`):它是二进制的子集,不是与二进制并列
|
|
424
|
+
* 的一档。与 `text` 一样把 `buffer` 带出去:`/api/blob` 的新侧就是这条链,不另写一份「lstat →
|
|
425
|
+
* 体积 → 读」的副本——上一份副本连 NUL 那道都没有,一个内容是文本的 `.png` 在 payload 里是
|
|
426
|
+
* 文本、在字节端点上却被当图发出去。
|
|
427
|
+
* - **`version` 是这份内容的身份**(`worktreeVersion`),前端拿它决定要不要重取。
|
|
371
428
|
*/
|
|
372
429
|
async function inspectFile(root, path) {
|
|
373
430
|
const { abs } = await resolveInRepo(root, path, { follow: false });
|
|
@@ -388,7 +445,15 @@ async function inspectFile(root, path) {
|
|
|
388
445
|
reason: "size"
|
|
389
446
|
};
|
|
390
447
|
const buffer = await readFile(abs);
|
|
391
|
-
if (buffer.includes(0))
|
|
448
|
+
if (buffer.includes(0)) {
|
|
449
|
+
if (imageMimeOf(path) === null) return { kind: "binary" };
|
|
450
|
+
return {
|
|
451
|
+
kind: "image",
|
|
452
|
+
buffer,
|
|
453
|
+
size: info.size,
|
|
454
|
+
version: worktreeVersion(info)
|
|
455
|
+
};
|
|
456
|
+
}
|
|
392
457
|
const lines = countLines(buffer);
|
|
393
458
|
if (lines > 5e4) return {
|
|
394
459
|
kind: "too-large",
|
|
@@ -404,6 +469,69 @@ async function inspectFile(root, path) {
|
|
|
404
469
|
};
|
|
405
470
|
}
|
|
406
471
|
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region src/server/git/image.ts
|
|
474
|
+
/**
|
|
475
|
+
* `<base>:<path>` 是 revision 语法,不是 pathspec——`GIT_LITERAL_PATHSPECS=1` 管不到它,
|
|
476
|
+
* `./x` 会按相对 cwd 解释、`..` 段则直接不是一个对象名。所以拼进去的必须是 `resolveInRepo`
|
|
477
|
+
* 归一化后的那份(无 `.` 段、无前导 `./`、`/` 分隔),字面量那道边界校验也因此过了一遍。
|
|
478
|
+
*/
|
|
479
|
+
function blobRef(baseRef, normalizedPath) {
|
|
480
|
+
return `${baseRef}:${normalizedPath}`;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* 基准里这个 blob 的字节数;**不存在即 `null`,不是错误**——新增的文件在基准里本来就没有,
|
|
484
|
+
* 基准是空树时更是一个都没有。`path` 必须已经过 `resolveInRepo` 归一化(见 `blobRef`)。
|
|
485
|
+
*/
|
|
486
|
+
async function baseBlobSize(root, baseRef, normalizedPath) {
|
|
487
|
+
const result = await runGit([
|
|
488
|
+
"cat-file",
|
|
489
|
+
"-s",
|
|
490
|
+
blobRef(baseRef, normalizedPath)
|
|
491
|
+
], root);
|
|
492
|
+
if (result.code !== 0) return null;
|
|
493
|
+
const size = Number(result.stdout.trim());
|
|
494
|
+
return Number.isSafeInteger(size) && size >= 0 ? size : null;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* 取一侧的字节。**非图片扩展名一律 400**——不限扩展名的话它就是一个「下载工作区任意文件」
|
|
498
|
+
* 的端点,而 `/api/file` 读任意文本时至少还经过分类链与两道闸。
|
|
499
|
+
*
|
|
500
|
+
* 两侧都再卡一次 5MB(`MAX_BYTES`):payload 已经按侧卡过,但字节是第二次请求,中间文件可以
|
|
501
|
+
* 长大。`new` 侧走 `inspectFile`——与 payload 同一条链,NUL ∧ 扩展名两半都过;`old` 侧带
|
|
502
|
+
* `maxStdoutBytes` 去撞,超限即就地掐断 git。
|
|
503
|
+
*/
|
|
504
|
+
async function readImageBytes(root, path, side) {
|
|
505
|
+
const mime = imageMimeOf(path);
|
|
506
|
+
if (mime === null) throw new WorktreeError("invalid-path", "not an image");
|
|
507
|
+
if (side === "new") {
|
|
508
|
+
const file = await inspectFile(root, path);
|
|
509
|
+
if (file.kind === "too-large") throw new WorktreeError("too-large", "image too large");
|
|
510
|
+
if (file.kind !== "image") throw new WorktreeError("invalid-path", "not an image");
|
|
511
|
+
return {
|
|
512
|
+
buffer: file.buffer,
|
|
513
|
+
mime
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
const [base, { path: normalized }] = await Promise.all([resolveDiffBase(root), resolveInRepo(root, path, { follow: false })]);
|
|
517
|
+
let result;
|
|
518
|
+
try {
|
|
519
|
+
result = await runGitRaw([
|
|
520
|
+
"cat-file",
|
|
521
|
+
"blob",
|
|
522
|
+
blobRef(base.ref, normalized)
|
|
523
|
+
], root, { maxStdoutBytes: MAX_BYTES });
|
|
524
|
+
} catch (cause) {
|
|
525
|
+
if (cause instanceof GitError && cause.kind === "overflow") throw new WorktreeError("too-large", "image too large");
|
|
526
|
+
throw cause;
|
|
527
|
+
}
|
|
528
|
+
if (result.code !== 0) throw new WorktreeError("not-found", "no such file in the diff base");
|
|
529
|
+
return {
|
|
530
|
+
buffer: result.stdout,
|
|
531
|
+
mime
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
407
535
|
//#endregion
|
|
408
536
|
//#region src/server/git/diff.ts
|
|
409
537
|
/** `-z` 输出里是否原样出现这条路径。 */
|
|
@@ -496,14 +624,55 @@ async function readNumstat(root, base, path, oldPath) {
|
|
|
496
624
|
lines: mine.reduce((total, record) => total + record.lines, 0)
|
|
497
625
|
};
|
|
498
626
|
}
|
|
499
|
-
/**
|
|
500
|
-
async function
|
|
627
|
+
/** 工作区里这个文件的 `lstat`;文件不在(删除)就是 `null`。 */
|
|
628
|
+
async function worktreeStat(abs) {
|
|
501
629
|
try {
|
|
502
|
-
return
|
|
630
|
+
return await lstat(abs);
|
|
503
631
|
} catch {
|
|
504
632
|
return null;
|
|
505
633
|
}
|
|
506
634
|
}
|
|
635
|
+
/** 上一条只取体积的形态——三条 `too-large` 分支只要这一个数。 */
|
|
636
|
+
async function worktreeSize(abs) {
|
|
637
|
+
return (await worktreeStat(abs))?.size ?? null;
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* 已跟踪图片的两侧元数据。**判据的二进制那一半是调用方给的(numstat 的 `-\t-`)**,这里只管
|
|
641
|
+
* 扩展名命中之后的事:旧侧问基准(`cat-file -s`,不存在即 `null`——新增、或基准是空树),新侧
|
|
642
|
+
* `lstat` 工作区(不存在即 `null`——已删除)。重命名的旧侧在 `oldPath`,`old.path` 填成它,前端
|
|
643
|
+
* 拿着直接问 `/api/blob`,不自己拼。
|
|
644
|
+
*
|
|
645
|
+
* **`version` 是内容身份,前端拿它决定要不要重取**:旧侧是基准的 oid(`<base>:<path>` 那个 blob
|
|
646
|
+
* 只在基准换了之后才可能变,而 oid 是 `resolveDiffBase` 那次 `rev-parse` 顺手就有的),新侧是
|
|
647
|
+
* 体积 + mtime(`worktreeVersion`)。
|
|
648
|
+
*
|
|
649
|
+
* **5MB 按侧卡**:任一侧超过就整个回 `too-large`——一张 8MB 的 PNG 说「太大」是真话;`size`
|
|
650
|
+
* 取**两侧里大的那个**(取不到给 0):固定报工作区那份时,HEAD 里 8MB 的图被换成 120KB 的,提示
|
|
651
|
+
* 会说「too large (file is 120 KB)」,而 Files 里同一个文件正常显示——自相矛盾。
|
|
652
|
+
*/
|
|
653
|
+
async function imageDiff(root, base, path, abs, oldPath) {
|
|
654
|
+
const basePath = oldPath ?? path;
|
|
655
|
+
const [oldSize, info] = await Promise.all([baseBlobSize(root, base.ref, basePath), worktreeStat(abs)]);
|
|
656
|
+
const largest = Math.max(oldSize ?? 0, info?.size ?? 0);
|
|
657
|
+
if (largest > 5242880) return {
|
|
658
|
+
kind: "too-large",
|
|
659
|
+
size: largest,
|
|
660
|
+
reason: "size"
|
|
661
|
+
};
|
|
662
|
+
return {
|
|
663
|
+
kind: "image",
|
|
664
|
+
old: oldSize === null ? null : {
|
|
665
|
+
path: basePath,
|
|
666
|
+
size: oldSize,
|
|
667
|
+
version: base.oid
|
|
668
|
+
},
|
|
669
|
+
new: info === null ? null : {
|
|
670
|
+
path,
|
|
671
|
+
size: info.size,
|
|
672
|
+
version: worktreeVersion(info)
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
}
|
|
507
676
|
/**
|
|
508
677
|
* 已跟踪文件的补丁,以及三道拒绝。
|
|
509
678
|
*
|
|
@@ -514,7 +683,12 @@ async function worktreeSize(abs) {
|
|
|
514
683
|
*
|
|
515
684
|
* 顺序:二进制(numstat)→ 行数(numstat)→ 取补丁并卡字节。二进制先答是因为它比「太大」
|
|
516
685
|
* 更具体(一个 8MB 的 PNG 说「文件过大」等于把原因说错了);行数排在取补丁之前,是因为它
|
|
517
|
-
* 不用付出取补丁的代价就能拦下 5
|
|
686
|
+
* 不用付出取补丁的代价就能拦下 5 万行以上的改动。二进制里扩展名在表里的那一支放行成
|
|
687
|
+
* `image`(`imageDiff`)——扩展名只在 git 已判定二进制之后才查,单看扩展名会把一个内容是
|
|
688
|
+
* 文本的 `.png` 画成破图。
|
|
689
|
+
*
|
|
690
|
+
* `path` / `oldPath` 是 `resolveInRepo` 归一化后的:图片那一路要把它拼进 `<base>:<path>`,
|
|
691
|
+
* 而那是 revision 语法、不受 `GIT_LITERAL_PATHSPECS` 保护。
|
|
518
692
|
*
|
|
519
693
|
* `size` 只用于**说话**、不再参与判定,所以**只在要拒绝的那两条分支上才去 `lstat`**:
|
|
520
694
|
* 正常那条路一次系统调用都不欠。文件已被删除时取不到,给 0。
|
|
@@ -523,7 +697,7 @@ async function worktreeSize(abs) {
|
|
|
523
697
|
* 重命名退化成一个全新增文件。两个路径都来自 status 的 `2 ` 记录,无需额外查询。
|
|
524
698
|
*/
|
|
525
699
|
async function trackedDiff(root, base, path, abs, oldPath, stat) {
|
|
526
|
-
if (stat?.binary) return { kind: "binary" };
|
|
700
|
+
if (stat?.binary) return imageMimeOf(path) === null ? { kind: "binary" } : imageDiff(root, base, path, abs, oldPath);
|
|
527
701
|
if (stat && stat.lines > 5e4) return {
|
|
528
702
|
kind: "too-large",
|
|
529
703
|
size: await worktreeSize(abs) ?? 0,
|
|
@@ -531,14 +705,14 @@ async function trackedDiff(root, base, path, abs, oldPath, stat) {
|
|
|
531
705
|
};
|
|
532
706
|
const args = oldPath ? [
|
|
533
707
|
"diff",
|
|
534
|
-
base,
|
|
708
|
+
base.ref,
|
|
535
709
|
"-M",
|
|
536
710
|
"--",
|
|
537
711
|
path,
|
|
538
712
|
oldPath
|
|
539
713
|
] : [
|
|
540
714
|
"diff",
|
|
541
|
-
base,
|
|
715
|
+
base.ref,
|
|
542
716
|
"--",
|
|
543
717
|
path
|
|
544
718
|
];
|
|
@@ -586,6 +760,15 @@ async function untrackedDiff(root, path) {
|
|
|
586
760
|
};
|
|
587
761
|
case "binary":
|
|
588
762
|
case "too-large": return file;
|
|
763
|
+
case "image": return {
|
|
764
|
+
kind: "image",
|
|
765
|
+
old: null,
|
|
766
|
+
new: {
|
|
767
|
+
path,
|
|
768
|
+
size: file.size,
|
|
769
|
+
version: file.version
|
|
770
|
+
}
|
|
771
|
+
};
|
|
589
772
|
}
|
|
590
773
|
const head = newFileHeader(path, file.executable ? "100755" : "100644");
|
|
591
774
|
if (file.lines === 0) return {
|
|
@@ -608,12 +791,12 @@ async function untrackedDiff(root, path) {
|
|
|
608
791
|
};
|
|
609
792
|
}
|
|
610
793
|
async function readDiff(root, query) {
|
|
611
|
-
const { abs } = await resolveInRepo(root, query.path, { follow: false });
|
|
612
|
-
|
|
613
|
-
const [base, listed] = await Promise.all([resolveDiffBase(root), inIndex(root,
|
|
614
|
-
const stat = await readNumstat(root, base,
|
|
615
|
-
if (listed || stat !== null) return trackedDiff(root, base,
|
|
616
|
-
return untrackedDiff(root,
|
|
794
|
+
const { abs, path } = await resolveInRepo(root, query.path, { follow: false });
|
|
795
|
+
const oldPath = query.oldPath ? (await resolveInRepo(root, query.oldPath, { follow: false })).path : void 0;
|
|
796
|
+
const [base, listed] = await Promise.all([resolveDiffBase(root), inIndex(root, path)]);
|
|
797
|
+
const stat = await readNumstat(root, base.ref, path, oldPath);
|
|
798
|
+
if (listed || stat !== null) return trackedDiff(root, base, path, abs, oldPath, stat);
|
|
799
|
+
return untrackedDiff(root, path);
|
|
617
800
|
}
|
|
618
801
|
|
|
619
802
|
//#endregion
|
|
@@ -628,6 +811,11 @@ async function readFileContent(root, path) {
|
|
|
628
811
|
};
|
|
629
812
|
case "binary":
|
|
630
813
|
case "too-large": return file;
|
|
814
|
+
case "image": return {
|
|
815
|
+
kind: "image",
|
|
816
|
+
size: file.size,
|
|
817
|
+
version: file.version
|
|
818
|
+
};
|
|
631
819
|
case "text": return {
|
|
632
820
|
kind: "text",
|
|
633
821
|
content: file.buffer.toString("utf8")
|
|
@@ -1904,6 +2092,27 @@ async function startServer(repo, options = {}) {
|
|
|
1904
2092
|
sendJson(res, 200, await readFileContent(repo.root, path));
|
|
1905
2093
|
return;
|
|
1906
2094
|
}
|
|
2095
|
+
/**
|
|
2096
|
+
* 图片字节,**唯一一个正文不是 JSON 的 API 端点**。`path` / `side` 都必填:`old` 是
|
|
2097
|
+
* diff 基准里的 blob、`new` 是工作区那份。只服务图片扩展名表里的路径、`Content-Type`
|
|
2098
|
+
* 按表给精确 MIME(`nosniff` 之下类型错一个字浏览器就不画),非图片一律 400——判据与
|
|
2099
|
+
* 5MB 那道闸都在 git 那侧,这里只把字节发出去。前端加的 `v=` 戳这里不看。
|
|
2100
|
+
*/
|
|
2101
|
+
case "/api/blob": {
|
|
2102
|
+
const path = url.searchParams.get("path");
|
|
2103
|
+
const side = url.searchParams.get("side");
|
|
2104
|
+
if (!path) {
|
|
2105
|
+
sendError(res, 400, "bad-request", "path is required");
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
if (side !== "old" && side !== "new") {
|
|
2109
|
+
sendError(res, 400, "bad-request", "side must be old or new");
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
const image = await readImageBytes(repo.root, path, side);
|
|
2113
|
+
send(res, 200, image.buffer, image.mime);
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
1907
2116
|
/** SSE。**三道校验在上面已经统一走过**,这里没有例外分支。 */
|
|
1908
2117
|
case "/api/events": {
|
|
1909
2118
|
const headers = {
|
package/dist/web/app.css
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid}::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, -apple-system, "Segoe UI", "Noto Sans", "PingFang SC", "Microsoft YaHei", sans-serif;--font-mono:ui-monospace, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--radius-sm:.25rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-editor-background:var(--lightningcss-light,#fff)var(--lightningcss-dark,#1f1f1f);--color-editor-foreground:var(--lightningcss-light,#3b3b3b)var(--lightningcss-dark,#ccc);--color-side-bar-background:var(--lightningcss-light,#f8f8f8)var(--lightningcss-dark,#181818);--color-side-bar-section-header-background:var(--lightningcss-light,#f0f0f0)var(--lightningcss-dark,#202020);--color-title-bar-background:var(--lightningcss-light,#f8f8f8)var(--lightningcss-dark,#181818);--color-panel-border:var(--lightningcss-light,#e5e5e5)var(--lightningcss-dark,#2b2b2b);--color-description-foreground:var(--lightningcss-light,#6f6f6f)var(--lightningcss-dark,#9d9d9d);--color-focus-border:var(--lightningcss-light,#005fb8)var(--lightningcss-dark,#0078d4);--color-text-link-foreground:var(--lightningcss-light,#005fb8)var(--lightningcss-dark,#4daafc);--color-toolbar-hover-background:var(--lightningcss-light,#b8b8b84f)var(--lightningcss-dark,#5a5d5e4f);--color-list-hover-background:var(--lightningcss-light,#e8e8e8)var(--lightningcss-dark,#2a2d2e);--color-list-active-selection-background:var(--lightningcss-light,#e4e6f1)var(--lightningcss-dark,#04395e);--color-list-active-selection-foreground:var(--lightningcss-light,#000)var(--lightningcss-dark,#fff);--color-warning-background:var(--lightningcss-light,#fdf6d3)var(--lightningcss-dark,#352a05);--color-warning-border:#b89500;--color-git-modified:var(--lightningcss-light,#895503)var(--lightningcss-dark,#e2c08d);--color-git-deleted:var(--lightningcss-light,#ad0707)var(--lightningcss-dark,#c74e39);--color-git-added:var(--lightningcss-light,#587c0c)var(--lightningcss-dark,#81b88b);--color-git-untracked:var(--lightningcss-light,#007100)var(--lightningcss-dark,#73c991);--color-git-conflicting:var(--lightningcss-light,#ad0707)var(--lightningcss-dark,#e4676b);--color-diff-inserted-background:#9bb95533;--color-diff-inserted-text-background:#9bb95573;--color-diff-inserted-border:#9bb95580;--color-diff-removed-background:#ff000029;--color-diff-removed-text-background:#ff000052;--color-diff-removed-border:#ff000059;--color-diff-diagonal-fill:var(--lightningcss-light,#0000000f)var(--lightningcss-dark,#ffffff0f)}}@layer base{*,:after,:before{box-sizing:border-box;border:0 solid;margin:0;padding:0}::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}button:not(:disabled){cursor:pointer}*{scrollbar-width:thin}}@layer components;@layer utilities{.absolute{position:absolute}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-y-0{inset-block:0}.top-0{top:0}.right-9\.5{right:calc(var(--spacing) * 9.5)}.left-0{left:0}.z-10{z-index:10}.mt-1{margin-top:var(--spacing)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.scrollbar-none::-webkit-scrollbar{display:none}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.h-screen{height:100vh}.min-h-0{min-height:0}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-max{width:max-content}.max-w-60{max-width:calc(var(--spacing) * 60)}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.scrollbar-none{scrollbar-width:none}.flex-col{flex-direction:column}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.self-center{align-self:center}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:2147483647px}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-editor-foreground{border-color:var(--color-editor-foreground)}.border-panel-border{border-color:var(--color-panel-border)}.border-transparent{border-color:#0000}.border-warning-border{border-color:var(--color-warning-border)}.bg-current{background-color:currentColor}.bg-editor-background{background-color:var(--color-editor-background)}.bg-list-active-selection-background{background-color:var(--color-list-active-selection-background)}.bg-side-bar-background{background-color:var(--color-side-bar-background)}.bg-side-bar-section-header-background{background-color:var(--color-side-bar-section-header-background)}.bg-title-bar-background{background-color:var(--color-title-bar-background)}.bg-warning-background{background-color:var(--color-warning-background)}.stroke-1{stroke-width:1px}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-4{padding:calc(var(--spacing) * 4)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing) * 6)}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\/6{font-size:var(--text-xs);line-height:calc(var(--spacing) * 6)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-description-foreground{color:var(--color-description-foreground)}.text-editor-foreground{color:var(--color-editor-foreground)}.text-git-added{color:var(--color-git-added)}.text-git-conflicting{color:var(--color-git-conflicting)}.text-git-deleted{color:var(--color-git-deleted)}.text-git-modified{color:var(--color-git-modified)}.text-git-untracked{color:var(--color-git-untracked)}.text-list-active-selection-foreground{color:var(--color-list-active-selection-foreground)}.italic{font-style:italic}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.divider-b{box-shadow:inset 0 -1px var(--color-panel-border)}.select-none{-webkit-user-select:none;user-select:none}.group-focus-within\:flex:is(:where(.group):focus-within *){display:flex}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\:flex:is(:where(.group):hover *){display:flex}.group-hover\:bg-list-hover-background:is(:where(.group):hover *){background-color:var(--color-list-hover-background)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:bg-list-hover-background:hover{background-color:var(--color-list-hover-background)}.hover\:bg-toolbar-hover-background:hover{background-color:var(--color-toolbar-hover-background)}}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:calc(2px * -1)}.focus-visible\:outline-focus-border:focus-visible{outline-color:var(--color-focus-border)}}:root{--hljs-fg:var(--lightningcss-light,#24292e)var(--lightningcss-dark,#c9d1d9);--hljs-bg:var(--lightningcss-light,#fff)var(--lightningcss-dark,#0d1117);--hljs-keyword:var(--lightningcss-light,#d73a49)var(--lightningcss-dark,#ff7b72);--hljs-entity:var(--lightningcss-light,#6f42c1)var(--lightningcss-dark,#d2a8ff);--hljs-constant:var(--lightningcss-light,#005cc5)var(--lightningcss-dark,#79c0ff);--hljs-string:var(--lightningcss-light,#032f62)var(--lightningcss-dark,#a5d6ff);--hljs-variable:var(--lightningcss-light,#e36209)var(--lightningcss-dark,#ffa657);--hljs-comment:var(--lightningcss-light,#6a737d)var(--lightningcss-dark,#8b949e);--hljs-entity-tag:var(--lightningcss-light,#22863a)var(--lightningcss-dark,#7ee787);--hljs-heading:var(--lightningcss-light,#005cc5)var(--lightningcss-dark,#1f6feb);--hljs-list:var(--lightningcss-light,#735c0f)var(--lightningcss-dark,#f2cc60);--hljs-inserted:var(--lightningcss-light,#22863a)var(--lightningcss-dark,#aff5b4);--hljs-inserted-bg:var(--lightningcss-light,#f0fff4)var(--lightningcss-dark,#033a16);--hljs-deleted:var(--lightningcss-light,#b31d28)var(--lightningcss-dark,#ffdcd7);--hljs-deleted-bg:var(--lightningcss-light,#ffeef0)var(--lightningcss-dark,#67060c)}.hljs{color:var(--hljs-fg);background:var(--hljs-bg)}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:var(--hljs-keyword)}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:var(--hljs-entity)}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:var(--hljs-constant)}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:var(--hljs-string)}.hljs-built_in,.hljs-symbol{color:var(--hljs-variable)}.hljs-comment,.hljs-code,.hljs-formula{color:var(--hljs-comment)}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:var(--hljs-entity-tag)}.hljs-subst{color:var(--hljs-fg)}.hljs-section{color:var(--hljs-heading);font-weight:700}.hljs-bullet{color:var(--hljs-list)}.hljs-emphasis{color:var(--hljs-fg);font-style:italic}.hljs-strong{color:var(--hljs-fg);font-weight:700}.hljs-addition{color:var(--hljs-inserted);background-color:var(--hljs-inserted-bg)}.hljs-deletion{color:var(--hljs-deleted);background-color:var(--hljs-deleted-bg)}:host,:root{--d2h-bg-color:#fff;--d2h-border-color:#ddd;--d2h-dim-color:#0000004d;--d2h-line-border-color:#eee;--d2h-file-header-bg-color:#f7f7f7;--d2h-file-header-border-color:#d8d8d8;--d2h-empty-placeholder-bg-color:#f1f1f1;--d2h-empty-placeholder-border-color:#e1e1e1;--d2h-selected-color:#c8e1ff;--d2h-ins-bg-color:#dfd;--d2h-ins-border-color:#b4e2b4;--d2h-ins-highlight-bg-color:#97f295;--d2h-ins-label-color:#399839;--d2h-del-bg-color:#fee8e9;--d2h-del-border-color:#e9aeae;--d2h-del-highlight-bg-color:#ffb6ba;--d2h-del-label-color:#c33;--d2h-change-del-color:#fdf2d0;--d2h-change-ins-color:#ded;--d2h-info-bg-color:#f8fafd;--d2h-info-border-color:#d5e4f2;--d2h-change-label-color:#d0b44c;--d2h-moved-label-color:#3572b0;--d2h-dark-color:#e6edf3;--d2h-dark-bg-color:#0d1117;--d2h-dark-border-color:#30363d;--d2h-dark-dim-color:#6e7681;--d2h-dark-line-border-color:#21262d;--d2h-dark-file-header-bg-color:#161b22;--d2h-dark-file-header-border-color:#30363d;--d2h-dark-empty-placeholder-bg-color:#6e76811a;--d2h-dark-empty-placeholder-border-color:#30363d;--d2h-dark-selected-color:#388bfd1a;--d2h-dark-ins-bg-color:#2ea04326;--d2h-dark-ins-border-color:#2ea04366;--d2h-dark-ins-highlight-bg-color:#2ea04366;--d2h-dark-ins-label-color:#3fb950;--d2h-dark-del-bg-color:#f851491a;--d2h-dark-del-border-color:#f8514966;--d2h-dark-del-highlight-bg-color:#f8514966;--d2h-dark-del-label-color:#f85149;--d2h-dark-change-del-color:#d2992233;--d2h-dark-change-ins-color:#2ea04340;--d2h-dark-info-bg-color:#388bfd1a;--d2h-dark-info-border-color:#388bfd66;--d2h-dark-change-label-color:#d29922;--d2h-dark-moved-label-color:#3572b0}.d2h-wrapper{text-align:left}.d2h-file-header{background-color:#f7f7f7;background-color:var(--d2h-file-header-bg-color);border-bottom:1px solid #d8d8d8;border-bottom:1px solid var(--d2h-file-header-border-color);height:35px;padding:5px 10px;font-family:Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;display:flex}.d2h-file-header.d2h-sticky-header{z-index:1;position:sticky;top:0}.d2h-file-stats{margin-left:auto;font-size:14px;display:flex}.d2h-lines-added{border:1px solid #b4e2b4;border:1px solid var(--d2h-ins-border-color);color:var(--d2h-ins-label-color);text-align:right;vertical-align:middle;border-radius:5px 0 0 5px;padding:2px}.d2h-lines-deleted{border:1px solid #e9aeae;border:1px solid var(--d2h-del-border-color);color:var(--d2h-del-label-color);text-align:left;vertical-align:middle;border-radius:0 5px 5px 0;margin-left:1px;padding:2px}.d2h-file-name-wrapper{align-items:center;width:100%;font-size:15px;display:flex}.d2h-file-name{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.d2h-file-wrapper{border:1px solid #ddd;border:1px solid var(--d2h-border-color);border-radius:3px;margin-bottom:1em}.d2h-file-collapse{cursor:pointer;border:1px solid #ddd;border:1px solid var(--d2h-border-color);border-radius:3px;justify-content:flex-end;align-items:center;padding:4px 8px;font-size:12px;display:none}.d2h-file-collapse.d2h-selected{background-color:#c8e1ff;background-color:var(--d2h-selected-color)}.d2h-file-collapse-input{margin:0 4px 0 0}.d2h-diff-table{border-collapse:collapse;width:100%;font-family:Menlo,Consolas,monospace;font-size:13px}.d2h-files-diff{width:100%;display:flex}.d2h-file-diff{overflow-y:hidden}.d2h-file-diff.d2h-d-none,.d2h-files-diff.d2h-d-none{display:none}.d2h-file-side-diff{width:50%;display:inline-block;overflow:scroll hidden}.d2h-code-line{width:calc(100% - 16em);padding:0 8em}.d2h-code-line,.d2h-code-side-line{-webkit-user-select:none;user-select:none;white-space:nowrap;display:inline-block}.d2h-code-side-line{width:calc(100% - 9em);padding:0 4.5em}.d2h-code-line-ctn{word-wrap:normal;-webkit-user-select:text;user-select:text;vertical-align:middle;white-space:pre;background:0 0;width:100%;padding:0;display:inline-block}.d2h-code-line del,.d2h-code-side-line del{background-color:#ffb6ba;background-color:var(--d2h-del-highlight-bg-color)}.d2h-code-line del,.d2h-code-line ins,.d2h-code-side-line del,.d2h-code-side-line ins{border-radius:.2em;margin-top:-1px;-webkit-text-decoration:none;text-decoration:none;display:inline-block}.d2h-code-line ins,.d2h-code-side-line ins{background-color:#97f295;background-color:var(--d2h-ins-highlight-bg-color);text-align:left}.d2h-code-line-prefix{word-wrap:normal;white-space:pre;background:0 0;padding:0;display:inline}.line-num1{float:left}.line-num1,.line-num2{box-sizing:border-box;text-overflow:ellipsis;width:3.5em;padding:0 .5em;overflow:hidden}.line-num2{float:right}.d2h-code-linenumber{background-color:#fff;background-color:var(--d2h-bg-color);border:solid #eee;border:solid var(--d2h-line-border-color);box-sizing:border-box;color:var(--d2h-dim-color);cursor:pointer;text-align:right;border-width:0 1px;width:7.5em;display:inline-block;position:absolute}.d2h-code-linenumber:after{content:""}.d2h-code-side-linenumber{background-color:#fff;background-color:var(--d2h-bg-color);border:solid #eee;border:solid var(--d2h-line-border-color);box-sizing:border-box;color:var(--d2h-dim-color);cursor:pointer;text-align:right;text-overflow:ellipsis;border-width:0 1px;width:4em;padding:0 .5em;display:inline-block;position:absolute;overflow:hidden}.d2h-code-side-linenumber:after{content:""}.d2h-code-side-emptyplaceholder,.d2h-emptyplaceholder{background-color:#f1f1f1;background-color:var(--d2h-empty-placeholder-bg-color);border-color:#e1e1e1;border-color:var(--d2h-empty-placeholder-border-color)}.d2h-code-line-prefix,.d2h-code-linenumber,.d2h-code-side-linenumber,.d2h-emptyplaceholder{-webkit-user-select:none;user-select:none}.d2h-code-linenumber,.d2h-code-side-linenumber{direction:rtl}.d2h-del{background-color:#fee8e9;background-color:var(--d2h-del-bg-color);border-color:#e9aeae;border-color:var(--d2h-del-border-color)}.d2h-ins{background-color:#dfd;background-color:var(--d2h-ins-bg-color);border-color:#b4e2b4;border-color:var(--d2h-ins-border-color)}.d2h-info{background-color:#f8fafd;background-color:var(--d2h-info-bg-color);border-color:#d5e4f2;border-color:var(--d2h-info-border-color);color:var(--d2h-dim-color)}.d2h-file-diff .d2h-del.d2h-change{background-color:#fdf2d0;background-color:var(--d2h-change-del-color)}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded;background-color:var(--d2h-change-ins-color)}.d2h-file-list-wrapper{margin-bottom:10px}.d2h-file-list-wrapper a{-webkit-text-decoration:none;text-decoration:none}.d2h-file-list-wrapper a,.d2h-file-list-wrapper a:visited{color:var(--d2h-moved-label-color)}.d2h-file-list-header{text-align:left}.d2h-file-list-title{font-weight:700}.d2h-file-list-line{text-align:left;display:flex}.d2h-file-list{margin:0;padding:0;list-style:none;display:block}.d2h-file-list>li{border-bottom:1px solid #ddd;border-bottom:1px solid var(--d2h-border-color);margin:0;padding:5px 10px}.d2h-file-list>li:last-child{border-bottom:none}.d2h-file-switch{cursor:pointer;font-size:10px;display:none}.d2h-icon{fill:currentColor;vertical-align:middle;margin-right:10px}.d2h-deleted{color:var(--d2h-del-label-color)}.d2h-added{color:var(--d2h-ins-label-color)}.d2h-changed{color:var(--d2h-change-label-color)}.d2h-moved{color:var(--d2h-moved-label-color)}.d2h-tag{background-color:#fff;background-color:var(--d2h-bg-color);margin-left:5px;padding:0 2px;font-size:10px;display:flex}.d2h-deleted-tag{border:1px solid #c33;border:1px solid var(--d2h-del-label-color)}.d2h-added-tag{border:1px solid #399839;border:1px solid var(--d2h-ins-label-color)}.d2h-changed-tag{border:1px solid #d0b44c;border:1px solid var(--d2h-change-label-color)}.d2h-moved-tag{border:1px solid #3572b0;border:1px solid var(--d2h-moved-label-color)}.d2h-dark-color-scheme{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);color:var(--d2h-dark-color)}.d2h-dark-color-scheme .d2h-file-header{background-color:#161b22;background-color:var(--d2h-dark-file-header-bg-color);border-bottom:#30363d;border-bottom:var(--d2h-dark-file-header-border-color)}.d2h-dark-color-scheme .d2h-lines-added{border:1px solid #2ea04366;border:1px solid var(--d2h-dark-ins-border-color);color:var(--d2h-dark-ins-label-color)}.d2h-dark-color-scheme .d2h-lines-deleted{border:1px solid #f8514966;border:1px solid var(--d2h-dark-del-border-color);color:var(--d2h-dark-del-label-color)}.d2h-dark-color-scheme .d2h-code-line del,.d2h-dark-color-scheme .d2h-code-side-line del{background-color:#f8514966;background-color:var(--d2h-dark-del-highlight-bg-color)}.d2h-dark-color-scheme .d2h-code-line ins,.d2h-dark-color-scheme .d2h-code-side-line ins{background-color:#2ea04366;background-color:var(--d2h-dark-ins-highlight-bg-color)}.d2h-dark-color-scheme .d2h-diff-tbody{border-color:#30363d;border-color:var(--d2h-dark-border-color)}.d2h-dark-color-scheme .d2h-code-side-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-dark-color-scheme .d2h-files-diff .d2h-code-side-emptyplaceholder,.d2h-dark-color-scheme .d2h-files-diff .d2h-emptyplaceholder{background-color:#6e76811a;background-color:var(--d2h-dark-empty-placeholder-bg-color);border-color:#30363d;border-color:var(--d2h-dark-empty-placeholder-border-color)}.d2h-dark-color-scheme .d2h-code-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-dark-color-scheme .d2h-del{background-color:#f851491a;background-color:var(--d2h-dark-del-bg-color);border-color:#f8514966;border-color:var(--d2h-dark-del-border-color)}.d2h-dark-color-scheme .d2h-ins{background-color:#2ea04326;background-color:var(--d2h-dark-ins-bg-color);border-color:#2ea04366;border-color:var(--d2h-dark-ins-border-color)}.d2h-dark-color-scheme .d2h-info{background-color:#388bfd1a;background-color:var(--d2h-dark-info-bg-color);border-color:#388bfd66;border-color:var(--d2h-dark-info-border-color);color:var(--d2h-dark-dim-color)}.d2h-dark-color-scheme .d2h-file-diff .d2h-del.d2h-change{background-color:#d2992233;background-color:var(--d2h-dark-change-del-color)}.d2h-dark-color-scheme .d2h-file-diff .d2h-ins.d2h-change{background-color:#2ea04340;background-color:var(--d2h-dark-change-ins-color)}.d2h-dark-color-scheme .d2h-file-wrapper{border:1px solid #30363d;border:1px solid var(--d2h-dark-border-color)}.d2h-dark-color-scheme .d2h-file-collapse{border:1px solid #0d1117;border:1px solid var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-file-collapse.d2h-selected{background-color:#388bfd1a;background-color:var(--d2h-dark-selected-color)}.d2h-dark-color-scheme .d2h-file-list-wrapper a,.d2h-dark-color-scheme .d2h-file-list-wrapper a:visited{color:var(--d2h-dark-moved-label-color)}.d2h-dark-color-scheme .d2h-file-list>li{border-bottom:1px solid #0d1117;border-bottom:1px solid var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-deleted{color:var(--d2h-dark-del-label-color)}.d2h-dark-color-scheme .d2h-added{color:var(--d2h-dark-ins-label-color)}.d2h-dark-color-scheme .d2h-changed{color:var(--d2h-dark-change-label-color)}.d2h-dark-color-scheme .d2h-moved{color:var(--d2h-dark-moved-label-color)}.d2h-dark-color-scheme .d2h-tag{background-color:#0d1117;background-color:var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-deleted-tag{border:1px solid #f85149;border:1px solid var(--d2h-dark-del-label-color)}.d2h-dark-color-scheme .d2h-added-tag{border:1px solid #3fb950;border:1px solid var(--d2h-dark-ins-label-color)}.d2h-dark-color-scheme .d2h-changed-tag{border:1px solid #d29922;border:1px solid var(--d2h-dark-change-label-color)}.d2h-dark-color-scheme .d2h-moved-tag{border:1px solid #3572b0;border:1px solid var(--d2h-dark-moved-label-color)}@media (prefers-color-scheme:dark){.d2h-auto-color-scheme{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);color:var(--d2h-dark-color)}.d2h-auto-color-scheme .d2h-file-header{background-color:#161b22;background-color:var(--d2h-dark-file-header-bg-color);border-bottom:#30363d;border-bottom:var(--d2h-dark-file-header-border-color)}.d2h-auto-color-scheme .d2h-lines-added{border:1px solid #2ea04366;border:1px solid var(--d2h-dark-ins-border-color);color:var(--d2h-dark-ins-label-color)}.d2h-auto-color-scheme .d2h-lines-deleted{border:1px solid #f8514966;border:1px solid var(--d2h-dark-del-border-color);color:var(--d2h-dark-del-label-color)}.d2h-auto-color-scheme .d2h-code-line del,.d2h-auto-color-scheme .d2h-code-side-line del{background-color:#f8514966;background-color:var(--d2h-dark-del-highlight-bg-color)}.d2h-auto-color-scheme .d2h-code-line ins,.d2h-auto-color-scheme .d2h-code-side-line ins{background-color:#2ea04366;background-color:var(--d2h-dark-ins-highlight-bg-color)}.d2h-auto-color-scheme .d2h-diff-tbody{border-color:#30363d;border-color:var(--d2h-dark-border-color)}.d2h-auto-color-scheme .d2h-code-side-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-auto-color-scheme .d2h-files-diff .d2h-code-side-emptyplaceholder,.d2h-auto-color-scheme .d2h-files-diff .d2h-emptyplaceholder{background-color:#6e76811a;background-color:var(--d2h-dark-empty-placeholder-bg-color);border-color:#30363d;border-color:var(--d2h-dark-empty-placeholder-border-color)}.d2h-auto-color-scheme .d2h-code-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-auto-color-scheme .d2h-del{background-color:#f851491a;background-color:var(--d2h-dark-del-bg-color);border-color:#f8514966;border-color:var(--d2h-dark-del-border-color)}.d2h-auto-color-scheme .d2h-ins{background-color:#2ea04326;background-color:var(--d2h-dark-ins-bg-color);border-color:#2ea04366;border-color:var(--d2h-dark-ins-border-color)}.d2h-auto-color-scheme .d2h-info{background-color:#388bfd1a;background-color:var(--d2h-dark-info-bg-color);border-color:#388bfd66;border-color:var(--d2h-dark-info-border-color);color:var(--d2h-dark-dim-color)}.d2h-auto-color-scheme .d2h-file-diff .d2h-del.d2h-change{background-color:#d2992233;background-color:var(--d2h-dark-change-del-color)}.d2h-auto-color-scheme .d2h-file-diff .d2h-ins.d2h-change{background-color:#2ea04340;background-color:var(--d2h-dark-change-ins-color)}.d2h-auto-color-scheme .d2h-file-wrapper{border:1px solid #30363d;border:1px solid var(--d2h-dark-border-color)}.d2h-auto-color-scheme .d2h-file-collapse{border:1px solid #0d1117;border:1px solid var(--d2h-dark-bg-color)}.d2h-auto-color-scheme .d2h-file-collapse.d2h-selected{background-color:#388bfd1a;background-color:var(--d2h-dark-selected-color)}.d2h-auto-color-scheme .d2h-file-list-wrapper a,.d2h-auto-color-scheme .d2h-file-list-wrapper a:visited{color:var(--d2h-dark-moved-label-color)}.d2h-auto-color-scheme .d2h-file-list>li{border-bottom:1px solid #0d1117;border-bottom:1px solid var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-deleted{color:var(--d2h-dark-del-label-color)}.d2h-auto-color-scheme .d2h-added{color:var(--d2h-dark-ins-label-color)}.d2h-auto-color-scheme .d2h-changed{color:var(--d2h-dark-change-label-color)}.d2h-auto-color-scheme .d2h-moved{color:var(--d2h-dark-moved-label-color)}.d2h-auto-color-scheme .d2h-tag{background-color:#0d1117;background-color:var(--d2h-dark-bg-color)}.d2h-auto-color-scheme .d2h-deleted-tag{border:1px solid #f85149;border:1px solid var(--d2h-dark-del-label-color)}.d2h-auto-color-scheme .d2h-added-tag{border:1px solid #3fb950;border:1px solid var(--d2h-dark-ins-label-color)}.d2h-auto-color-scheme .d2h-changed-tag{border:1px solid #d29922;border:1px solid var(--d2h-dark-change-label-color)}.d2h-auto-color-scheme .d2h-moved-tag{border:1px solid #3572b0;border:1px solid var(--d2h-dark-moved-label-color)}}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}:root[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:root[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:root{--gg-d2h-map:1;--d2h-bg-color:var(--color-editor-background);--d2h-border-color:var(--color-panel-border);--d2h-dim-color:var(--color-description-foreground);--d2h-line-border-color:var(--color-panel-border);--d2h-file-header-bg-color:var(--color-side-bar-section-header-background);--d2h-file-header-border-color:var(--color-panel-border);--d2h-info-bg-color:var(--color-side-bar-background);--d2h-info-border-color:var(--color-panel-border);--d2h-empty-placeholder-bg-color:var(--color-diff-diagonal-fill);--d2h-empty-placeholder-border-color:var(--color-panel-border);--d2h-selected-color:var(--color-list-active-selection-background);--d2h-ins-bg-color:var(--color-diff-inserted-background);--d2h-ins-highlight-bg-color:var(--color-diff-inserted-text-background);--d2h-ins-border-color:var(--color-diff-inserted-border);--d2h-ins-label-color:var(--color-git-added);--d2h-del-bg-color:var(--color-diff-removed-background);--d2h-del-highlight-bg-color:var(--color-diff-removed-text-background);--d2h-del-border-color:var(--color-diff-removed-border);--d2h-del-label-color:var(--color-git-deleted);--d2h-change-del-color:var(--color-diff-removed-background);--d2h-change-ins-color:var(--color-diff-inserted-background);--d2h-change-label-color:var(--color-git-modified);--d2h-moved-label-color:var(--color-text-link-foreground)}body{background-color:var(--color-editor-background);color:var(--color-editor-foreground)}.d2h-diff-table{font-family:var(--font-mono)}.d2h-file-header{display:none}.d2h-file-wrapper{border:none;margin-bottom:0}.d2h-code-linenumber,.d2h-files-diff .d2h-file-side-diff:first-child .d2h-code-side-linenumber{border-left:none}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid}::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, -apple-system, "Segoe UI", "Noto Sans", "PingFang SC", "Microsoft YaHei", sans-serif;--font-mono:ui-monospace, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--radius-sm:.25rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-editor-background:var(--lightningcss-light,#fff)var(--lightningcss-dark,#1f1f1f);--color-editor-foreground:var(--lightningcss-light,#3b3b3b)var(--lightningcss-dark,#ccc);--color-side-bar-background:var(--lightningcss-light,#f8f8f8)var(--lightningcss-dark,#181818);--color-side-bar-section-header-background:var(--lightningcss-light,#f0f0f0)var(--lightningcss-dark,#202020);--color-title-bar-background:var(--lightningcss-light,#f8f8f8)var(--lightningcss-dark,#181818);--color-panel-border:var(--lightningcss-light,#e5e5e5)var(--lightningcss-dark,#2b2b2b);--color-description-foreground:var(--lightningcss-light,#6f6f6f)var(--lightningcss-dark,#9d9d9d);--color-focus-border:var(--lightningcss-light,#005fb8)var(--lightningcss-dark,#0078d4);--color-text-link-foreground:var(--lightningcss-light,#005fb8)var(--lightningcss-dark,#4daafc);--color-toolbar-hover-background:var(--lightningcss-light,#b8b8b84f)var(--lightningcss-dark,#5a5d5e4f);--color-list-hover-background:var(--lightningcss-light,#e8e8e8)var(--lightningcss-dark,#2a2d2e);--color-list-active-selection-background:var(--lightningcss-light,#e4e6f1)var(--lightningcss-dark,#04395e);--color-list-active-selection-foreground:var(--lightningcss-light,#000)var(--lightningcss-dark,#fff);--color-warning-background:var(--lightningcss-light,#fdf6d3)var(--lightningcss-dark,#352a05);--color-warning-border:#b89500;--color-git-modified:var(--lightningcss-light,#895503)var(--lightningcss-dark,#e2c08d);--color-git-deleted:var(--lightningcss-light,#ad0707)var(--lightningcss-dark,#c74e39);--color-git-added:var(--lightningcss-light,#587c0c)var(--lightningcss-dark,#81b88b);--color-git-untracked:var(--lightningcss-light,#007100)var(--lightningcss-dark,#73c991);--color-git-conflicting:var(--lightningcss-light,#ad0707)var(--lightningcss-dark,#e4676b);--color-diff-inserted-background:#9bb95533;--color-diff-inserted-text-background:#9bb95573;--color-diff-inserted-border:#9bb95580;--color-diff-removed-background:#ff000029;--color-diff-removed-text-background:#ff000052;--color-diff-removed-border:#ff000059;--color-diff-diagonal-fill:var(--lightningcss-light,#0000000f)var(--lightningcss-dark,#ffffff0f)}}@layer base{*,:after,:before{box-sizing:border-box;border:0 solid;margin:0;padding:0}::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}button:not(:disabled){cursor:pointer}*{scrollbar-width:thin}}@layer components;@layer utilities{.absolute{position:absolute}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-y-0{inset-block:0}.top-0{top:0}.right-9\.5{right:calc(var(--spacing) * 9.5)}.left-0{left:0}.z-10{z-index:10}.mt-1{margin-top:var(--spacing)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.scrollbar-none::-webkit-scrollbar{display:none}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.h-9{height:calc(var(--spacing) * 9)}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.min-h-0{min-height:0}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-10{width:calc(var(--spacing) * 10)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-max{width:max-content}.max-w-60{max-width:calc(var(--spacing) * 60)}.max-w-64{max-width:calc(var(--spacing) * 64)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.scrollbar-none{scrollbar-width:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.self-center{align-self:center}.self-end{align-self:flex-end}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:2147483647px}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-editor-foreground{border-color:var(--color-editor-foreground)}.border-panel-border{border-color:var(--color-panel-border)}.border-transparent{border-color:#0000}.border-warning-border{border-color:var(--color-warning-border)}.bg-current{background-color:currentColor}.bg-editor-background{background-color:var(--color-editor-background)}.bg-list-active-selection-background{background-color:var(--color-list-active-selection-background)}.bg-side-bar-background{background-color:var(--color-side-bar-background)}.bg-side-bar-section-header-background{background-color:var(--color-side-bar-section-header-background)}.bg-title-bar-background{background-color:var(--color-title-bar-background)}.bg-warning-background{background-color:var(--color-warning-background)}.checkerboard{background-image:repeating-conic-gradient(var(--color-diff-diagonal-fill) 0 25%, transparent 0 50%);background-size:16px 16px}.stroke-1{stroke-width:1px}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-4{padding:calc(var(--spacing) * 4)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing) * 6)}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\/6{font-size:var(--text-xs);line-height:calc(var(--spacing) * 6)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-description-foreground{color:var(--color-description-foreground)}.text-editor-foreground{color:var(--color-editor-foreground)}.text-git-added{color:var(--color-git-added)}.text-git-conflicting{color:var(--color-git-conflicting)}.text-git-deleted{color:var(--color-git-deleted)}.text-git-modified{color:var(--color-git-modified)}.text-git-untracked{color:var(--color-git-untracked)}.text-list-active-selection-foreground{color:var(--color-list-active-selection-foreground)}.italic{font-style:italic}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.divider-b{box-shadow:inset 0 -1px var(--color-panel-border)}.select-none{-webkit-user-select:none;user-select:none}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\:flex:is(:where(.group):hover *){display:flex}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-has-focus-visible\:flex:is(:where(.group):has(:focus-visible) *){display:flex}@media (hover:hover){.hover\:bg-list-hover-background:hover{background-color:var(--color-list-hover-background)}.hover\:bg-toolbar-hover-background:hover{background-color:var(--color-toolbar-hover-background)}}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:calc(2px * -1)}.focus-visible\:outline-focus-border:focus-visible{outline-color:var(--color-focus-border)}@media (pointer:coarse){.pointer-coarse\:flex{display:flex}}.\[\&\>\*\]\:opacity-75>*{opacity:.75}.\[\&\>\*\:focus-visible\]\:opacity-100>:focus-visible,.\[\&\>\*\:hover\]\:opacity-100>:hover{opacity:1}}:root{--hljs-fg:var(--lightningcss-light,#24292e)var(--lightningcss-dark,#c9d1d9);--hljs-bg:var(--lightningcss-light,#fff)var(--lightningcss-dark,#0d1117);--hljs-keyword:var(--lightningcss-light,#d73a49)var(--lightningcss-dark,#ff7b72);--hljs-entity:var(--lightningcss-light,#6f42c1)var(--lightningcss-dark,#d2a8ff);--hljs-constant:var(--lightningcss-light,#005cc5)var(--lightningcss-dark,#79c0ff);--hljs-string:var(--lightningcss-light,#032f62)var(--lightningcss-dark,#a5d6ff);--hljs-variable:var(--lightningcss-light,#e36209)var(--lightningcss-dark,#ffa657);--hljs-comment:var(--lightningcss-light,#6a737d)var(--lightningcss-dark,#8b949e);--hljs-entity-tag:var(--lightningcss-light,#22863a)var(--lightningcss-dark,#7ee787);--hljs-heading:var(--lightningcss-light,#005cc5)var(--lightningcss-dark,#1f6feb);--hljs-list:var(--lightningcss-light,#735c0f)var(--lightningcss-dark,#f2cc60);--hljs-inserted:var(--lightningcss-light,#22863a)var(--lightningcss-dark,#aff5b4);--hljs-inserted-bg:var(--lightningcss-light,#f0fff4)var(--lightningcss-dark,#033a16);--hljs-deleted:var(--lightningcss-light,#b31d28)var(--lightningcss-dark,#ffdcd7);--hljs-deleted-bg:var(--lightningcss-light,#ffeef0)var(--lightningcss-dark,#67060c)}.hljs{color:var(--hljs-fg);background:var(--hljs-bg)}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:var(--hljs-keyword)}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:var(--hljs-entity)}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:var(--hljs-constant)}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:var(--hljs-string)}.hljs-built_in,.hljs-symbol{color:var(--hljs-variable)}.hljs-comment,.hljs-code,.hljs-formula{color:var(--hljs-comment)}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:var(--hljs-entity-tag)}.hljs-subst{color:var(--hljs-fg)}.hljs-section{color:var(--hljs-heading);font-weight:700}.hljs-bullet{color:var(--hljs-list)}.hljs-emphasis{color:var(--hljs-fg);font-style:italic}.hljs-strong{color:var(--hljs-fg);font-weight:700}.hljs-addition{color:var(--hljs-inserted);background-color:var(--hljs-inserted-bg)}.hljs-deletion{color:var(--hljs-deleted);background-color:var(--hljs-deleted-bg)}:host,:root{--d2h-bg-color:#fff;--d2h-border-color:#ddd;--d2h-dim-color:#0000004d;--d2h-line-border-color:#eee;--d2h-file-header-bg-color:#f7f7f7;--d2h-file-header-border-color:#d8d8d8;--d2h-empty-placeholder-bg-color:#f1f1f1;--d2h-empty-placeholder-border-color:#e1e1e1;--d2h-selected-color:#c8e1ff;--d2h-ins-bg-color:#dfd;--d2h-ins-border-color:#b4e2b4;--d2h-ins-highlight-bg-color:#97f295;--d2h-ins-label-color:#399839;--d2h-del-bg-color:#fee8e9;--d2h-del-border-color:#e9aeae;--d2h-del-highlight-bg-color:#ffb6ba;--d2h-del-label-color:#c33;--d2h-change-del-color:#fdf2d0;--d2h-change-ins-color:#ded;--d2h-info-bg-color:#f8fafd;--d2h-info-border-color:#d5e4f2;--d2h-change-label-color:#d0b44c;--d2h-moved-label-color:#3572b0;--d2h-dark-color:#e6edf3;--d2h-dark-bg-color:#0d1117;--d2h-dark-border-color:#30363d;--d2h-dark-dim-color:#6e7681;--d2h-dark-line-border-color:#21262d;--d2h-dark-file-header-bg-color:#161b22;--d2h-dark-file-header-border-color:#30363d;--d2h-dark-empty-placeholder-bg-color:#6e76811a;--d2h-dark-empty-placeholder-border-color:#30363d;--d2h-dark-selected-color:#388bfd1a;--d2h-dark-ins-bg-color:#2ea04326;--d2h-dark-ins-border-color:#2ea04366;--d2h-dark-ins-highlight-bg-color:#2ea04366;--d2h-dark-ins-label-color:#3fb950;--d2h-dark-del-bg-color:#f851491a;--d2h-dark-del-border-color:#f8514966;--d2h-dark-del-highlight-bg-color:#f8514966;--d2h-dark-del-label-color:#f85149;--d2h-dark-change-del-color:#d2992233;--d2h-dark-change-ins-color:#2ea04340;--d2h-dark-info-bg-color:#388bfd1a;--d2h-dark-info-border-color:#388bfd66;--d2h-dark-change-label-color:#d29922;--d2h-dark-moved-label-color:#3572b0}.d2h-wrapper{text-align:left}.d2h-file-header{background-color:#f7f7f7;background-color:var(--d2h-file-header-bg-color);border-bottom:1px solid #d8d8d8;border-bottom:1px solid var(--d2h-file-header-border-color);height:35px;padding:5px 10px;font-family:Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;display:flex}.d2h-file-header.d2h-sticky-header{z-index:1;position:sticky;top:0}.d2h-file-stats{margin-left:auto;font-size:14px;display:flex}.d2h-lines-added{border:1px solid #b4e2b4;border:1px solid var(--d2h-ins-border-color);color:var(--d2h-ins-label-color);text-align:right;vertical-align:middle;border-radius:5px 0 0 5px;padding:2px}.d2h-lines-deleted{border:1px solid #e9aeae;border:1px solid var(--d2h-del-border-color);color:var(--d2h-del-label-color);text-align:left;vertical-align:middle;border-radius:0 5px 5px 0;margin-left:1px;padding:2px}.d2h-file-name-wrapper{align-items:center;width:100%;font-size:15px;display:flex}.d2h-file-name{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.d2h-file-wrapper{border:1px solid #ddd;border:1px solid var(--d2h-border-color);border-radius:3px;margin-bottom:1em}.d2h-file-collapse{cursor:pointer;border:1px solid #ddd;border:1px solid var(--d2h-border-color);border-radius:3px;justify-content:flex-end;align-items:center;padding:4px 8px;font-size:12px;display:none}.d2h-file-collapse.d2h-selected{background-color:#c8e1ff;background-color:var(--d2h-selected-color)}.d2h-file-collapse-input{margin:0 4px 0 0}.d2h-diff-table{border-collapse:collapse;width:100%;font-family:Menlo,Consolas,monospace;font-size:13px}.d2h-files-diff{width:100%;display:flex}.d2h-file-diff{overflow-y:hidden}.d2h-file-diff.d2h-d-none,.d2h-files-diff.d2h-d-none{display:none}.d2h-file-side-diff{width:50%;display:inline-block;overflow:scroll hidden}.d2h-code-line{width:calc(100% - 16em);padding:0 8em}.d2h-code-line,.d2h-code-side-line{-webkit-user-select:none;user-select:none;white-space:nowrap;display:inline-block}.d2h-code-side-line{width:calc(100% - 9em);padding:0 4.5em}.d2h-code-line-ctn{word-wrap:normal;-webkit-user-select:text;user-select:text;vertical-align:middle;white-space:pre;background:0 0;width:100%;padding:0;display:inline-block}.d2h-code-line del,.d2h-code-side-line del{background-color:#ffb6ba;background-color:var(--d2h-del-highlight-bg-color)}.d2h-code-line del,.d2h-code-line ins,.d2h-code-side-line del,.d2h-code-side-line ins{border-radius:.2em;margin-top:-1px;-webkit-text-decoration:none;text-decoration:none;display:inline-block}.d2h-code-line ins,.d2h-code-side-line ins{background-color:#97f295;background-color:var(--d2h-ins-highlight-bg-color);text-align:left}.d2h-code-line-prefix{word-wrap:normal;white-space:pre;background:0 0;padding:0;display:inline}.line-num1{float:left}.line-num1,.line-num2{box-sizing:border-box;text-overflow:ellipsis;width:3.5em;padding:0 .5em;overflow:hidden}.line-num2{float:right}.d2h-code-linenumber{background-color:#fff;background-color:var(--d2h-bg-color);border:solid #eee;border:solid var(--d2h-line-border-color);box-sizing:border-box;color:var(--d2h-dim-color);cursor:pointer;text-align:right;border-width:0 1px;width:7.5em;display:inline-block;position:absolute}.d2h-code-linenumber:after{content:""}.d2h-code-side-linenumber{background-color:#fff;background-color:var(--d2h-bg-color);border:solid #eee;border:solid var(--d2h-line-border-color);box-sizing:border-box;color:var(--d2h-dim-color);cursor:pointer;text-align:right;text-overflow:ellipsis;border-width:0 1px;width:4em;padding:0 .5em;display:inline-block;position:absolute;overflow:hidden}.d2h-code-side-linenumber:after{content:""}.d2h-code-side-emptyplaceholder,.d2h-emptyplaceholder{background-color:#f1f1f1;background-color:var(--d2h-empty-placeholder-bg-color);border-color:#e1e1e1;border-color:var(--d2h-empty-placeholder-border-color)}.d2h-code-line-prefix,.d2h-code-linenumber,.d2h-code-side-linenumber,.d2h-emptyplaceholder{-webkit-user-select:none;user-select:none}.d2h-code-linenumber,.d2h-code-side-linenumber{direction:rtl}.d2h-del{background-color:#fee8e9;background-color:var(--d2h-del-bg-color);border-color:#e9aeae;border-color:var(--d2h-del-border-color)}.d2h-ins{background-color:#dfd;background-color:var(--d2h-ins-bg-color);border-color:#b4e2b4;border-color:var(--d2h-ins-border-color)}.d2h-info{background-color:#f8fafd;background-color:var(--d2h-info-bg-color);border-color:#d5e4f2;border-color:var(--d2h-info-border-color);color:var(--d2h-dim-color)}.d2h-file-diff .d2h-del.d2h-change{background-color:#fdf2d0;background-color:var(--d2h-change-del-color)}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded;background-color:var(--d2h-change-ins-color)}.d2h-file-list-wrapper{margin-bottom:10px}.d2h-file-list-wrapper a{-webkit-text-decoration:none;text-decoration:none}.d2h-file-list-wrapper a,.d2h-file-list-wrapper a:visited{color:var(--d2h-moved-label-color)}.d2h-file-list-header{text-align:left}.d2h-file-list-title{font-weight:700}.d2h-file-list-line{text-align:left;display:flex}.d2h-file-list{margin:0;padding:0;list-style:none;display:block}.d2h-file-list>li{border-bottom:1px solid #ddd;border-bottom:1px solid var(--d2h-border-color);margin:0;padding:5px 10px}.d2h-file-list>li:last-child{border-bottom:none}.d2h-file-switch{cursor:pointer;font-size:10px;display:none}.d2h-icon{fill:currentColor;vertical-align:middle;margin-right:10px}.d2h-deleted{color:var(--d2h-del-label-color)}.d2h-added{color:var(--d2h-ins-label-color)}.d2h-changed{color:var(--d2h-change-label-color)}.d2h-moved{color:var(--d2h-moved-label-color)}.d2h-tag{background-color:#fff;background-color:var(--d2h-bg-color);margin-left:5px;padding:0 2px;font-size:10px;display:flex}.d2h-deleted-tag{border:1px solid #c33;border:1px solid var(--d2h-del-label-color)}.d2h-added-tag{border:1px solid #399839;border:1px solid var(--d2h-ins-label-color)}.d2h-changed-tag{border:1px solid #d0b44c;border:1px solid var(--d2h-change-label-color)}.d2h-moved-tag{border:1px solid #3572b0;border:1px solid var(--d2h-moved-label-color)}.d2h-dark-color-scheme{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);color:var(--d2h-dark-color)}.d2h-dark-color-scheme .d2h-file-header{background-color:#161b22;background-color:var(--d2h-dark-file-header-bg-color);border-bottom:#30363d;border-bottom:var(--d2h-dark-file-header-border-color)}.d2h-dark-color-scheme .d2h-lines-added{border:1px solid #2ea04366;border:1px solid var(--d2h-dark-ins-border-color);color:var(--d2h-dark-ins-label-color)}.d2h-dark-color-scheme .d2h-lines-deleted{border:1px solid #f8514966;border:1px solid var(--d2h-dark-del-border-color);color:var(--d2h-dark-del-label-color)}.d2h-dark-color-scheme .d2h-code-line del,.d2h-dark-color-scheme .d2h-code-side-line del{background-color:#f8514966;background-color:var(--d2h-dark-del-highlight-bg-color)}.d2h-dark-color-scheme .d2h-code-line ins,.d2h-dark-color-scheme .d2h-code-side-line ins{background-color:#2ea04366;background-color:var(--d2h-dark-ins-highlight-bg-color)}.d2h-dark-color-scheme .d2h-diff-tbody{border-color:#30363d;border-color:var(--d2h-dark-border-color)}.d2h-dark-color-scheme .d2h-code-side-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-dark-color-scheme .d2h-files-diff .d2h-code-side-emptyplaceholder,.d2h-dark-color-scheme .d2h-files-diff .d2h-emptyplaceholder{background-color:#6e76811a;background-color:var(--d2h-dark-empty-placeholder-bg-color);border-color:#30363d;border-color:var(--d2h-dark-empty-placeholder-border-color)}.d2h-dark-color-scheme .d2h-code-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-dark-color-scheme .d2h-del{background-color:#f851491a;background-color:var(--d2h-dark-del-bg-color);border-color:#f8514966;border-color:var(--d2h-dark-del-border-color)}.d2h-dark-color-scheme .d2h-ins{background-color:#2ea04326;background-color:var(--d2h-dark-ins-bg-color);border-color:#2ea04366;border-color:var(--d2h-dark-ins-border-color)}.d2h-dark-color-scheme .d2h-info{background-color:#388bfd1a;background-color:var(--d2h-dark-info-bg-color);border-color:#388bfd66;border-color:var(--d2h-dark-info-border-color);color:var(--d2h-dark-dim-color)}.d2h-dark-color-scheme .d2h-file-diff .d2h-del.d2h-change{background-color:#d2992233;background-color:var(--d2h-dark-change-del-color)}.d2h-dark-color-scheme .d2h-file-diff .d2h-ins.d2h-change{background-color:#2ea04340;background-color:var(--d2h-dark-change-ins-color)}.d2h-dark-color-scheme .d2h-file-wrapper{border:1px solid #30363d;border:1px solid var(--d2h-dark-border-color)}.d2h-dark-color-scheme .d2h-file-collapse{border:1px solid #0d1117;border:1px solid var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-file-collapse.d2h-selected{background-color:#388bfd1a;background-color:var(--d2h-dark-selected-color)}.d2h-dark-color-scheme .d2h-file-list-wrapper a,.d2h-dark-color-scheme .d2h-file-list-wrapper a:visited{color:var(--d2h-dark-moved-label-color)}.d2h-dark-color-scheme .d2h-file-list>li{border-bottom:1px solid #0d1117;border-bottom:1px solid var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-deleted{color:var(--d2h-dark-del-label-color)}.d2h-dark-color-scheme .d2h-added{color:var(--d2h-dark-ins-label-color)}.d2h-dark-color-scheme .d2h-changed{color:var(--d2h-dark-change-label-color)}.d2h-dark-color-scheme .d2h-moved{color:var(--d2h-dark-moved-label-color)}.d2h-dark-color-scheme .d2h-tag{background-color:#0d1117;background-color:var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-deleted-tag{border:1px solid #f85149;border:1px solid var(--d2h-dark-del-label-color)}.d2h-dark-color-scheme .d2h-added-tag{border:1px solid #3fb950;border:1px solid var(--d2h-dark-ins-label-color)}.d2h-dark-color-scheme .d2h-changed-tag{border:1px solid #d29922;border:1px solid var(--d2h-dark-change-label-color)}.d2h-dark-color-scheme .d2h-moved-tag{border:1px solid #3572b0;border:1px solid var(--d2h-dark-moved-label-color)}@media (prefers-color-scheme:dark){.d2h-auto-color-scheme{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);color:var(--d2h-dark-color)}.d2h-auto-color-scheme .d2h-file-header{background-color:#161b22;background-color:var(--d2h-dark-file-header-bg-color);border-bottom:#30363d;border-bottom:var(--d2h-dark-file-header-border-color)}.d2h-auto-color-scheme .d2h-lines-added{border:1px solid #2ea04366;border:1px solid var(--d2h-dark-ins-border-color);color:var(--d2h-dark-ins-label-color)}.d2h-auto-color-scheme .d2h-lines-deleted{border:1px solid #f8514966;border:1px solid var(--d2h-dark-del-border-color);color:var(--d2h-dark-del-label-color)}.d2h-auto-color-scheme .d2h-code-line del,.d2h-auto-color-scheme .d2h-code-side-line del{background-color:#f8514966;background-color:var(--d2h-dark-del-highlight-bg-color)}.d2h-auto-color-scheme .d2h-code-line ins,.d2h-auto-color-scheme .d2h-code-side-line ins{background-color:#2ea04366;background-color:var(--d2h-dark-ins-highlight-bg-color)}.d2h-auto-color-scheme .d2h-diff-tbody{border-color:#30363d;border-color:var(--d2h-dark-border-color)}.d2h-auto-color-scheme .d2h-code-side-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-auto-color-scheme .d2h-files-diff .d2h-code-side-emptyplaceholder,.d2h-auto-color-scheme .d2h-files-diff .d2h-emptyplaceholder{background-color:#6e76811a;background-color:var(--d2h-dark-empty-placeholder-bg-color);border-color:#30363d;border-color:var(--d2h-dark-empty-placeholder-border-color)}.d2h-auto-color-scheme .d2h-code-linenumber{background-color:#0d1117;background-color:var(--d2h-dark-bg-color);border-color:#21262d;border-color:var(--d2h-dark-line-border-color);color:var(--d2h-dark-dim-color)}.d2h-auto-color-scheme .d2h-del{background-color:#f851491a;background-color:var(--d2h-dark-del-bg-color);border-color:#f8514966;border-color:var(--d2h-dark-del-border-color)}.d2h-auto-color-scheme .d2h-ins{background-color:#2ea04326;background-color:var(--d2h-dark-ins-bg-color);border-color:#2ea04366;border-color:var(--d2h-dark-ins-border-color)}.d2h-auto-color-scheme .d2h-info{background-color:#388bfd1a;background-color:var(--d2h-dark-info-bg-color);border-color:#388bfd66;border-color:var(--d2h-dark-info-border-color);color:var(--d2h-dark-dim-color)}.d2h-auto-color-scheme .d2h-file-diff .d2h-del.d2h-change{background-color:#d2992233;background-color:var(--d2h-dark-change-del-color)}.d2h-auto-color-scheme .d2h-file-diff .d2h-ins.d2h-change{background-color:#2ea04340;background-color:var(--d2h-dark-change-ins-color)}.d2h-auto-color-scheme .d2h-file-wrapper{border:1px solid #30363d;border:1px solid var(--d2h-dark-border-color)}.d2h-auto-color-scheme .d2h-file-collapse{border:1px solid #0d1117;border:1px solid var(--d2h-dark-bg-color)}.d2h-auto-color-scheme .d2h-file-collapse.d2h-selected{background-color:#388bfd1a;background-color:var(--d2h-dark-selected-color)}.d2h-auto-color-scheme .d2h-file-list-wrapper a,.d2h-auto-color-scheme .d2h-file-list-wrapper a:visited{color:var(--d2h-dark-moved-label-color)}.d2h-auto-color-scheme .d2h-file-list>li{border-bottom:1px solid #0d1117;border-bottom:1px solid var(--d2h-dark-bg-color)}.d2h-dark-color-scheme .d2h-deleted{color:var(--d2h-dark-del-label-color)}.d2h-auto-color-scheme .d2h-added{color:var(--d2h-dark-ins-label-color)}.d2h-auto-color-scheme .d2h-changed{color:var(--d2h-dark-change-label-color)}.d2h-auto-color-scheme .d2h-moved{color:var(--d2h-dark-moved-label-color)}.d2h-auto-color-scheme .d2h-tag{background-color:#0d1117;background-color:var(--d2h-dark-bg-color)}.d2h-auto-color-scheme .d2h-deleted-tag{border:1px solid #f85149;border:1px solid var(--d2h-dark-del-label-color)}.d2h-auto-color-scheme .d2h-added-tag{border:1px solid #3fb950;border:1px solid var(--d2h-dark-ins-label-color)}.d2h-auto-color-scheme .d2h-changed-tag{border:1px solid #d29922;border:1px solid var(--d2h-dark-change-label-color)}.d2h-auto-color-scheme .d2h-moved-tag{border:1px solid #3572b0;border:1px solid var(--d2h-dark-moved-label-color)}}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}:root[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:root[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:root{--gg-d2h-map:1;--d2h-bg-color:var(--color-editor-background);--d2h-border-color:var(--color-panel-border);--d2h-dim-color:var(--color-description-foreground);--d2h-line-border-color:var(--color-panel-border);--d2h-file-header-bg-color:var(--color-side-bar-section-header-background);--d2h-file-header-border-color:var(--color-panel-border);--d2h-info-bg-color:var(--color-side-bar-background);--d2h-info-border-color:var(--color-panel-border);--d2h-empty-placeholder-bg-color:var(--color-diff-diagonal-fill);--d2h-empty-placeholder-border-color:var(--color-panel-border);--d2h-selected-color:var(--color-list-active-selection-background);--d2h-ins-bg-color:var(--color-diff-inserted-background);--d2h-ins-highlight-bg-color:var(--color-diff-inserted-text-background);--d2h-ins-border-color:var(--color-diff-inserted-border);--d2h-ins-label-color:var(--color-git-added);--d2h-del-bg-color:var(--color-diff-removed-background);--d2h-del-highlight-bg-color:var(--color-diff-removed-text-background);--d2h-del-border-color:var(--color-diff-removed-border);--d2h-del-label-color:var(--color-git-deleted);--d2h-change-del-color:var(--color-diff-removed-background);--d2h-change-ins-color:var(--color-diff-inserted-background);--d2h-change-label-color:var(--color-git-modified);--d2h-moved-label-color:var(--color-text-link-foreground)}body{background-color:var(--color-editor-background);color:var(--color-editor-foreground)}.d2h-diff-table{font-family:var(--font-mono)}.d2h-file-header{display:none}.d2h-file-wrapper{border:none;margin-bottom:0}.d2h-code-linenumber,.d2h-files-diff .d2h-file-side-diff:first-child .d2h-code-side-linenumber{border-left:none}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
|
3
3
|
/*$vite$:1*/
|