flashts 1.0.4 → 1.0.6

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/CHANGELOG.md CHANGED
@@ -2,6 +2,66 @@
2
2
 
3
3
  All notable changes to FlashTS will be documented in this file.
4
4
 
5
+ ## [1.0.6] - 2026-01-24
6
+
7
+ ### Added
8
+
9
+ - **Live Web Preview**: Full-featured preview panel for HTML, React (TSX/JSX), and web projects with Vite-powered hot module replacement.
10
+ - **Micro-Console Panel**: Tabbed console view separating Vite server logs from browser console output, providing clear visibility into both build errors and runtime logs.
11
+ - **Browser Console Capture**: Client-side console.log, warn, and error statements are now captured and streamed to the Micro-Console in real-time.
12
+ - **Markdown Rendering**: Files with `.md` extension now render with full syntax highlighting and GitHub-flavored styling.
13
+ - **Project Export System**: Export projects as production-ready ZIP files with customizable `package.json` metadata and dependency management.
14
+ - **Project Import System**: Import existing projects from ZIP files or folder uploads, with automatic structure preservation.
15
+ - **File Explorer**: Full tree-view file browser with folder support, context menus, and drag-and-drop organization.
16
+ - **Professional Welcome Screen**: Redesigned onboarding modal with feature showcase, keyboard shortcuts reference, and startup toggle.
17
+
18
+ ### Changed
19
+
20
+ - **Isolated Sandbox Environment**: Execution and preview environments now use a dedicated `tmp/isolated_env` directory with shared `node_modules`, completely separate from the CLI installation.
21
+ - **Session Architecture**: Implemented UUID-based session isolation for previews to prevent Windows file locking conflicts during multi-tab usage.
22
+ - **Execution Efficiency**: Execution sessions now reuse a single static folder instead of creating new directories, improving disk usage.
23
+ - **Process Management**: Enhanced process cleanup with guaranteed termination of Vite and Bun subprocesses on CLI exit (Ctrl+C).
24
+ - **Binary Path Resolution**: All subprocess spawns now use absolute binary paths (`process.execPath`) to prevent PATH-related failures on Windows.
25
+ - **Welcome Screen Performance**: Replaced Framer Motion animations with optimized CSS-only transitions for improved frame rates.
26
+ - **Compact UI**: Reduced Welcome Screen dimensions and element sizes for a cleaner, less intrusive experience.
27
+
28
+ ### Fixed
29
+
30
+ - **ENOENT Spawn Errors**: Resolved `uv_spawn 'bun'` failures by using the resolved executable path instead of relying on system PATH.
31
+ - **EBUSY Lock Errors**: Eliminated Windows file locking errors during session cleanup by implementing resilient, non-blocking garbage collection.
32
+ - **Preview Synchronization**: Fixed HMR sync to correctly target session-specific directories using the session ID.
33
+ - **Vite Config Generation**: Corrected syntax error in dynamically generated `vite.config.ts` that prevented preview startup.
34
+ - **Startup Cleanup**: CLI now performs aggressive garbage collection on startup to remove any orphaned session directories from previous runs.
35
+ - **Exit Cleanup**: Guaranteed cleanup of all temporary directories (`execute-session`, `preview-*`) when the CLI is terminated.
36
+
37
+ ### Technical
38
+
39
+ - **Full Sandbox Isolation**: Preview dependencies are now installed in an isolated `node_modules` completely separate from the CLI package.
40
+ - **Monaco Type Resolution**: Enhanced type acquisition to search both isolated sandbox and CLI `node_modules` for IntelliSense.
41
+ - **Resilient GC**: Implemented try-catch wrapped cleanup routines that gracefully handle locked files without blocking new sessions.
42
+ - **Port Discovery**: Automatic port assignment using ephemeral ports for Vite instances to avoid conflicts.
43
+
44
+ ## [1.0.5] - 2026-01-23
45
+
46
+ ### Added
47
+
48
+ - **Real-time Console**: Implemented streaming output for immediate feedback on async processes and loops.
49
+ - **Auto-run**: Code now executes automatically on change after the initial manual run.
50
+ - **Auto-run Safeguard**: Logic prevents auto-run from re-enabling if manually disabled by the user.
51
+ - **Hard Reload**: `Ctrl + Shift + F` now aborts any running process and restarts a fresh execution.
52
+ - **Seamless Updates**: Console logs are now replaced instantly without clearing to prevent flickering.
53
+ - **CLI Feedback**: Added "Opening in browser..." message to CLI output.
54
+
55
+ ### Changed
56
+
57
+ - **Run Button**: UI now remains stable ("Run") during execution, using color and spinner to indicate state.
58
+ - **Package Manager**: Added Framer Motion animations and "stay open" behavior for multi-package installation.
59
+ - **Scope Isolation**: Reverted `moduleDetection: 3` to restore global variables and implemented visual suppression of "redeclaration" errors.
60
+
61
+ ### Fixed
62
+
63
+ - **Type Error**: Fixed `handleRun` onClick handler in `App.tsx` passing event object instead of boolean.
64
+
5
65
  ## [1.0.4] - 2026-01-23
6
66
 
7
67
  ### Changed
package/README.md CHANGED
@@ -1,61 +1,83 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/ZtaMDev/FlashTS/refs/heads/main/client/public/favicon.svg" alt="FlashTS" width="80" />
2
+ <img src="https://raw.githubusercontent.com/ZtaMDev/FlashTS/refs/heads/main/client/public/favicon.svg" alt="FlashTS" width="100" />
3
3
  <h1>FlashTS</h1>
4
4
  <p><b>High-performance TypeScript/JavaScript Playground powered by Bun</b></p>
5
+
6
+ [![Open Setup](https://img.shields.io/badge/Bun-v1.3.6-black?logo=bun&logoColor=white)](https://bun.sh)
7
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
+
5
9
  </div>
6
10
 
7
11
  ---
8
12
 
9
- FlashTS is an ultra-fast, modern playground that brings a professional IDE-like experience to your browser. Create, run, and share TypeScript projects with full NPM module support instantly.
13
+ FlashTS is a professional-grade TypeScript/JavaScript playground designed for ultra-fast iteration. Unlike others, it's open-source, supports NPM modules out of the box, and provides a powerful Web Preview for React and other modern frameworks.
10
14
 
11
- ## Quick Start (via NPM)
15
+ ## Quick Start (via CLI)
12
16
 
13
- The fastest way to experience FlashTS is via the CLI.
17
+ The recommended way to use FlashTS is through the CLI.
14
18
 
15
19
  ```bash
16
20
  bun install -g flashts
17
21
  ```
18
22
 
19
- Open it with:
23
+ Then simply run:
20
24
 
21
25
  ```bash
22
26
  flashts
23
27
  ```
24
28
 
25
- ### Options
29
+ ### CLI Options
30
+
31
+ | Flag | Description |
32
+ | --------------------- | ------------------------------------------------------- |
33
+ | `-p, --port <number>` | Set a custom port (defaults to 3000, autoscans if busy) |
34
+ | `-s, --share` | Generate a shareable public link via localtunnel |
35
+ | `--no-open` | Prevent the browser from opening automatically |
26
36
 
27
- | Flag | Description |
28
- | --------------------- | ----------------------------------------------------- |
29
- | `-p, --port <number>` | Set a custom port (default: 3000) |
30
- | `-s, --share` | Generate a shareable public link with tunnel password |
31
- | `--no-open` | Prevent the browser from opening automatically |
37
+ ---
32
38
 
33
39
  ## Key Features
34
40
 
35
- - **Blazing Fast**: Powered by **Bun**, the all-in-one JavaScript runtime.
41
+ ### Professional IDE Experience
42
+
43
+ - **Multi-file Workspace**: Build complex apps with relative imports and folder structures.
44
+ - **Smart IntelliSense**: Real-time type definitions for all your NPM dependencies.
45
+ - **Micro-Console**: A dedicated log panel that combines Vite build errors and browser `console` output.
46
+
47
+ ### Instant Web Preview
36
48
 
37
- <img width="1596" height="705" alt="image" src="https://github.com/user-attachments/assets/e0bdc737-532d-4414-b08d-0ce40e16de29" />
49
+ - **React & JSX Support**: Full support for `.tsx` and `.jsx` files with automatic HMR.
50
+ - **Auto-run**: Code executes instantly as you type (or via `Ctrl + Shift + F`).
51
+ - **Zero Config**: Just create an `index.html` or start writing a React component; FlashTS handles the rest.
38
52
 
39
- - **Multi-file Workspace**: Work on complex projects with relative imports (`import { x } from "./utils"`).
53
+ ### Powerhouse Backend
40
54
 
41
- <img width="1596" height="716" alt="image" src="https://github.com/user-attachments/assets/19966998-1d3e-4c1c-8101-ca9f0f1be71c" />
55
+ - **Bun Runtime**: Blazing fast execution and dependency resolution.
56
+ - **NPM Manager**: Search and install any package from the huge NPM registry instantly.
57
+ - **Persistence**: Sessions are kept alive during tab switches and refreshes.
42
58
 
43
- - **Smart IntelliSense**: Real-time type definitions for your NPM dependencies.
59
+ ---
60
+
61
+ ## Productivity Shortcuts
44
62
 
45
- <img width="922" height="707" alt="image" src="https://github.com/user-attachments/assets/927171ae-85c9-4854-9849-b78fe25dc3bc" />
63
+ | Action | Shortcut |
64
+ | -------------------- | ------------------ |
65
+ | **Run / Restart** | `Ctrl + Shift + F` |
66
+ | **NPM Manager** | `Ctrl + Shift + L` |
67
+ | **Download Project** | `Ctrl + Shift + E` |
68
+ | **Import Files** | `Ctrl + Shift + I` |
46
69
 
47
- - **NPM Management**: Search and install packages directly from the UI.
70
+ ---
48
71
 
49
- <img width="1599" height="717" alt="image" src="https://github.com/user-attachments/assets/43a9b37d-c6c9-4558-808d-5eaf105030b1" />
72
+ ## Architecture
50
73
 
51
- - **Instant Sharing**: Generate public links to share your playground with others.
52
- - **Premium UI**: Dark mode, responsive design, and smooth animations.
74
+ FlashTS uses a hybrid architecture for maximum performance:
53
75
 
54
- ## Usage Tips
76
+ - **Client**: React + Monaco Editor + Vite-powered Preview.
77
+ - **Server**: Hono + Bun.spawn for session-isolated execution.
78
+ - **Vite Plugin**: A custom plugin captures all browser logs and redirects them to the IDE's Micro-Console.
55
79
 
56
- - **Run Shortcut**: `Ctrl + Shift + F` to execute the current file.
57
- - **Package Manager**: `Ctrl + Shift + L` to quickly find and install new packages.
58
- - **Sharing**: Use `flashts --share` to get a public URL and your tunnel password (IP).
80
+ ---
59
81
 
60
82
  ## License
61
83
 
@@ -63,8 +85,4 @@ FlashTS is open-source software licensed under the [MIT License](LICENSE).
63
85
 
64
86
  ---
65
87
 
66
- ### Contributing & Development
67
-
68
- Interested in how FlashTS works or want to contribute? Check out our [CONTRIBUTING.md](./CONTRIBUTING.md) for architecture details and local setup instructions.
69
-
70
- Built by **ZMDev** because all online options are paid, not open source or doesn't support npm modules correctly.
88
+ ### Built by **ZMDev**
package/bin/cli.ts CHANGED
@@ -10,15 +10,42 @@ const program = new Command();
10
10
  program
11
11
  .name("flashts")
12
12
  .description("FlashTS: High-performance TypeScript Playground CLI")
13
- .version("1.0.4")
13
+ .version("1.0.6")
14
14
  .option("-p, --port <number>", "Port to run the server on", "3000")
15
15
  .option("-s, --share", "Generate a shareable public link")
16
16
  .option("--no-open", "Do not open the browser automatically")
17
17
  .action(async (options: { port: string; share: any; open: any; }) => {
18
- const port = parseInt(options.port);
18
+ const findAvailablePort = async (startPort: number): Promise<number> => {
19
+ let currentPort = startPort;
20
+ while (currentPort < startPort + 100) {
21
+ try {
22
+ const server = Bun.serve({
23
+ port: currentPort,
24
+ fetch: () => new Response("check"),
25
+ });
26
+ server.stop();
27
+ return currentPort;
28
+ } catch (e: any) {
29
+ if (e.code === "EADDRINUSE" || e.message.includes("EADDRINUSE")) {
30
+ currentPort++;
31
+ } else {
32
+ throw e;
33
+ }
34
+ }
35
+ }
36
+ return startPort;
37
+ };
38
+
39
+ const requestedPort = parseInt(options.port);
40
+ const port = await findAvailablePort(requestedPort);
41
+
42
+ if (port !== requestedPort) {
43
+ console.log(`${pc.yellow("⚠")} Port ${requestedPort} is in use, using ${pc.bold(port)} instead.`);
44
+ }
45
+
19
46
  const packageRoot = join(import.meta.dir, "..");
20
47
 
21
- console.log(`\n⚡ ${pc.bold(pc.cyan("FlashTS"))} ${pc.dim("v1.0.4")}`);
48
+ console.log(`\n⚡ ${pc.bold(pc.cyan("FlashTS"))} ${pc.dim("v1.0.6")}`);
22
49
  console.log(`${pc.green("➜")} Local: ${pc.cyan(`http://localhost:${port}`)}`);
23
50
 
24
51
  // Start the server process
@@ -48,15 +75,17 @@ program
48
75
 
49
76
  if (options.open) {
50
77
  setTimeout(() => {
78
+ console.log(`${pc.gray("➜")} ${pc.dim("Opening in browser...")}`);
51
79
  open(`http://localhost:${port}`);
52
80
  }, 1000);
53
81
  }
54
82
 
55
- // Keep process alive
83
+ // Keep process alive and ensure total cleanup
56
84
  process.on("SIGINT", () => {
57
85
  console.log(pc.yellow("\nStopping FlashTS..."));
58
- serverProc.kill();
59
- process.exit(0);
86
+ // The server itself will handle killing vites on SIGINT
87
+ serverProc.kill("SIGINT");
88
+ setTimeout(() => process.exit(0), 500);
60
89
  });
61
90
  });
62
91
 
@@ -0,0 +1 @@
1
+ *,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--font-sans);font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono);font-feature-settings:normal;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}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.left-0\.5{left:.125rem}.right-0{right:0}.right-4{right:1rem}.top-0{top:0}.top-0\.5{top:.125rem}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[10000\]{z-index:10000}.z-\[100\]{z-index:100}.z-\[20000\]{z-index:20000}.z-\[9999\]{z-index:9999}.z-\[99\]{z-index:99}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-auto{margin-top:auto;margin-bottom:auto}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.\!h-auto{height:auto!important}.h-1{height:.25rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0}.w-10{width:2.5rem}.w-2{width:.5rem}.w-24{width:6rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-64{width:16rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.min-w-0{min-width:0}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-\[120px\]{max-width:120px}.max-w-\[600px\]{max-width:600px}.max-w-lg{max-width:32rem}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.flex-1{flex:1}.flex-\[2\]{flex:2}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x:0px;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-4{--tw-translate-x:1rem;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:2s cubic-bezier(.4,0,.6,1) infinite pulse}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;user-select:none}.resize-none{resize:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-x{border-left-width:1px;border-right-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-none{border-style:none}.border-accent-primary{border-color:var(--accent-primary)}.border-blue-400\/10{border-color:#60a5fa1a}.border-border-color{border-color:var(--border-color)}.border-cyan-400\/10{border-color:#22d3ee1a}.border-green-400\/10{border-color:#4ade801a}.border-orange-400\/10{border-color:#fb923c1a}.border-purple-400\/10{border-color:#c084fc1a}.border-red-400\/20{border-color:#f8717133}.border-transparent{border-color:#0000}.border-white\/10{border-color:#ffffff1a}.border-white\/5{border-color:#ffffff0d}.border-white\/\[0\.02\]{border-color:#ffffff05}.border-yellow-400\/10{border-color:#facc151a}.border-yellow-500\/20{border-color:#eab30833}.border-t-transparent{border-top-color:#0000}.bg-\[\#09090b\]{--tw-bg-opacity:1;background-color:rgb(9 9 11/var(--tw-bg-opacity,1))}.bg-\[\#0c0c0e\]{--tw-bg-opacity:1;background-color:rgb(12 12 14/var(--tw-bg-opacity,1))}.bg-\[\#0d0d0f\]\/95{background-color:#0d0d0ff2}.bg-\[\#0d1117\]{--tw-bg-opacity:1;background-color:rgb(13 17 23/var(--tw-bg-opacity,1))}.bg-\[\#1e1e20\]{--tw-bg-opacity:1;background-color:rgb(30 30 32/var(--tw-bg-opacity,1))}.bg-accent-primary{background-color:var(--accent-primary)}.bg-bg-primary{background-color:var(--bg-primary)}.bg-bg-secondary{background-color:var(--bg-secondary)}.bg-bg-tertiary{background-color:var(--bg-tertiary)}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-black\/20{background-color:#0003}.bg-black\/40{background-color:#0006}.bg-black\/60{background-color:#0009}.bg-black\/85{background-color:#000000d9}.bg-blue-400\/5{background-color:#60a5fa0d}.bg-border-color{background-color:var(--border-color)}.bg-cyan-400\/5{background-color:#22d3ee0d}.bg-green-400\/5{background-color:#4ade800d}.bg-orange-400\/5{background-color:#fb923c0d}.bg-purple-400\/5{background-color:#c084fc0d}.bg-red-400\/10{background-color:#f871711a}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-red-500\/10{background-color:#ef44441a}.bg-transparent{background-color:#0000}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-white\/10{background-color:#ffffff1a}.bg-white\/20{background-color:#fff3}.bg-white\/40{background-color:#fff6}.bg-white\/5{background-color:#ffffff0d}.bg-white\/\[0\.02\]{background-color:#ffffff05}.bg-yellow-400\/5{background-color:#facc150d}.bg-yellow-500\/10{background-color:#eab3081a}.bg-yellow-500\/20{background-color:#eab30833}.bg-gradient-to-br{background-image:linear-gradient(to bottom right, var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right, var(--tw-gradient-stops))}.from-accent-primary{--tw-gradient-from:var(--accent-primary) var(--tw-gradient-from-position);--tw-gradient-to:#fff0 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.from-transparent{--tw-gradient-from:transparent var(--tw-gradient-from-position);--tw-gradient-to:#0000 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-100{--tw-gradient-from:#fef9c3 var(--tw-gradient-from-position);--tw-gradient-to:#fef9c300 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.via-accent-primary{--tw-gradient-to:#fff0 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--accent-primary) var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-orange-100{--tw-gradient-to:#ffedd5 var(--tw-gradient-to-position)}.to-orange-600{--tw-gradient-to:#ea580c var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.\!p-0{padding:0!important}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.\!px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pl-5{padding-left:1.25rem}.pt-2{padding-top:.5rem}.pt-24{padding-top:6rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.italic{font-style:italic}.leading-loose{line-height:2}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-accent-primary{color:var(--accent-primary)}.text-amber-400{--tw-text-opacity:1;color:rgb(251 191 36/var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.text-cyan-400{--tw-text-opacity:1;color:rgb(34 211 238/var(--tw-text-opacity,1))}.text-green-400{--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.text-orange-400{--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity,1))}.text-purple-400{--tw-text-opacity:1;color:rgb(192 132 252/var(--tw-text-opacity,1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-text-primary{color:var(--text-primary)}.text-text-secondary{color:var(--text-secondary)}.text-transparent{color:#0000}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-white\/80{color:#fffc}.text-yellow-200{--tw-text-opacity:1;color:rgb(254 240 138/var(--tw-text-opacity,1))}.text-yellow-400{--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity,1))}.text-yellow-500{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity,1))}.text-yellow-500\/70{color:#eab308b3}.line-through{text-decoration-line:line-through}.opacity-0{opacity:0}.opacity-10{opacity:.1}.opacity-100{opacity:1}.opacity-20{opacity:.2}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow-2xl{--tw-shadow:0 25px 50px -12px #00000040;--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px #0000001a, 0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.outline-none{outline-offset:2px;outline:2px solid #0000}.ring-0{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-\[background-color\,color\]{transition-property:background-color,color;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-property:transform;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}:root{--bg-primary:#09090b;--bg-secondary:#18181b;--bg-tertiary:#27272a;--accent-primary:#f59e0b;--accent-glow:#f59e0b80;--text-primary:#f4f4f5;--text-secondary:#a1a1aa;--border-color:#27272a;--font-mono:"JetBrains Mono", "Fira Code", source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;--font-sans:"Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--bg-primary);color:var(--text-primary);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow:hidden}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--bg-primary)}::-webkit-scrollbar-thumb{background:var(--bg-tertiary);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#3f3f46}.glass{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background:#18181b99;border:1px solid #ffffff0d}.flex-center{justify-content:center;align-items:center;display:flex}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@keyframes glow{0%{box-shadow:0 0 5px var(--accent-glow)}50%{box-shadow:0 0 20px var(--accent-glow)}to{box-shadow:0 0 5px var(--accent-glow)}}@keyframes modal-entrance{0%{opacity:0;filter:blur(10px);transform:scale(.9)translateY(20px)}60%{filter:blur();transform:scale(1.02)translateY(-5px)}to{opacity:1;transform:scale(1)translateY(0)}}.animate-modal{animation:.5s cubic-bezier(.34,1.56,.64,1) forwards modal-entrance}.btn-primary{color:#fff;cursor:pointer;background:linear-gradient(135deg,#f59e0b,#ea580c);border:none;border-radius:8px;align-items:center;gap:.5rem;padding:.5rem 1.5rem;font-weight:600;transition:all .2s;display:flex}.btn-primary:hover{box-shadow:0 4px 12px var(--accent-glow);transform:translateY(-1px)}.btn-primary:active{transform:translateY(0)}.panel-header{border-bottom:1px solid var(--border-color);background:var(--bg-secondary);height:48px;color:var(--text-secondary);-webkit-user-select:none;user-select:none;justify-content:space-between;align-items:center;padding:0 1rem;font-size:.875rem;font-weight:500;display:flex}[data-panel-resize-handle],[data-panel-resize-handle]:focus,[data-panel-resize-handle]:focus-visible,[data-panel-resize-handle]:active,[data-panel-resize-handle] *{box-shadow:none!important;-webkit-tap-highlight-color:transparent!important;border-color:#0000!important;outline:none!important}.markdown-body{color:#e6edf3;word-wrap:break-word;line-height:1.6;font-family:var(--font-sans)}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{color:var(--accent-primary);margin-top:1.5rem;margin-bottom:1rem;font-weight:600;line-height:1.25}.markdown-body h1{border-bottom:1px solid var(--border-color);padding-bottom:.3rem;font-size:2rem}.markdown-body h2{border-bottom:1px solid var(--border-color);padding-bottom:.3rem;font-size:1.5rem}.markdown-body h3{font-size:1.25rem}.markdown-body p,.markdown-body blockquote,.markdown-body ul,.markdown-body ol,.markdown-body dl,.markdown-body table,.markdown-body pre{margin-top:0;margin-bottom:1rem}.markdown-body code{font-size:85%;font-family:var(--font-mono);background-color:#ffffff1a;border-radius:6px;margin:0;padding:.2rem .4rem}.markdown-body pre{border:1px solid var(--border-color);background-color:#0d1117;border-radius:6px;padding:1rem;font-size:85%;line-height:1.45;overflow:auto}.markdown-body pre code{word-break:normal;white-space:pre;background-color:#0000;border:0;margin:0;padding:0;font-size:100%}.markdown-body blockquote{color:var(--text-secondary);border-left:.25rem solid var(--border-color);padding:0 1rem}.markdown-body ul{padding-left:2rem;list-style-type:disc}.markdown-body ol{padding-left:2rem;list-style-type:decimal}.placeholder\:text-white\/20::placeholder{color:#fff3}.last\:border-0:last-child{border-width:0}.hover\:bg-accent-primary:hover{background-color:var(--accent-primary)}.hover\:bg-red-500\/20:hover{background-color:#ef444433}.hover\:bg-red-600:hover{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:bg-yellow-500\/30:hover{background-color:#eab3084d}.hover\:text-accent-primary:hover{color:var(--accent-primary)}.hover\:text-red-400:hover{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.hover\:text-text-primary:hover{color:var(--text-primary)}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.hover\:text-yellow-500:hover{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-\[0_0_20px_rgba\(245\,158\,11\,0\.3\)\]:hover{--tw-shadow:0 0 20px #f59e0b4d;--tw-shadow-colored:0 0 20px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.hover\:brightness-110:hover{--tw-brightness:brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-accent-primary:focus{border-color:var(--accent-primary)}.focus\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.active\:scale-90:active{--tw-scale-x:.9;--tw-scale-y:.9;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:hover\:bg-transparent:hover:disabled{background-color:#0000}.group:hover .group-hover\:opacity-100{opacity:1}.group:hover .group-hover\:opacity-30{opacity:.3}@media (min-width:640px){.sm\:block{display:block}}@media (min-width:768px){.md\:block{display:block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:h-8{height:2rem}.md\:h-auto{height:auto}.md\:w-1{width:.25rem}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:gap-3{gap:.75rem}.md\:p-10{padding:2.5rem}.md\:p-6{padding:1.5rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#79c0ff}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-comment,.hljs-code,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}