+83
-51
bun.lock
+83
-51
bun.lock
···
5
5
"name": "atproto-backup",
6
6
"dependencies": {
7
7
"@atcute/car": "^3.1.1",
8
-
"@atproto/api": "^0.15.25",
8
+
"@atproto/api": "^0.15.26",
9
9
"@atproto/jwk-webcrypto": "^0.1.9",
10
10
"@atproto/oauth-client-browser": "^0.3.27",
11
11
"@radix-ui/react-avatar": "^1.1.10",
12
12
"@radix-ui/react-checkbox": "^1.3.2",
13
+
"@radix-ui/react-dialog": "^1.1.14",
13
14
"@radix-ui/react-dropdown-menu": "^2.1.15",
14
15
"@radix-ui/react-label": "^2.1.7",
15
16
"@radix-ui/react-progress": "^1.1.7",
···
18
19
"@radix-ui/react-switch": "^1.2.5",
19
20
"@radix-ui/react-tooltip": "^1.2.7",
20
21
"@tailwindcss/vite": "^4.1.11",
21
-
"@tauri-apps/api": "^2",
22
-
"@tauri-apps/plugin-autostart": "~2",
23
-
"@tauri-apps/plugin-deep-link": "~2",
24
-
"@tauri-apps/plugin-fs": "~2",
25
-
"@tauri-apps/plugin-opener": "^2",
26
-
"@tauri-apps/plugin-process": "~2",
27
-
"@tauri-apps/plugin-shell": "~2",
28
-
"@tauri-apps/plugin-store": "~2",
29
-
"@tauri-apps/plugin-updater": "~2",
30
-
"@tauri-apps/plugin-websocket": "~2",
31
-
"antd": "^5.26.4",
22
+
"@tauri-apps/api": "^2.6.0",
23
+
"@tauri-apps/plugin-autostart": "~2.5.0",
24
+
"@tauri-apps/plugin-deep-link": "~2.4.0",
25
+
"@tauri-apps/plugin-fs": "~2.4.0",
26
+
"@tauri-apps/plugin-opener": "^2.4.0",
27
+
"@tauri-apps/plugin-process": "~2.3.0",
28
+
"@tauri-apps/plugin-shell": "~2.3.0",
29
+
"@tauri-apps/plugin-store": "~2.3.0",
30
+
"@tauri-apps/plugin-updater": "~2.9.0",
31
+
"@tauri-apps/plugin-websocket": "~2.4.0",
32
+
"antd": "^5.26.6",
32
33
"class-variance-authority": "^0.7.1",
33
34
"clsx": "^2.1.1",
34
35
"lucide-react": "^0.525.0",
35
-
"next": "^15.3.5",
36
+
"next": "^15.4.2",
36
37
"next-themes": "^0.4.6",
37
38
"nextra": "^4.2.17",
38
39
"nextra-theme-docs": "^4.2.17",
39
40
"react": "^19.1.0",
40
41
"react-dom": "^19.1.0",
41
-
"shadcn": "^2.9.0",
42
+
"react-markdown": "^10.1.0",
43
+
"remark-gfm": "^4.0.1",
44
+
"shadcn": "^2.9.2",
45
+
"shiki": "^3.8.1",
42
46
"sonner": "^2.0.6",
43
47
"tailwind-merge": "^3.3.1",
44
48
"tailwindcss": "^4.1.11",
45
49
},
46
50
"devDependencies": {
47
-
"@tauri-apps/cli": "^2",
48
-
"@types/node": "^24.0.13",
49
-
"@types/react": "^18.3.1",
50
-
"@types/react-dom": "^18.3.1",
51
-
"@vitejs/plugin-react": "^4.3.4",
51
+
"@tauri-apps/cli": "^2.6.2",
52
+
"@types/node": "^24.0.15",
53
+
"@types/react": "^18.3.23",
54
+
"@types/react-dom": "^18.3.7",
55
+
"@vitejs/plugin-react": "^4.7.0",
52
56
"tw-animate-css": "^1.3.5",
53
-
"typescript": "~5.6.2",
54
-
"vite": "^6.0.3",
57
+
"typescript": "~5.6.3",
58
+
"vite": "^6.3.5",
55
59
},
56
60
},
57
61
},
···
107
111
108
112
"@atproto-labs/simple-store-memory": ["@atproto-labs/simple-store-memory@0.1.3", "", { "dependencies": { "@atproto-labs/simple-store": "0.2.0", "lru-cache": "^10.2.0" } }, "sha512-jkitT9+AtU+0b28DoN92iURLaCt/q/q4yX8q6V+9LSwYlUTqKoj/5NFKvF7x6EBuG+gpUdlcycbH7e60gjOhRQ=="],
109
113
110
-
"@atproto/api": ["@atproto/api@0.15.25", "", { "dependencies": { "@atproto/common-web": "^0.4.2", "@atproto/lexicon": "^0.4.12", "@atproto/syntax": "^0.4.0", "@atproto/xrpc": "^0.7.1", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-dUqe920qyXd596AI5iJyBlSv0vK5fh1a8PC0zPoeM+FzGDiebnbxuJdPIZ3HeBT/xQ2ce9HwYk1Ih2G7a+JkzQ=="],
114
+
"@atproto/api": ["@atproto/api@0.15.26", "", { "dependencies": { "@atproto/common-web": "^0.4.2", "@atproto/lexicon": "^0.4.12", "@atproto/syntax": "^0.4.0", "@atproto/xrpc": "^0.7.1", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-AdXGjeCpLZiP9YMGi4YOdK1ayqkBhklmGfSG8UefqR6tTHth59PZvYs5KiwLnFhedt2Xljt3eUlhkn14Y48wEA=="],
111
115
112
116
"@atproto/common-web": ["@atproto/common-web@0.4.2", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw=="],
113
117
···
381
385
382
386
"@napi-rs/simple-git-win32-x64-msvc": ["@napi-rs/simple-git-win32-x64-msvc@0.1.19", "", { "os": "win32", "cpu": "x64" }, "sha512-FmNuPoK4+qwaSCkp8lm3sJlrxk374enW+zCE5ZksXlZzj/9BDJAULJb5QUJ7o9Y8A/G+d8LkdQLPBE2Jaxe5XA=="],
383
387
384
-
"@next/env": ["@next/env@15.3.5", "", {}, "sha512-7g06v8BUVtN2njAX/r8gheoVffhiKFVt4nx74Tt6G4Hqw9HCLYQVx/GkH2qHvPtAHZaUNZ0VXAa0pQP6v1wk7g=="],
388
+
"@next/env": ["@next/env@15.4.2", "", {}, "sha512-kd7MvW3pAP7tmk1NaiX4yG15xb2l4gNhteKQxt3f+NGR22qwPymn9RBuv26QKfIKmfo6z2NpgU8W2RT0s0jlvg=="],
385
389
386
-
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.3.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lM/8tilIsqBq+2nq9kbTW19vfwFve0NR7MxfkuSUbRSgXlMQoJYg+31+++XwKVSXk4uT23G2eF/7BRIKdn8t8w=="],
390
+
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.4.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ovqjR8NjCBdBf1U+R/Gvn0RazTtXS9n6wqs84iFaCS1NHbw9ksVE4dfmsYcLoyUVd9BWE0bjkphOWrrz8uz/uw=="],
387
391
388
-
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.3.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-WhwegPQJ5IfoUNZUVsI9TRAlKpjGVK0tpJTL6KeiC4cux9774NYE9Wu/iCfIkL/5J8rPAkqZpG7n+EfiAfidXA=="],
392
+
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.4.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-I8d4W7tPqbdbHRI4z1iBfaoJIBrEG4fnWKIe+Rj1vIucNZ5cEinfwkBt3RcDF00bFRZRDpvKuDjgMFD3OyRBnw=="],
389
393
390
-
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.3.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-LVD6uMOZ7XePg3KWYdGuzuvVboxujGjbcuP2jsPAN3MnLdLoZUXKRc6ixxfs03RH7qBdEHCZjyLP/jBdCJVRJQ=="],
394
+
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.4.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-lvhz02dU3Ec5thzfQ2RCUeOFADjNkS/px1W7MBt7HMhf0/amMfT8Z/aXOwEA+cVWN7HSDRSUc8hHILoHmvajsg=="],
391
395
392
-
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.3.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-k8aVScYZ++BnS2P69ClK7v4nOu702jcF9AIHKu6llhHEtBSmM2zkPGl9yoqbSU/657IIIb0QHpdxEr0iW9z53A=="],
396
+
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.4.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-v+5PPfL8UP+KKHS3Mox7QMoeFdMlaV0zeNMIF7eLC4qTiVSO0RPNnK0nkBZSD5BEkkf//c+vI9s/iHxddCZchA=="],
393
397
394
-
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.3.5", "", { "os": "linux", "cpu": "x64" }, "sha512-2xYU0DI9DGN/bAHzVwADid22ba5d/xrbrQlr2U+/Q5WkFUzeL0TDR963BdrtLS/4bMmKZGptLeg6282H/S2i8A=="],
398
+
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.4.2", "", { "os": "linux", "cpu": "x64" }, "sha512-PHLYOC9W2cu6I/JEKo77+LW4uPNvyEQiSkVRUQPsOIsf01PRr8PtPhwtz3XNnC9At8CrzPkzqQ9/kYDg4R4Inw=="],
395
399
396
-
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.3.5", "", { "os": "linux", "cpu": "x64" }, "sha512-TRYIqAGf1KCbuAB0gjhdn5Ytd8fV+wJSM2Nh2is/xEqR8PZHxfQuaiNhoF50XfY90sNpaRMaGhF6E+qjV1b9Tg=="],
400
+
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.4.2", "", { "os": "linux", "cpu": "x64" }, "sha512-lpmUF9FfLFns4JbTu+5aJGA8aR9dXaA12eoNe9CJbVkGib0FDiPa4kBGTwy0xDxKNGlv3bLDViyx1U+qafmuJQ=="],
397
401
398
-
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.3.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-h04/7iMEUSMY6fDGCvdanKqlO1qYvzNxntZlCzfE8i5P0uqzVQWQquU1TIhlz0VqGQGXLrFDuTJVONpqGqjGKQ=="],
402
+
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.4.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-aMjogoGnRepas0LQ/PBPsvvUzj+IoXw2IoDSEShEtrsu2toBiaxEWzOQuPZ8nie8+1iF7TA63S7rlp3YWAjNEg=="],
399
403
400
-
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.3.5", "", { "os": "win32", "cpu": "x64" }, "sha512-5fhH6fccXxnX2KhllnGhkYMndhOiLOLEiVGYjP2nizqeGWkN10sA9taATlXwake2E2XMvYZjjz0Uj7T0y+z1yw=="],
404
+
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.4.2", "", { "os": "win32", "cpu": "x64" }, "sha512-FxwauyexSFu78wEqR/+NB9MnqXVj6SxJKwcVs2CRjeSX/jBagDCgtR2W36PZUYm0WPgY1pQ3C1+nn7zSnwROuw=="],
401
405
402
406
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
403
407
···
427
431
428
432
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
429
433
434
+
"@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-focus-guards": "1.1.2", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw=="],
435
+
430
436
"@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
431
437
432
438
"@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ=="],
···
517
523
518
524
"@react-types/shared": ["@react-types/shared@3.30.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-COIazDAx1ncDg046cTJ8SFYsX8aS3lB/08LDnbkH/SkdYrFPWDlXMrO/sUam8j1WWM+PJ+4d1mj7tODIKNiFog=="],
519
525
520
-
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.19", "", {}, "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA=="],
526
+
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
521
527
522
528
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.45.0", "", { "os": "android", "cpu": "arm" }, "sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg=="],
523
529
···
559
565
560
566
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.45.0", "", { "os": "win32", "cpu": "x64" }, "sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA=="],
561
567
562
-
"@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="],
568
+
"@shikijs/core": ["@shikijs/core@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-uTSXzUBQ/IgFcUa6gmGShCHr4tMdR3pxUiiWKDm8pd42UKJdYhkAYsAmHX5mTwybQ5VyGDgTjW4qKSsRvGSang=="],
563
569
564
-
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="],
570
+
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-rZRp3BM1llrHkuBPAdYAzjlF7OqlM0rm/7EWASeCcY7cRYZIrOnGIHE9qsLz5TCjGefxBFnwgIECzBs2vmOyKA=="],
565
571
566
-
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="],
572
+
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-KGQJZHlNY7c656qPFEQpIoqOuC4LrxjyNndRdzk5WKB/Ie87+NJCF1xo9KkOUxwxylk7rT6nhlZyTGTC4fCe1g=="],
567
573
568
-
"@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="],
574
+
"@shikijs/langs": ["@shikijs/langs@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1" } }, "sha512-TjOFg2Wp1w07oKnXjs0AUMb4kJvujML+fJ1C5cmEj45lhjbUXtziT1x2bPQb9Db6kmPhkG5NI2tgYW1/DzhUuQ=="],
569
575
570
-
"@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="],
576
+
"@shikijs/themes": ["@shikijs/themes@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1" } }, "sha512-Vu3t3BBLifc0GB0UPg2Pox1naTemrrvyZv2lkiSw3QayVV60me1ujFQwPZGgUTmwXl1yhCPW8Lieesm0CYruLQ=="],
571
577
572
578
"@shikijs/twoslash": ["@shikijs/twoslash@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0", "twoslash": "^0.2.12" } }, "sha512-OdyoZRbzTB80qHFHdaXT070OG9hiljxbsJMZmrMAPWXG2e4FV8wbC63VBM5BJXa1DH645nw20VX1MzASkO5V9g=="],
573
579
574
-
"@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="],
580
+
"@shikijs/types": ["@shikijs/types@3.8.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-5C39Q8/8r1I26suLh+5TPk1DTrbY/kn3IdWA5HdizR0FhlhD05zx5nKCqhzSfDHH3p4S0ZefxWd77DLV+8FhGg=="],
575
581
576
582
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
577
-
578
-
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
579
583
580
584
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
581
585
···
755
759
756
760
"@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="],
757
761
758
-
"@types/node": ["@types/node@24.0.13", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ=="],
762
+
"@types/node": ["@types/node@24.0.15", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA=="],
759
763
760
764
"@types/prop-types": ["@types/prop-types@15.7.15", "", {}, "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw=="],
761
765
···
775
779
776
780
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
777
781
778
-
"@vitejs/plugin-react": ["@vitejs/plugin-react@4.6.0", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.19", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ=="],
782
+
"@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="],
779
783
780
784
"@xmldom/xmldom": ["@xmldom/xmldom@0.9.8", "", {}, "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A=="],
781
785
···
795
799
796
800
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
797
801
798
-
"antd": ["antd@5.26.4", "", { "dependencies": { "@ant-design/colors": "^7.2.1", "@ant-design/cssinjs": "^1.23.0", "@ant-design/cssinjs-utils": "^1.1.3", "@ant-design/fast-color": "^2.0.6", "@ant-design/icons": "^5.6.1", "@ant-design/react-slick": "~1.1.2", "@babel/runtime": "^7.26.0", "@rc-component/color-picker": "~2.0.1", "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/tour": "~1.15.1", "@rc-component/trigger": "^2.2.7", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11", "rc-cascader": "~3.34.0", "rc-checkbox": "~3.5.0", "rc-collapse": "~3.9.0", "rc-dialog": "~9.6.0", "rc-drawer": "~7.3.0", "rc-dropdown": "~4.2.1", "rc-field-form": "~2.7.0", "rc-image": "~7.12.0", "rc-input": "~1.8.0", "rc-input-number": "~9.5.0", "rc-mentions": "~2.20.0", "rc-menu": "~9.16.1", "rc-motion": "^2.9.5", "rc-notification": "~5.6.4", "rc-pagination": "~5.1.0", "rc-picker": "~4.11.3", "rc-progress": "~4.0.0", "rc-rate": "~2.13.1", "rc-resize-observer": "^1.4.3", "rc-segmented": "~2.7.0", "rc-select": "~14.16.8", "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", "rc-table": "~7.51.1", "rc-tabs": "~15.6.1", "rc-textarea": "~1.10.0", "rc-tooltip": "~6.4.0", "rc-tree": "~5.13.1", "rc-tree-select": "~5.27.0", "rc-upload": "~4.9.2", "rc-util": "^5.44.4", "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.2" }, "peerDependencies": { "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-e1EnOvEkvvqcQ18dxfzChBJyJACyih13WpNf2OtnP9z2POh/SF0fXL+ynUemT1zfr+p+P1po/tmHXaMc5PMghg=="],
802
+
"antd": ["antd@5.26.6", "", { "dependencies": { "@ant-design/colors": "^7.2.1", "@ant-design/cssinjs": "^1.23.0", "@ant-design/cssinjs-utils": "^1.1.3", "@ant-design/fast-color": "^2.0.6", "@ant-design/icons": "^5.6.1", "@ant-design/react-slick": "~1.1.2", "@babel/runtime": "^7.26.0", "@rc-component/color-picker": "~2.0.1", "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/tour": "~1.15.1", "@rc-component/trigger": "^2.2.7", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11", "rc-cascader": "~3.34.0", "rc-checkbox": "~3.5.0", "rc-collapse": "~3.9.0", "rc-dialog": "~9.6.0", "rc-drawer": "~7.3.0", "rc-dropdown": "~4.2.1", "rc-field-form": "~2.7.0", "rc-image": "~7.12.0", "rc-input": "~1.8.0", "rc-input-number": "~9.5.0", "rc-mentions": "~2.20.0", "rc-menu": "~9.16.1", "rc-motion": "^2.9.5", "rc-notification": "~5.6.4", "rc-pagination": "~5.1.0", "rc-picker": "~4.11.3", "rc-progress": "~4.0.0", "rc-rate": "~2.13.1", "rc-resize-observer": "^1.4.3", "rc-segmented": "~2.7.0", "rc-select": "~14.16.8", "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", "rc-table": "~7.51.1", "rc-tabs": "~15.6.1", "rc-textarea": "~1.10.0", "rc-tooltip": "~6.4.0", "rc-tree": "~5.13.1", "rc-tree-select": "~5.27.0", "rc-upload": "~4.9.2", "rc-util": "^5.44.4", "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.2" }, "peerDependencies": { "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-k8ipeT+UL2tP/x4jHTXElScAxsD94JgrIEeGHj80nNO4dL9hqcmaOUBpHo3ieCf6MFjhS7gLUthysQeP6e7DUg=="],
799
803
800
804
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
801
805
···
830
834
"browserslist": ["browserslist@4.25.1", "", { "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw=="],
831
835
832
836
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
833
-
834
-
"busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="],
835
837
836
838
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
837
839
···
1193
1195
1194
1196
"headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="],
1195
1197
1198
+
"html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="],
1199
+
1196
1200
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
1197
1201
1198
1202
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
···
1497
1501
1498
1502
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
1499
1503
1500
-
"next": ["next@15.3.5", "", { "dependencies": { "@next/env": "15.3.5", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.3.5", "@next/swc-darwin-x64": "15.3.5", "@next/swc-linux-arm64-gnu": "15.3.5", "@next/swc-linux-arm64-musl": "15.3.5", "@next/swc-linux-x64-gnu": "15.3.5", "@next/swc-linux-x64-musl": "15.3.5", "@next/swc-win32-arm64-msvc": "15.3.5", "@next/swc-win32-x64-msvc": "15.3.5", "sharp": "^0.34.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-RkazLBMMDJSJ4XZQ81kolSpwiCt907l0xcgcpF4xC2Vml6QVcPNXW0NQRwQ80FFtSn7UM52XN0anaw8TEJXaiw=="],
1504
+
"next": ["next@15.4.2", "", { "dependencies": { "@next/env": "15.4.2", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.4.2", "@next/swc-darwin-x64": "15.4.2", "@next/swc-linux-arm64-gnu": "15.4.2", "@next/swc-linux-arm64-musl": "15.4.2", "@next/swc-linux-x64-gnu": "15.4.2", "@next/swc-linux-x64-musl": "15.4.2", "@next/swc-win32-arm64-msvc": "15.4.2", "@next/swc-win32-x64-msvc": "15.4.2", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-oH1rmFso+84NIkocfuxaGKcXIjMUTmnzV2x0m8qsYtB4gD6iflLMESXt5XJ8cFgWMBei4v88rNr/j+peNg72XA=="],
1501
1505
1502
1506
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
1503
1507
···
1527
1531
1528
1532
"onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="],
1529
1533
1530
-
"oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="],
1534
+
"oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="],
1535
+
1536
+
"oniguruma-to-es": ["oniguruma-to-es@4.3.3", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg=="],
1531
1537
1532
1538
"ora": ["ora@6.3.1", "", { "dependencies": { "chalk": "^5.0.0", "cli-cursor": "^4.0.0", "cli-spinners": "^2.6.1", "is-interactive": "^2.0.0", "is-unicode-supported": "^1.1.0", "log-symbols": "^5.1.0", "stdin-discarder": "^0.1.0", "strip-ansi": "^7.0.1", "wcwidth": "^1.0.1" } }, "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ=="],
1533
1539
···
1673
1679
1674
1680
"react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
1675
1681
1682
+
"react-markdown": ["react-markdown@10.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ=="],
1683
+
1676
1684
"react-medium-image-zoom": ["react-medium-image-zoom@5.2.14", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-nfTVYcAUnBzXQpPDcZL+cG/e6UceYUIG+zDcnemL7jtAqbJjVVkA85RgneGtJeni12dTyiRPZVM6Szkmwd/o8w=="],
1677
1685
1678
1686
"react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="],
···
1779
1787
1780
1788
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
1781
1789
1782
-
"shadcn": ["shadcn@2.9.0", "", { "dependencies": { "@antfu/ni": "^23.2.0", "@babel/core": "^7.22.1", "@babel/parser": "^7.22.6", "@babel/plugin-transform-typescript": "^7.22.5", "@modelcontextprotocol/sdk": "^1.10.2", "commander": "^10.0.0", "cosmiconfig": "^8.1.3", "deepmerge": "^4.3.1", "diff": "^5.1.0", "execa": "^7.0.0", "fast-glob": "^3.3.2", "fs-extra": "^11.1.0", "https-proxy-agent": "^6.2.0", "kleur": "^4.1.5", "msw": "^2.7.1", "node-fetch": "^3.3.0", "ora": "^6.1.2", "postcss": "^8.4.24", "prompts": "^2.4.2", "recast": "^0.23.2", "stringify-object": "^5.0.0", "ts-morph": "^18.0.0", "tsconfig-paths": "^4.2.0", "zod": "^3.20.2", "zod-to-json-schema": "^3.24.5" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-Wc3zs7SnNdLOiXhJFkdAyB+PZLvo9qk1noRz1kH6x3coMLS8f1SjqKlw5kAtX5abpvzLs07PRFnAtKpBApr20g=="],
1790
+
"shadcn": ["shadcn@2.9.2", "", { "dependencies": { "@antfu/ni": "^23.2.0", "@babel/core": "^7.22.1", "@babel/parser": "^7.22.6", "@babel/plugin-transform-typescript": "^7.22.5", "@modelcontextprotocol/sdk": "^1.10.2", "commander": "^10.0.0", "cosmiconfig": "^8.1.3", "deepmerge": "^4.3.1", "diff": "^5.1.0", "execa": "^7.0.0", "fast-glob": "^3.3.2", "fs-extra": "^11.1.0", "https-proxy-agent": "^6.2.0", "kleur": "^4.1.5", "msw": "^2.7.1", "node-fetch": "^3.3.0", "ora": "^6.1.2", "postcss": "^8.4.24", "prompts": "^2.4.2", "recast": "^0.23.2", "stringify-object": "^5.0.0", "ts-morph": "^18.0.0", "tsconfig-paths": "^4.2.0", "zod": "^3.20.2", "zod-to-json-schema": "^3.24.5" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-Ssat5Qlosk3XQckSmHEUZ1WDiXXxZbeXEl2HI4QKlBwmboMHYFaVhOMl3ObRVN578C/d369AsKQcgLWF8F5hCA=="],
1783
1791
1784
1792
"sharp": ["sharp@0.34.3", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.4", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.3", "@img/sharp-darwin-x64": "0.34.3", "@img/sharp-libvips-darwin-arm64": "1.2.0", "@img/sharp-libvips-darwin-x64": "1.2.0", "@img/sharp-libvips-linux-arm": "1.2.0", "@img/sharp-libvips-linux-arm64": "1.2.0", "@img/sharp-libvips-linux-ppc64": "1.2.0", "@img/sharp-libvips-linux-s390x": "1.2.0", "@img/sharp-libvips-linux-x64": "1.2.0", "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", "@img/sharp-libvips-linuxmusl-x64": "1.2.0", "@img/sharp-linux-arm": "0.34.3", "@img/sharp-linux-arm64": "0.34.3", "@img/sharp-linux-ppc64": "0.34.3", "@img/sharp-linux-s390x": "0.34.3", "@img/sharp-linux-x64": "0.34.3", "@img/sharp-linuxmusl-arm64": "0.34.3", "@img/sharp-linuxmusl-x64": "0.34.3", "@img/sharp-wasm32": "0.34.3", "@img/sharp-win32-arm64": "0.34.3", "@img/sharp-win32-ia32": "0.34.3", "@img/sharp-win32-x64": "0.34.3" } }, "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg=="],
1785
1793
···
1787
1795
1788
1796
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
1789
1797
1790
-
"shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="],
1798
+
"shiki": ["shiki@3.8.1", "", { "dependencies": { "@shikijs/core": "3.8.1", "@shikijs/engine-javascript": "3.8.1", "@shikijs/engine-oniguruma": "3.8.1", "@shikijs/langs": "3.8.1", "@shikijs/themes": "3.8.1", "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-+MYIyjwGPCaegbpBeFN9+oOifI8CKiKG3awI/6h3JeT85c//H2wDW/xCJEGuQ5jPqtbboKNqNy+JyX9PYpGwNg=="],
1791
1799
1792
1800
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
1793
1801
···
1818
1826
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
1819
1827
1820
1828
"stdin-discarder": ["stdin-discarder@0.1.0", "", { "dependencies": { "bl": "^5.0.0" } }, "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ=="],
1821
-
1822
-
"streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="],
1823
1829
1824
1830
"strict-event-emitter": ["strict-event-emitter@0.5.1", "", {}, "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ=="],
1825
1831
···
2017
2023
2018
2024
"@inquirer/core/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
2019
2025
2026
+
"@shikijs/twoslash/@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="],
2027
+
2028
+
"@shikijs/twoslash/@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="],
2029
+
2020
2030
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.4", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g=="],
2021
2031
2022
2032
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.4", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg=="],
···
2061
2071
2062
2072
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
2063
2073
2074
+
"nextra/shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="],
2075
+
2064
2076
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
2065
2077
2066
2078
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
···
2088
2100
"tough-cookie/universalify": ["universalify@0.2.0", "", {}, "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="],
2089
2101
2090
2102
"wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
2103
+
2104
+
"@shikijs/twoslash/@shikijs/core/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="],
2105
+
2106
+
"@shikijs/twoslash/@shikijs/core/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="],
2091
2107
2092
2108
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
2093
2109
···
2105
2121
2106
2122
"mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
2107
2123
2124
+
"nextra/shiki/@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="],
2125
+
2126
+
"nextra/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="],
2127
+
2128
+
"nextra/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="],
2129
+
2130
+
"nextra/shiki/@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="],
2131
+
2132
+
"nextra/shiki/@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="],
2133
+
2134
+
"nextra/shiki/@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="],
2135
+
2108
2136
"remark-reading-time/unist-util-visit/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
2109
2137
2110
2138
"remark-reading-time/unist-util-visit/unist-util-is": ["unist-util-is@5.2.1", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw=="],
···
2116
2144
"string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2117
2145
2118
2146
"wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2147
+
2148
+
"@shikijs/twoslash/@shikijs/core/@shikijs/engine-javascript/oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="],
2149
+
2150
+
"nextra/shiki/@shikijs/engine-javascript/oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="],
2119
2151
}
2120
2152
}
+25
-21
package.json
+25
-21
package.json
···
11
11
},
12
12
"dependencies": {
13
13
"@atcute/car": "^3.1.1",
14
-
"@atproto/api": "^0.15.25",
14
+
"@atproto/api": "^0.15.26",
15
15
"@atproto/jwk-webcrypto": "^0.1.9",
16
16
"@atproto/oauth-client-browser": "^0.3.27",
17
17
"@radix-ui/react-avatar": "^1.1.10",
18
18
"@radix-ui/react-checkbox": "^1.3.2",
19
+
"@radix-ui/react-dialog": "^1.1.14",
19
20
"@radix-ui/react-dropdown-menu": "^2.1.15",
20
21
"@radix-ui/react-label": "^2.1.7",
21
22
"@radix-ui/react-progress": "^1.1.7",
···
24
25
"@radix-ui/react-switch": "^1.2.5",
25
26
"@radix-ui/react-tooltip": "^1.2.7",
26
27
"@tailwindcss/vite": "^4.1.11",
27
-
"@tauri-apps/api": "^2",
28
-
"@tauri-apps/plugin-autostart": "~2",
29
-
"@tauri-apps/plugin-deep-link": "~2",
30
-
"@tauri-apps/plugin-fs": "~2",
31
-
"@tauri-apps/plugin-opener": "^2",
32
-
"@tauri-apps/plugin-process": "~2",
33
-
"@tauri-apps/plugin-shell": "~2",
34
-
"@tauri-apps/plugin-store": "~2",
35
-
"@tauri-apps/plugin-updater": "~2",
36
-
"@tauri-apps/plugin-websocket": "~2",
37
-
"antd": "^5.26.4",
28
+
"@tauri-apps/api": "^2.6.0",
29
+
"@tauri-apps/plugin-autostart": "~2.5.0",
30
+
"@tauri-apps/plugin-deep-link": "~2.4.0",
31
+
"@tauri-apps/plugin-fs": "~2.4.0",
32
+
"@tauri-apps/plugin-opener": "^2.4.0",
33
+
"@tauri-apps/plugin-process": "~2.3.0",
34
+
"@tauri-apps/plugin-shell": "~2.3.0",
35
+
"@tauri-apps/plugin-store": "~2.3.0",
36
+
"@tauri-apps/plugin-updater": "~2.9.0",
37
+
"@tauri-apps/plugin-websocket": "~2.4.0",
38
+
"antd": "^5.26.6",
38
39
"class-variance-authority": "^0.7.1",
39
40
"clsx": "^2.1.1",
40
41
"lucide-react": "^0.525.0",
41
-
"next": "^15.3.5",
42
+
"next": "^15.4.2",
42
43
"next-themes": "^0.4.6",
43
44
"nextra": "^4.2.17",
44
45
"nextra-theme-docs": "^4.2.17",
45
46
"react": "^19.1.0",
46
47
"react-dom": "^19.1.0",
47
-
"shadcn": "^2.9.0",
48
+
"react-markdown": "^10.1.0",
49
+
"remark-gfm": "^4.0.1",
50
+
"shadcn": "^2.9.2",
51
+
"shiki": "^3.8.1",
48
52
"sonner": "^2.0.6",
49
53
"tailwind-merge": "^3.3.1",
50
54
"tailwindcss": "^4.1.11"
51
55
},
52
56
"devDependencies": {
53
-
"@tauri-apps/cli": "^2",
54
-
"@types/node": "^24.0.13",
55
-
"@types/react": "^18.3.1",
56
-
"@types/react-dom": "^18.3.1",
57
-
"@vitejs/plugin-react": "^4.3.4",
57
+
"@tauri-apps/cli": "^2.6.2",
58
+
"@types/node": "^24.0.15",
59
+
"@types/react": "^18.3.23",
60
+
"@types/react-dom": "^18.3.7",
61
+
"@vitejs/plugin-react": "^4.7.0",
58
62
"tw-animate-css": "^1.3.5",
59
-
"typescript": "~5.6.2",
60
-
"vite": "^6.0.3"
63
+
"typescript": "~5.6.3",
64
+
"vite": "^6.3.5"
61
65
},
62
66
"trustedDependencies": [
63
67
"@tailwindcss/oxide"
+1
-1
src-tauri/Cargo.lock
+1
-1
src-tauri/Cargo.lock
+1
-1
src-tauri/Cargo.toml
+1
-1
src-tauri/Cargo.toml
+40
-40
src-tauri/src/lib.rs
+40
-40
src-tauri/src/lib.rs
···
42
42
start_background_scheduler,
43
43
stop_background_scheduler
44
44
])
45
-
// .on_menu_event(|app, event| match event.id.as_ref() {
46
-
// "quit" => {
47
-
// std::process::exit(0);
48
-
// }
49
-
// "show" => {
50
-
// let window = app.get_webview_window("main").unwrap();
51
-
// window.show().unwrap();
52
-
// window.set_focus().unwrap();
53
-
// }
54
-
// "hide" => {
55
-
// let window = app.get_webview_window("main").unwrap();
56
-
// window.hide().unwrap();
57
-
// }
58
-
// "backup_now" => {
59
-
// // Emit event to trigger backup
60
-
// app.emit("perform-backup", ()).unwrap();
61
-
// }
62
-
// _ => {
63
-
// println!("menu item {:?} not handled", event.id);
64
-
// }
65
-
// })
66
-
// .on_tray_icon_event(|tray, event| match event {
67
-
// TrayIconEvent::Click {
68
-
// button: MouseButton::Left,
69
-
// button_state: MouseButtonState::Up,
70
-
// ..
71
-
// } => {
72
-
// println!("left click pressed and released");
73
-
// // in this example, let's show and focus the main window when the tray is clicked
74
-
// let app = tray.app_handle();
75
-
// if let Some(window) = app.get_webview_window("main") {
76
-
// let _ = window.show();
77
-
// let _ = window.set_focus();
78
-
// }
79
-
// }
80
-
// _ => {
81
-
// println!("unhandled event {event:?}");
82
-
// }
83
-
// })
45
+
.on_menu_event(|app, event| match event.id.as_ref() {
46
+
"quit" => {
47
+
std::process::exit(0);
48
+
}
49
+
"show" => {
50
+
let window = app.get_webview_window("main").unwrap();
51
+
window.show().unwrap();
52
+
window.set_focus().unwrap();
53
+
}
54
+
"hide" => {
55
+
let window = app.get_webview_window("main").unwrap();
56
+
window.hide().unwrap();
57
+
}
58
+
"backup_now" => {
59
+
// Emit event to trigger backup
60
+
app.emit("perform-backup", ()).unwrap();
61
+
}
62
+
_ => {
63
+
println!("menu item {:?} not handled", event.id);
64
+
}
65
+
})
66
+
.on_tray_icon_event(|tray, event| match event {
67
+
TrayIconEvent::Click {
68
+
button: MouseButton::Left,
69
+
button_state: MouseButtonState::Up,
70
+
..
71
+
} => {
72
+
println!("left click pressed and released");
73
+
// in this example, let's show and focus the main window when the tray is clicked
74
+
let app = tray.app_handle();
75
+
if let Some(window) = app.get_webview_window("main") {
76
+
let _ = window.show();
77
+
let _ = window.set_focus();
78
+
}
79
+
}
80
+
_ => {
81
+
println!("unhandled event {event:?}");
82
+
}
83
+
})
84
84
.setup(|app| {
85
85
#[cfg(any(windows, target_os = "linux"))]
86
86
{
87
87
app.deep_link().register_all()?;
88
88
}
89
-
//let tray = create_system_tray(app);
89
+
let tray = create_system_tray(app);
90
90
91
91
Ok(())
92
92
});
+1
-1
src-tauri/tauri.conf.json
+1
-1
src-tauri/tauri.conf.json
+141
-80
src/App.tsx
+141
-80
src/App.tsx
···
12
12
import { ScrollArea } from "./components/ui/scroll-area";
13
13
import { BackupAgent } from "./lib/backup";
14
14
import { settingsManager } from "./lib/settings";
15
-
import { check } from "@tauri-apps/plugin-updater";
15
+
import { check, Update } from "@tauri-apps/plugin-updater";
16
16
import { relaunch } from "@tauri-apps/plugin-process";
17
17
import {
18
18
BackgroundBackupService,
19
19
handleBackgroundBackup,
20
20
} from "./lib/backgroundBackup";
21
+
import {
22
+
Dialog,
23
+
DialogClose,
24
+
DialogContent,
25
+
DialogDescription,
26
+
DialogFooter,
27
+
DialogHeader,
28
+
DialogTitle,
29
+
DialogTrigger,
30
+
} from "@/components/ui/dialog";
31
+
import { Progress } from "./components/ui/progress";
32
+
import { MarkdownRenderer } from "./components/ui/markdown-renderer";
21
33
22
34
function AppContent() {
23
35
const { isLoading, isAuthenticated, profile, client, login, logout, agent } =
···
25
37
const appWindow = getCurrentWindow();
26
38
27
39
const [isLocalStorageReady, setIsLocalStorageReady] = useState(false);
40
+
const [update, setUpdate] = useState<Update | null>(null);
41
+
const [downloadProgress, setDownloadProgress] = useState<number | null>(null);
28
42
29
43
useEffect(() => {
30
44
const initStorage = async () => {
···
67
81
}, [isAuthenticated, agent]);
68
82
69
83
// Auto-backup functionality (for when app is open)
70
-
useEffect(() => {
71
-
if (!isAuthenticated || !agent) return;
84
+
// useEffect(() => {
85
+
// if (!isAuthenticated || !agent) return;
72
86
73
-
let intervalId: ReturnType<typeof setInterval> | null = null;
87
+
// let intervalId: ReturnType<typeof setInterval> | null = null;
74
88
75
-
const checkAndPerformBackup = async () => {
76
-
try {
77
-
const lastBackupDate = await settingsManager.getLastBackupDate();
78
-
const frequency = await settingsManager.getBackupFrequency();
89
+
// const checkAndPerformBackup = async () => {
90
+
// try {
91
+
// const lastBackupDate = await settingsManager.getLastBackupDate();
92
+
// const frequency = await settingsManager.getBackupFrequency();
79
93
80
-
if (!lastBackupDate) {
81
-
// No previous backup, so we should do one
82
-
await performBackup();
83
-
return;
84
-
}
94
+
// if (!lastBackupDate) {
95
+
// // No previous backup, so we should do one
96
+
// await performBackup();
97
+
// return;
98
+
// }
85
99
86
-
const lastBackup = new Date(lastBackupDate);
87
-
const now = new Date();
88
-
const timeDiff = now.getTime() - lastBackup.getTime();
100
+
// const lastBackup = new Date(lastBackupDate);
101
+
// const now = new Date();
102
+
// const timeDiff = now.getTime() - lastBackup.getTime();
89
103
90
-
if (frequency === "daily") {
91
-
// Check if 24 hours have passed
92
-
const oneDay = 24 * 60 * 60 * 1000;
93
-
if (timeDiff >= oneDay) {
94
-
await performBackup();
95
-
}
96
-
} else if (frequency === "weekly") {
97
-
// Check if 7 days have passed
98
-
const oneWeek = 7 * 24 * 60 * 60 * 1000;
99
-
if (timeDiff >= oneWeek) {
100
-
await performBackup();
101
-
}
102
-
}
103
-
} catch (error) {
104
-
console.error("Error in automatic backup check:", error);
105
-
}
106
-
};
104
+
// if (frequency === "daily") {
105
+
// // Check if 24 hours have passed
106
+
// const oneDay = 24 * 60 * 60 * 1000;
107
+
// if (timeDiff >= oneDay) {
108
+
// await performBackup();
109
+
// }
110
+
// } else if (frequency === "weekly") {
111
+
// // Check if 7 days have passed
112
+
// const oneWeek = 7 * 24 * 60 * 60 * 1000;
113
+
// if (timeDiff >= oneWeek) {
114
+
// await performBackup();
115
+
// }
116
+
// }
117
+
// } catch (error) {
118
+
// console.error("Error in automatic backup check:", error);
119
+
// }
120
+
// };
107
121
108
-
const performBackup = async () => {
109
-
try {
110
-
console.log("Automatic backup due, starting backup...");
111
-
const manager = new BackupAgent(agent);
112
-
await manager.startBackup();
122
+
// const performBackup = async () => {
123
+
// try {
124
+
// console.log("Automatic backup due, starting backup...");
125
+
// const manager = new BackupAgent(agent);
126
+
// await manager.startBackup();
113
127
114
-
// Update the last backup date
115
-
await settingsManager.setLastBackupDate(new Date().toISOString());
128
+
// // Update the last backup date
129
+
// await settingsManager.setLastBackupDate(new Date().toISOString());
116
130
117
-
console.log("Automatic backup completed successfully");
118
-
} catch (error) {
119
-
console.error("Automatic backup failed:", error);
120
-
}
121
-
};
131
+
// console.log("Automatic backup completed successfully");
132
+
// } catch (error) {
133
+
// console.error("Automatic backup failed:", error);
134
+
// }
135
+
// };
122
136
123
-
// Check immediately when authenticated
124
-
checkAndPerformBackup();
137
+
// // Check immediately when authenticated
138
+
// checkAndPerformBackup();
125
139
126
-
// Set up interval to check every hour
127
-
intervalId = setInterval(checkAndPerformBackup, 60 * 60 * 1000);
140
+
// // Set up interval to check every hour
141
+
// intervalId = setInterval(checkAndPerformBackup, 60 * 60 * 1000);
128
142
129
-
return () => {
130
-
if (intervalId) {
131
-
clearInterval(intervalId);
132
-
}
133
-
};
134
-
}, [isAuthenticated, agent]);
143
+
// return () => {
144
+
// if (intervalId) {
145
+
// clearInterval(intervalId);
146
+
// }
147
+
// };
148
+
// }, [isAuthenticated, agent]);
135
149
136
150
useEffect(() => {
137
151
(async () => {
···
140
154
console.log(
141
155
`found update ${update.version} from ${update.date} with notes ${update.body}`
142
156
);
143
-
toast("Downloading new update...");
144
-
let downloaded = 0;
145
-
let contentLength = 0;
146
-
// alternatively we could also call update.download() and update.install() separately
147
-
await update.downloadAndInstall((event) => {
148
-
switch (event.event) {
149
-
case "Started":
150
-
//@ts-expect-error
151
-
contentLength = event.data.contentLength;
152
-
console.log(
153
-
`started downloading ${event.data.contentLength} bytes`
154
-
);
155
-
break;
156
-
case "Progress":
157
-
downloaded += event.data.chunkLength;
158
-
console.log(`downloaded ${downloaded} from ${contentLength}`);
159
-
break;
160
-
case "Finished":
161
-
console.log("download finished");
162
-
break;
163
-
}
164
-
});
165
-
166
-
toast("Update ready, restarting...");
167
-
await relaunch();
157
+
setUpdate(update);
168
158
}
169
159
})();
170
160
}, []);
···
227
217
</Button>
228
218
</div>
229
219
</div>
220
+
221
+
<Dialog
222
+
open={update != null}
223
+
onOpenChange={(it) => {
224
+
if (it == false) setUpdate(null);
225
+
}}
226
+
>
227
+
{/* <DialogTrigger>Open</DialogTrigger> */}
228
+
<DialogContent>
229
+
<DialogHeader>
230
+
<DialogTitle>
231
+
New update available ({update?.currentVersion} ➜ {update?.version}
232
+
)
233
+
</DialogTitle>
234
+
<DialogDescription>
235
+
<MarkdownRenderer
236
+
children={update?.body ?? "No details provided"}
237
+
/>
238
+
</DialogDescription>
239
+
<DialogFooter className="mt-4">
240
+
{downloadProgress == null ? (
241
+
<>
242
+
<DialogClose asChild className="cursor-pointer">
243
+
<Button variant="outline">Skip</Button>
244
+
</DialogClose>
245
+
<Button
246
+
className="cursor-pointer"
247
+
onClick={async () => {
248
+
if (update == null) toast("Failed: update not found");
249
+
toast("Downloading new update...");
250
+
let downloaded = 0;
251
+
let contentLength = 0;
252
+
// alternatively we could also call update.download() and update.install() separately
253
+
await update!!.downloadAndInstall((event) => {
254
+
switch (event.event) {
255
+
case "Started":
256
+
//@ts-expect-error
257
+
contentLength = event.data.contentLength;
258
+
setDownloadProgress(0);
259
+
console.log(
260
+
`started downloading ${event.data.contentLength} bytes`
261
+
);
262
+
break;
263
+
case "Progress":
264
+
downloaded += event.data.chunkLength;
265
+
setDownloadProgress(downloaded / contentLength);
266
+
console.log(
267
+
`downloaded ${downloaded} from ${contentLength}`
268
+
);
269
+
break;
270
+
case "Finished":
271
+
setDownloadProgress(100);
272
+
console.log("download finished");
273
+
break;
274
+
}
275
+
});
276
+
277
+
toast("Update ready, restarting...");
278
+
await relaunch();
279
+
}}
280
+
>
281
+
Download
282
+
</Button>
283
+
</>
284
+
) : (
285
+
<Progress value={downloadProgress} className="w-full" />
286
+
)}
287
+
</DialogFooter>
288
+
</DialogHeader>
289
+
</DialogContent>
290
+
</Dialog>
230
291
231
292
<ScrollArea>
232
293
{isLoading || !isLocalStorageReady ? (
+36
src/components/hooks/use-copy-to-clipboard.ts
+36
src/components/hooks/use-copy-to-clipboard.ts
···
1
+
import { useCallback, useRef, useState } from "react";
2
+
import { toast } from "sonner";
3
+
4
+
type UseCopyToClipboardProps = {
5
+
text: string;
6
+
copyMessage?: string;
7
+
};
8
+
9
+
export function useCopyToClipboard({
10
+
text,
11
+
copyMessage = "Copied to clipboard!",
12
+
}: UseCopyToClipboardProps) {
13
+
const [isCopied, setIsCopied] = useState(false);
14
+
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
15
+
16
+
const handleCopy = useCallback(() => {
17
+
navigator.clipboard
18
+
.writeText(text)
19
+
.then(() => {
20
+
toast.success(copyMessage);
21
+
setIsCopied(true);
22
+
if (timeoutRef.current) {
23
+
clearTimeout(timeoutRef.current);
24
+
timeoutRef.current = null;
25
+
}
26
+
timeoutRef.current = setTimeout(() => {
27
+
setIsCopied(false);
28
+
}, 2000);
29
+
})
30
+
.catch(() => {
31
+
toast.error("Failed to copy to clipboard.");
32
+
});
33
+
}, [text, copyMessage]);
34
+
35
+
return { isCopied, handleCopy };
36
+
}
+143
src/components/ui/dialog.tsx
+143
src/components/ui/dialog.tsx
···
1
+
"use client";
2
+
3
+
import * as React from "react";
4
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
5
+
import { XIcon } from "lucide-react";
6
+
7
+
import { cn } from "@/lib/utils";
8
+
9
+
function Dialog({
10
+
...props
11
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
12
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
13
+
}
14
+
15
+
function DialogTrigger({
16
+
...props
17
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
18
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
19
+
}
20
+
21
+
function DialogPortal({
22
+
...props
23
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
24
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
25
+
}
26
+
27
+
function DialogClose({
28
+
...props
29
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
30
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
31
+
}
32
+
33
+
function DialogOverlay({
34
+
className,
35
+
...props
36
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
37
+
return (
38
+
<DialogPrimitive.Overlay
39
+
data-slot="dialog-overlay"
40
+
className={cn(
41
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
42
+
className
43
+
)}
44
+
{...props}
45
+
/>
46
+
);
47
+
}
48
+
49
+
function DialogContent({
50
+
className,
51
+
children,
52
+
showCloseButton = true,
53
+
...props
54
+
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
55
+
showCloseButton?: boolean;
56
+
}) {
57
+
return (
58
+
<DialogPortal data-slot="dialog-portal">
59
+
<DialogOverlay />
60
+
<DialogPrimitive.Content
61
+
data-slot="dialog-content"
62
+
className={cn(
63
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
64
+
className
65
+
)}
66
+
{...props}
67
+
>
68
+
{children}
69
+
{showCloseButton && (
70
+
<DialogPrimitive.Close
71
+
data-slot="dialog-close"
72
+
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
73
+
>
74
+
<XIcon />
75
+
<span className="sr-only">Close</span>
76
+
</DialogPrimitive.Close>
77
+
)}
78
+
</DialogPrimitive.Content>
79
+
</DialogPortal>
80
+
);
81
+
}
82
+
83
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
84
+
return (
85
+
<div
86
+
data-slot="dialog-header"
87
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
88
+
{...props}
89
+
/>
90
+
);
91
+
}
92
+
93
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
94
+
return (
95
+
<div
96
+
data-slot="dialog-footer"
97
+
className={cn(
98
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
99
+
className
100
+
)}
101
+
{...props}
102
+
/>
103
+
);
104
+
}
105
+
106
+
function DialogTitle({
107
+
className,
108
+
...props
109
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
110
+
return (
111
+
<DialogPrimitive.Title
112
+
data-slot="dialog-title"
113
+
className={cn("text-lg leading-none font-semibold", className)}
114
+
{...props}
115
+
/>
116
+
);
117
+
}
118
+
119
+
function DialogDescription({
120
+
className,
121
+
...props
122
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
123
+
return (
124
+
<DialogPrimitive.Description
125
+
data-slot="dialog-description"
126
+
className={cn("text-muted-foreground text-sm", className)}
127
+
{...props}
128
+
/>
129
+
);
130
+
}
131
+
132
+
export {
133
+
Dialog,
134
+
DialogClose,
135
+
DialogContent,
136
+
DialogDescription,
137
+
DialogFooter,
138
+
DialogHeader,
139
+
DialogOverlay,
140
+
DialogPortal,
141
+
DialogTitle,
142
+
DialogTrigger,
143
+
};
+223
src/components/ui/markdown-renderer.tsx
+223
src/components/ui/markdown-renderer.tsx
···
1
+
import React, { Suspense } from "react";
2
+
import Markdown from "react-markdown";
3
+
import remarkGfm from "remark-gfm";
4
+
import type { ThemedToken, TokensResult } from "shiki";
5
+
6
+
import { cn } from "@/lib/utils";
7
+
import { CopyButton } from "@/components/ui/copy-button";
8
+
9
+
interface MarkdownRendererProps {
10
+
children: string;
11
+
}
12
+
13
+
export function MarkdownRenderer({ children }: MarkdownRendererProps) {
14
+
return (
15
+
<div className="space-y-3">
16
+
<Markdown remarkPlugins={[remarkGfm]} components={COMPONENTS}>
17
+
{children}
18
+
</Markdown>
19
+
</div>
20
+
);
21
+
}
22
+
23
+
interface HighlightedPre extends React.HTMLAttributes<HTMLPreElement> {
24
+
children: string;
25
+
language: string;
26
+
}
27
+
28
+
// Synchronous wrapper that uses Suspense
29
+
const HighlightedPre = ({ children, language, ...props }: HighlightedPre) => {
30
+
return (
31
+
<Suspense fallback={<pre {...props}>{children}</pre>}>
32
+
<AsyncHighlightedPre language={language} {...props}>
33
+
{children}
34
+
</AsyncHighlightedPre>
35
+
</Suspense>
36
+
);
37
+
};
38
+
39
+
// Async logic moved here, loaded with lazy or dynamic inside the component
40
+
const AsyncHighlightedPre = (props: HighlightedPre) => {
41
+
const [tokens, setTokens] = React.useState<ThemedToken[][] | null>([]);
42
+
const [loaded, setLoaded] = React.useState(false);
43
+
44
+
React.useEffect(() => {
45
+
(async () => {
46
+
const { codeToTokens, bundledLanguages } = await import("shiki");
47
+
48
+
if (!(props.language in bundledLanguages)) {
49
+
setTokens(null);
50
+
setLoaded(true);
51
+
return;
52
+
}
53
+
54
+
const { tokens } = await codeToTokens(props.children, {
55
+
lang: props.language as keyof typeof bundledLanguages,
56
+
defaultColor: false,
57
+
themes: {
58
+
light: "github-light",
59
+
dark: "github-dark",
60
+
},
61
+
});
62
+
63
+
setTokens(tokens);
64
+
setLoaded(true);
65
+
})();
66
+
}, [props.children, props.language]);
67
+
68
+
if (!loaded) {
69
+
return <pre {...props}>{props.children}</pre>;
70
+
}
71
+
72
+
if (!tokens) {
73
+
return <pre {...props}>{props.children}</pre>;
74
+
}
75
+
76
+
return (
77
+
<pre {...props}>
78
+
<code>
79
+
{tokens.map((line, lineIndex) => (
80
+
<span key={lineIndex}>
81
+
{line.map((token, tokenIndex) => {
82
+
const style =
83
+
typeof token.htmlStyle === "string"
84
+
? undefined
85
+
: token.htmlStyle;
86
+
87
+
return (
88
+
<span
89
+
key={tokenIndex}
90
+
className="text-shiki-light bg-shiki-light-bg dark:text-shiki-dark dark:bg-shiki-dark-bg"
91
+
style={style}
92
+
>
93
+
{token.content}
94
+
</span>
95
+
);
96
+
})}
97
+
{"\n"}
98
+
</span>
99
+
))}
100
+
</code>
101
+
</pre>
102
+
);
103
+
};
104
+
105
+
HighlightedPre.displayName = "HighlightedCode";
106
+
107
+
interface CodeBlockProps extends React.HTMLAttributes<HTMLPreElement> {
108
+
children: React.ReactNode;
109
+
className?: string;
110
+
language: string;
111
+
}
112
+
113
+
const CodeBlock = ({
114
+
children,
115
+
className,
116
+
language,
117
+
...restProps
118
+
}: CodeBlockProps) => {
119
+
const code =
120
+
typeof children === "string"
121
+
? children
122
+
: childrenTakeAllStringContents(children);
123
+
124
+
const preClass = cn(
125
+
"overflow-x-scroll rounded-md border bg-background/50 p-4 font-mono text-sm [scrollbar-width:none]",
126
+
className
127
+
);
128
+
129
+
return (
130
+
<div className="group/code relative mb-4">
131
+
<Suspense
132
+
fallback={
133
+
<pre className={preClass} {...restProps}>
134
+
{children}
135
+
</pre>
136
+
}
137
+
>
138
+
<HighlightedPre language={language} className={preClass}>
139
+
{code}
140
+
</HighlightedPre>
141
+
</Suspense>
142
+
143
+
<div className="invisible absolute right-2 top-2 flex space-x-1 rounded-lg p-1 opacity-0 transition-all duration-200 group-hover/code:visible group-hover/code:opacity-100">
144
+
<CopyButton content={code} copyMessage="Copied code to clipboard" />
145
+
</div>
146
+
</div>
147
+
);
148
+
};
149
+
150
+
function childrenTakeAllStringContents(element: any): string {
151
+
if (typeof element === "string") {
152
+
return element;
153
+
}
154
+
155
+
if (element?.props?.children) {
156
+
let children = element.props.children;
157
+
158
+
if (Array.isArray(children)) {
159
+
return children
160
+
.map((child) => childrenTakeAllStringContents(child))
161
+
.join("");
162
+
} else {
163
+
return childrenTakeAllStringContents(children);
164
+
}
165
+
}
166
+
167
+
return "";
168
+
}
169
+
170
+
const COMPONENTS = {
171
+
h1: withClass("h1", "text-2xl font-semibold"),
172
+
h2: withClass("h2", "font-semibold text-xl"),
173
+
h3: withClass("h3", "font-semibold text-lg"),
174
+
h4: withClass("h4", "font-semibold text-base"),
175
+
h5: withClass("h5", "font-medium"),
176
+
strong: withClass("strong", "font-semibold"),
177
+
a: withClass("a", "text-primary underline underline-offset-2"),
178
+
blockquote: withClass("blockquote", "border-l-2 border-primary pl-4"),
179
+
code: ({ children, className, node, ...rest }: any) => {
180
+
const match = /language-(\w+)/.exec(className || "");
181
+
return match ? (
182
+
<CodeBlock className={className} language={match[1]} {...rest}>
183
+
{children}
184
+
</CodeBlock>
185
+
) : (
186
+
<code
187
+
className={cn(
188
+
"font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:bg-background/50 [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5"
189
+
)}
190
+
{...rest}
191
+
>
192
+
{children}
193
+
</code>
194
+
);
195
+
},
196
+
pre: ({ children }: any) => children,
197
+
ol: withClass("ol", "list-decimal space-y-2 pl-6"),
198
+
ul: withClass("ul", "list-disc space-y-2 pl-6"),
199
+
li: withClass("li", "my-1.5"),
200
+
table: withClass(
201
+
"table",
202
+
"w-full border-collapse overflow-y-auto rounded-md border border-foreground/20"
203
+
),
204
+
th: withClass(
205
+
"th",
206
+
"border border-foreground/20 px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
207
+
),
208
+
td: withClass(
209
+
"td",
210
+
"border border-foreground/20 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
211
+
),
212
+
tr: withClass("tr", "m-0 border-t p-0 even:bg-muted"),
213
+
p: withClass("p", "whitespace-pre-wrap"),
214
+
hr: withClass("hr", "border-foreground/20"),
215
+
};
216
+
217
+
function withClass(Tag: keyof JSX.IntrinsicElements, classes: string) {
218
+
const Component = ({ node, ...props }: any) => (
219
+
<Tag className={classes} {...props} />
220
+
);
221
+
Component.displayName = Tag;
222
+
return Component;
223
+
}
+16
tailwind.config.js
+16
tailwind.config.js
···
1
+
/** @type {import('tailwindcss').Config} */
2
+
module.exports = {
3
+
content: ["./src/**/*.{html,js}"],
4
+
theme: {
5
+
extend: {
6
+
colors: {
7
+
shiki: {
8
+
light: "var(--shiki-light)",
9
+
"light-bg": "var(--shiki-light-bg)",
10
+
dark: "var(--shiki-dark)",
11
+
"dark-bg": "var(--shiki-dark-bg)",
12
+
},
13
+
},
14
+
},
15
+
},
16
+
};