@idl3/claude-control 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,6 +28,8 @@ npm install -g @idl3/claude-control # or run once: npx @idl3/claude-control
28
28
  **Optional local AI (no API key):**
29
29
 
30
30
  - **Voice → text** — run `claude-control setup` once: it installs `ffmpeg` + `whisper.cpp` (Homebrew) and downloads a ggml model to `~/.claude-control/models/`. The mic in the composer then records audio and transcribes it locally (no API key). *(Manual equivalent: `brew install ffmpeg whisper-cpp` and drop a model at `~/.claude-control/models/ggml-base.en.bin`.)*
31
+
32
+ > **Microphone on a phone or tablet**: browsers only allow mic access on a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) (HTTPS or `localhost`). A plain `http://192.168.x.x:4317` URL leaves `navigator.mediaDevices` undefined on iOS/Android — the permission won't stick and re-prompts every reload. `localhost` on the Mac itself is exempt. Easiest fix: `tailscale serve --bg 4317` then open the `https://<host>.ts.net` URL. Or run with your own cert: `TLS_CERT=cert.pem TLS_KEY=key.pem claude-control`.
31
33
  - **Prompt enhancer (✨)** — defaults to a **local MLX model** on Apple Silicon. One-time setup:
32
34
  ```bash
33
35
  python3 -m venv ~/.claude-control/mlx-venv
package/bin/setup.sh CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/bin/bash
2
- # claude-control setup — install local dependencies for voice transcription.
2
+ # claude-control setup — install local dependencies (voice + raw terminal).
3
3
  #
4
- # Whisper.cpp is NOT bundled. The 🎤 voice input needs three things, all local
5
- # (no API key, no cloud): ffmpeg, the whisper-cli binary (Homebrew `whisper-cpp`),
6
- # and a ggml model under ~/.claude-control/models. This installs/downloads them
4
+ # None of these are bundled. The 🎤 voice input needs ffmpeg, the whisper-cli
5
+ # binary (Homebrew `whisper-cpp`), and a ggml model under ~/.claude-control/models.
6
+ # The in-browser raw terminal needs ttyd. This installs/downloads them all
7
7
  # idempotently. tmux (required to run the app at all) is checked too.
8
8
  set -uo pipefail
9
9
 
@@ -28,8 +28,10 @@ if ! command -v brew >/dev/null 2>&1; then
28
28
  exit 1
29
29
  fi
30
30
 
31
- say "Installing ffmpeg + whisper-cpp (Homebrew, skips if already present)…"
32
- brew install ffmpeg whisper-cpp || {
31
+ say "Installing ffmpeg + whisper-cpp + ttyd (Homebrew, skips if already present)…"
32
+ # ttyd powers the in-browser raw tmux terminal; the server spawns/manages it on
33
+ # demand (no daemon to start), but the binary must exist first.
34
+ brew install ffmpeg whisper-cpp ttyd || {
33
35
  bad "brew install failed — see output above"
34
36
  exit 1
35
37
  }
@@ -50,10 +52,11 @@ else
50
52
  fi
51
53
  fi
52
54
 
53
- say "Verifying voice-transcription chain…"
55
+ say "Verifying local dependencies…"
54
56
  command -v ffmpeg >/dev/null 2>&1 && ok "ffmpeg: $(command -v ffmpeg)" || bad "ffmpeg missing"
55
57
  command -v whisper-cli >/dev/null 2>&1 && ok "whisper-cli: $(command -v whisper-cli)" || bad "whisper-cli missing (brew install whisper-cpp)"
56
58
  ls "$MODELS_DIR"/ggml-*.bin >/dev/null 2>&1 && ok "model: $(ls "$MODELS_DIR"/ggml-*.bin | head -1)" || bad "no ggml model in $MODELS_DIR"
59
+ command -v ttyd >/dev/null 2>&1 && ok "ttyd: $(command -v ttyd)" || bad "ttyd missing (brew install ttyd) — raw in-browser terminal won't work without it"
57
60
 
58
61
  say "Done. The 🎤 mic (voice → text) is ready."
59
62
  echo " Note: the MLX prompt-enhancer (optional) is separate; the optimiser falls"
package/lib/config.js CHANGED
@@ -45,6 +45,12 @@ const CLAUDE_BIN_MAX = 500;
45
45
  const MLX_MODEL_MAX = 200;
46
46
  const OPTIMIZE_BACKENDS = ['mlx', 'claude', 'rules'];
47
47
 
48
+ // Transcript font-size: integer px values the user can choose.
49
+ // Base range: 12-18px. External-display range: 12-22px (larger monitor benefit).
50
+ const FONT_SIZE_MIN = 12;
51
+ const FONT_SIZE_MAX = 18;
52
+ const EXT_FONT_SIZE_MAX = 22;
53
+
48
54
  /** Defaults, recomputed each call so a changed HOME/env is honoured. */
49
55
  function defaults() {
50
56
  return {
@@ -57,6 +63,11 @@ function defaults() {
57
63
  optimizeBackend: 'mlx',
58
64
  // Default MLX model auto-picked for this machine's unified memory.
59
65
  mlxModel: recommendMlxModel(detectMachine().ramGB),
66
+ // Transcript font-size (px). 0 = use the CSS default (--txt-transcript).
67
+ // transcriptFontSize applies on non-external-display (base / iPad).
68
+ // externalFontSize applies ONLY when body.is-external-display is set.
69
+ transcriptFontSize: 0,
70
+ externalFontSize: 0,
60
71
  };
61
72
  }
62
73
 
@@ -64,7 +75,7 @@ function defaults() {
64
75
  * Read the persisted config, merged over defaults. Never throws — a missing,
65
76
  * empty, or corrupt file falls back to defaults. Only known keys are surfaced.
66
77
  *
67
- * @returns {{ launchCommand: string, defaultCwd: string, optimizeModel: string, claudeBin: string, optimizeBackend: string, mlxModel: string }}
78
+ * @returns {{ launchCommand: string, defaultCwd: string, optimizeModel: string, claudeBin: string, optimizeBackend: string, mlxModel: string, transcriptFontSize: number, externalFontSize: number }}
68
79
  */
69
80
  export function readConfig() {
70
81
  const base = defaults();
@@ -75,6 +86,13 @@ export function readConfig() {
75
86
  return base;
76
87
  }
77
88
  if (!parsed || typeof parsed !== 'object') return base;
89
+
90
+ const clampFontSize = (v, max) => {
91
+ const n = Number(v);
92
+ if (!Number.isInteger(n) || n === 0) return 0; // 0 = use CSS default
93
+ return Math.min(max, Math.max(FONT_SIZE_MIN, n));
94
+ };
95
+
78
96
  return {
79
97
  launchCommand:
80
98
  typeof parsed.launchCommand === 'string' && parsed.launchCommand.trim()
@@ -101,6 +119,14 @@ export function readConfig() {
101
119
  typeof parsed.mlxModel === 'string' && parsed.mlxModel.trim()
102
120
  ? parsed.mlxModel
103
121
  : base.mlxModel,
122
+ transcriptFontSize:
123
+ parsed.transcriptFontSize !== undefined
124
+ ? clampFontSize(parsed.transcriptFontSize, FONT_SIZE_MAX)
125
+ : base.transcriptFontSize,
126
+ externalFontSize:
127
+ parsed.externalFontSize !== undefined
128
+ ? clampFontSize(parsed.externalFontSize, EXT_FONT_SIZE_MAX)
129
+ : base.externalFontSize,
104
130
  };
105
131
  }
106
132
 
@@ -191,6 +217,28 @@ export function writeConfig(partial = {}) {
191
217
  next.mlxModel = m;
192
218
  }
193
219
 
220
+ if (partial.transcriptFontSize !== undefined) {
221
+ const n = Number(partial.transcriptFontSize);
222
+ if (!Number.isFinite(n) || !Number.isInteger(n)) {
223
+ throw new Error('transcriptFontSize must be an integer');
224
+ }
225
+ if (n !== 0 && (n < FONT_SIZE_MIN || n > FONT_SIZE_MAX)) {
226
+ throw new Error(`transcriptFontSize must be 0 or ${FONT_SIZE_MIN}–${FONT_SIZE_MAX}`);
227
+ }
228
+ next.transcriptFontSize = n;
229
+ }
230
+
231
+ if (partial.externalFontSize !== undefined) {
232
+ const n = Number(partial.externalFontSize);
233
+ if (!Number.isFinite(n) || !Number.isInteger(n)) {
234
+ throw new Error('externalFontSize must be an integer');
235
+ }
236
+ if (n !== 0 && (n < FONT_SIZE_MIN || n > EXT_FONT_SIZE_MAX)) {
237
+ throw new Error(`externalFontSize must be 0 or ${FONT_SIZE_MIN}–${EXT_FONT_SIZE_MAX}`);
238
+ }
239
+ next.externalFontSize = n;
240
+ }
241
+
194
242
  const dir = dataDir();
195
243
  fs.mkdirSync(dir, { recursive: true });
196
244
  fs.writeFileSync(configPath(), JSON.stringify(next, null, 2), { mode: 0o600 });
package/lib/optimize.js CHANGED
@@ -107,16 +107,11 @@ export function rulesOptimize(input) {
107
107
  optimized = stripped;
108
108
  }
109
109
 
110
- // Step 3: detect missing structure
110
+ // Step 3: note (don't inject) a weak imperative. We deliberately do NOT prepend
111
+ // a "Goal:" line — "Goal:" reads as the /goal full-autonomy directive and must
112
+ // never be added by accident (the user explicitly opted out of this rewrite).
111
113
  if (!hasImperativeGoal(optimized)) {
112
- changes.push('Goal not stated as a clear imperative up front.');
113
- // Restructure: extract first sentence/clause as Goal line
114
- const firstSentenceEnd = optimized.search(/[.!?\n]/);
115
- const firstClause =
116
- firstSentenceEnd > 0 ? optimized.slice(0, firstSentenceEnd) : optimized;
117
- const rest = firstSentenceEnd > 0 ? optimized.slice(firstSentenceEnd + 1).trimStart() : '';
118
- optimized = `Goal: ${firstClause}${rest ? '\n\n' + rest : ''}`;
119
- rationale.push('Prepended "Goal:" line so the imperative comes first.');
114
+ changes.push('Consider leading with a clear imperative (verb-first).');
120
115
  }
121
116
 
122
117
  if (!mentionsOutputFormat(optimized)) {
package/lib/sessions.js CHANGED
@@ -500,6 +500,7 @@ export class SessionRegistry extends EventEmitter {
500
500
  transcriptPath: transcript?.transcriptPath ?? null,
501
501
  pinned: isPinned,
502
502
  lastActivity: transcript?.lastActivity ?? null,
503
+ lastActivityMs: transcript?.lastActivityMs ?? null,
503
504
  pending,
504
505
  pendingQuestion: transcript?.pendingQuestion ?? panePrompt?.question ?? null,
505
506
  cmd: win.cmd,
package/lib/subagents.js CHANGED
@@ -32,6 +32,9 @@ const META_RE = /^agent-(.+)\.meta\.json$/;
32
32
  // LLM pauses while still expiring stale-but-finished agents whose tool_result
33
33
  // predates the bounded parent buffer. doneByParent always wins when available.
34
34
  const RUNNING_WINDOW_MS = 600_000;
35
+ // A file written within this window is treated as actively-running, overriding a
36
+ // (possibly premature, e.g. background-launch-ack) doneByParent flag.
37
+ const ACTIVE_WINDOW_MS = 20_000;
35
38
 
36
39
  // ---------------------------------------------------------------------------
37
40
  // Agent definition front-matter cache + discovery
@@ -138,6 +141,109 @@ function _lookupAgentDef(agentType) {
138
141
  return null;
139
142
  }
140
143
 
144
+ // ---------------------------------------------------------------------------
145
+ // Agent listing — mirrors lib/skills.js `listSkills` pattern
146
+ // ---------------------------------------------------------------------------
147
+
148
+ /** 30-second TTL for the agent list cache. */
149
+ const AGENTS_CACHE_TTL_MS = 30_000;
150
+
151
+ /**
152
+ * Per-cwd cache so different sessions each get their own merged agent list.
153
+ * Key: cwd string (or '' for the process-cwd-only list).
154
+ * @type {Map<string, { agents: AgentEntry[], ts: number }>}
155
+ */
156
+ const _agentsCache = new Map();
157
+
158
+ /**
159
+ * @typedef {{ name: string, description: string, source: 'user' | 'project' | 'plugin' }} AgentEntry
160
+ */
161
+
162
+ /**
163
+ * Discover all available agent definitions for a given session cwd.
164
+ * Merges roots from `_agentSearchRoots()` (user + plugin + process.cwd agents)
165
+ * plus the session-specific cwd agents dir when provided.
166
+ *
167
+ * Priority (highest → lowest): project > user > plugin.
168
+ * Implemented by processing roots in order plugin → user → project and
169
+ * overwriting on name clash (later entry wins), which yields project-last = wins.
170
+ *
171
+ * Results are cached per-cwd for AGENTS_CACHE_TTL_MS.
172
+ *
173
+ * @param {string|null} [cwd] the session's working directory; null = no project agents
174
+ * @returns {AgentEntry[]}
175
+ */
176
+ export function listAgents(cwd) {
177
+ const cacheKey = cwd ?? '';
178
+ const now = Date.now();
179
+ const hit = _agentsCache.get(cacheKey);
180
+ if (hit && now - hit.ts < AGENTS_CACHE_TTL_MS) {
181
+ return hit.agents;
182
+ }
183
+
184
+ const home = os.homedir();
185
+ const pluginCacheRoot = path.join(home, '.claude', 'plugins', 'cache');
186
+
187
+ // Collect roots from _agentSearchRoots() (includes user + plugin cache + process.cwd agents).
188
+ const baseRoots = _agentSearchRoots();
189
+
190
+ // Also include the session-specific cwd agents dir when it differs from process.cwd().
191
+ const cwdAgentsDir = cwd ? path.join(cwd, '.claude', 'agents') : null;
192
+ const allRoots = cwdAgentsDir && !baseRoots.includes(cwdAgentsDir)
193
+ ? [...baseRoots, cwdAgentsDir]
194
+ : baseRoots;
195
+
196
+ /**
197
+ * Classify a root by source priority.
198
+ * Plugin roots live under ~/.claude/plugins/cache.
199
+ * The user root is ~/.claude/agents.
200
+ * Everything else is treated as project (cwd-local).
201
+ *
202
+ * We process in order: plugin → user → project so that when names clash
203
+ * the last write wins, giving project > user > plugin precedence.
204
+ */
205
+ const classifyRoot = (/** @type {string} */ dir) => {
206
+ if (dir.startsWith(pluginCacheRoot + path.sep) || dir === pluginCacheRoot) return 'plugin';
207
+ if (dir === path.join(home, '.claude', 'agents')) return 'user';
208
+ return 'project';
209
+ };
210
+
211
+ // Sort roots: plugin first, then user, then project (so project overwrites on clash).
212
+ const priority = { plugin: 0, user: 1, project: 2 };
213
+ const sortedRoots = [...allRoots].sort((a, b) => priority[classifyRoot(a)] - priority[classifyRoot(b)]);
214
+
215
+ /** @type {Map<string, AgentEntry>} */
216
+ const byName = new Map();
217
+
218
+ for (const dir of sortedRoots) {
219
+ const source = classifyRoot(dir);
220
+ let files;
221
+ try { files = fs.readdirSync(dir); } catch { continue; }
222
+ for (const filename of files) {
223
+ if (!filename.endsWith('.md')) continue;
224
+ const filePath = path.join(dir, filename);
225
+ let content;
226
+ try { content = fs.readFileSync(filePath, 'utf8'); } catch { continue; }
227
+ const fm = _parseFrontMatter(content);
228
+ const name = fm?.name?.trim() || filename.slice(0, -3); // sans .md
229
+ const description = fm?.description ?? '';
230
+ // Overwrite unconditionally — sortedRoots ordering ensures project wins last.
231
+ byName.set(name, { name, description, source });
232
+ }
233
+ }
234
+
235
+ const agents = [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
236
+ _agentsCache.set(cacheKey, { agents, ts: now });
237
+ return agents;
238
+ }
239
+
240
+ /**
241
+ * Bust the in-process agents cache. Used in tests.
242
+ */
243
+ export function _bustAgentsCache() {
244
+ _agentsCache.clear();
245
+ }
246
+
141
247
  export class SubAgentsWatcher extends EventEmitter {
142
248
  /**
143
249
  * @param {string} transcriptPath absolute path to the PARENT transcript
@@ -261,13 +367,23 @@ export class SubAgentsWatcher extends EventEmitter {
261
367
  * even when their parent tool_result predates the bounded message buffer.
262
368
  */
263
369
  _statusFor(a) {
264
- if (a.doneByParent) return 'done';
370
+ let mtimeMs = null;
265
371
  try {
266
- const mtimeMs = fs.statSync(a.jsonlPath).mtimeMs;
267
- return Date.now() - mtimeMs < RUNNING_WINDOW_MS ? 'running' : 'done';
372
+ mtimeMs = fs.statSync(a.jsonlPath).mtimeMs;
268
373
  } catch {
269
374
  return 'done';
270
375
  }
376
+ const age = Date.now() - mtimeMs;
377
+ // Actively being written → RUNNING, even if the parent already emitted a
378
+ // tool_result for this agent. A BACKGROUND agent's launch-ack tool_result
379
+ // lands IMMEDIATELY (setting doneByParent) while the agent keeps writing for
380
+ // minutes — without this override it would wrongly read as done the whole run.
381
+ if (age < ACTIVE_WINDOW_MS) return 'running';
382
+ // Quiet file: the parent's tool_result is now authoritative (foreground agents
383
+ // go quiet exactly at completion → done within ACTIVE_WINDOW). Otherwise fall
384
+ // back to the longer freshness window (covers long mid-inference pauses).
385
+ if (a.doneByParent) return 'done';
386
+ return age < RUNNING_WINDOW_MS ? 'running' : 'done';
271
387
  }
272
388
 
273
389
  _entry(a) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idl3/claude-control",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "description": "Local web UI to watch and drive your Claude Code sessions running in tmux — live transcripts, reply, answer AskUserQuestion, attach files, from a browser or phone.",
6
6
  "keywords": [
package/server.js CHANGED
@@ -4,6 +4,7 @@
4
4
  // monitoring into a localhost web UI. Bind 127.0.0.1 only; never shell out with user text.
5
5
 
6
6
  import http from 'node:http';
7
+ import https from 'node:https';
7
8
  import net from 'node:net';
8
9
  import fs from 'node:fs';
9
10
  import path from 'node:path';
@@ -16,7 +17,7 @@ import * as tmux from './lib/tmux.js';
16
17
  import * as terminal from './lib/terminal.js';
17
18
  import * as shell from './lib/shell.js';
18
19
  import { TranscriptTailer } from './lib/transcript.js';
19
- import { SubAgentsWatcher } from './lib/subagents.js';
20
+ import { SubAgentsWatcher, listAgents } from './lib/subagents.js';
20
21
  import { parsePanePrompt } from './lib/prompt.js';
21
22
  import { SessionRegistry, listRecentTranscripts } from './lib/sessions.js';
22
23
  import { loadPins, savePins, validateTranscriptPath, pinKey } from './lib/pins.js';
@@ -176,8 +177,33 @@ function isAllowedOrigin(origin) {
176
177
  }
177
178
  }
178
179
 
179
- // --- HTTP -------------------------------------------------------------------
180
- const server = http.createServer((req, res) => {
180
+ // --- HTTP / HTTPS -----------------------------------------------------------
181
+ // Optional TLS: set TLS_CERT and TLS_KEY to PEM file paths to serve HTTPS.
182
+ // Both must be set together; a missing file is a hard startup error.
183
+ function loadTls() {
184
+ const certPath = process.env.TLS_CERT;
185
+ const keyPath = process.env.TLS_KEY;
186
+ if (!certPath && !keyPath) return null;
187
+ if (!certPath || !keyPath) {
188
+ console.error('TLS error: both TLS_CERT and TLS_KEY must be set (only one was provided).');
189
+ process.exit(1);
190
+ }
191
+ let cert, key;
192
+ try { cert = fs.readFileSync(certPath); } catch (e) {
193
+ console.error(`TLS error: cannot read TLS_CERT "${certPath}": ${e.message}`);
194
+ process.exit(1);
195
+ }
196
+ try { key = fs.readFileSync(keyPath); } catch (e) {
197
+ console.error(`TLS error: cannot read TLS_KEY "${keyPath}": ${e.message}`);
198
+ process.exit(1);
199
+ }
200
+ return { cert, key };
201
+ }
202
+
203
+ const _tls = loadTls();
204
+ const _scheme = _tls ? 'https' : 'http';
205
+
206
+ const _handler = (req, res) => {
181
207
  const u = new URL(req.url, 'http://localhost');
182
208
 
183
209
  if (u.pathname === '/api/sessions') {
@@ -193,6 +219,13 @@ const server = http.createServer((req, res) => {
193
219
  const skillsCwd = skillsSession?.cwd ?? null;
194
220
  return endJson(res, 200, { skills: listSkills(skillsCwd) });
195
221
  }
222
+ if (u.pathname === '/api/agents') {
223
+ if (!checkToken(req)) return endJson(res, 401, { error: 'unauthorized' });
224
+ const agentsId = u.searchParams.get('id');
225
+ const agentsSession = agentsId ? sessionById(agentsId) : null;
226
+ const agentsCwd = agentsSession?.cwd ?? null;
227
+ return endJson(res, 200, { agents: listAgents(agentsCwd) });
228
+ }
196
229
  if (u.pathname === '/api/skill') {
197
230
  if (!checkToken(req)) return endJson(res, 401, { error: 'unauthorized' });
198
231
  const skillId = u.searchParams.get('id');
@@ -357,7 +390,11 @@ const server = http.createServer((req, res) => {
357
390
 
358
391
  // static
359
392
  serveStatic(u.pathname, res);
360
- });
393
+ };
394
+
395
+ const server = _tls
396
+ ? https.createServer(_tls, _handler)
397
+ : http.createServer(_handler);
361
398
 
362
399
  // In-UI "Update now" (POST /api/update): run the self-update script DETACHED
363
400
  // (it git-pulls, reinstalls, rebuilds the web bundle, then restarts this
@@ -1631,7 +1668,7 @@ async function main() {
1631
1668
 
1632
1669
  server.listen(CONFIG.port, CONFIG.host, () => {
1633
1670
  // eslint-disable-next-line no-console
1634
- console.log(`claude-control → http://${CONFIG.host}:${CONFIG.port}/`);
1671
+ console.log(`claude-control → ${_scheme}://${CONFIG.host}:${CONFIG.port}/`);
1635
1672
  if (CONFIG.token) {
1636
1673
  // The token is no longer carried in the URL — the web app prompts for it
1637
1674
  // on load and sends it as an Authorization header (HTTP) / subprotocol
@@ -1,3 +1,3 @@
1
- import{g as Ve}from"./index-Dku_hPFx.js";function xe(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const i=e[t],u=typeof i;(u==="object"||u==="function")&&!Object.isFrozen(i)&&xe(i)}),e}class he{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function we(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function B(e,...t){const i=Object.create(null);for(const u in e)i[u]=e[u];return t.forEach(function(u){for(const b in u)i[b]=u[b]}),i}const qe="</span>",pe=e=>!!e.scope,Qe=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const i=e.split(".");return[`${t}${i.shift()}`,...i.map((u,b)=>`${u}${"_".repeat(b+1)}`)].join(" ")}return`${t}${e}`};class me{constructor(t,i){this.buffer="",this.classPrefix=i.classPrefix,t.walk(this)}addText(t){this.buffer+=we(t)}openNode(t){if(!pe(t))return;const i=Qe(t.scope,{prefix:this.classPrefix});this.span(i)}closeNode(t){pe(t)&&(this.buffer+=qe)}value(){return this.buffer}span(t){this.buffer+=`<span class="${t}">`}}const de=(e={})=>{const t={children:[]};return Object.assign(t,e),t};class te{constructor(){this.rootNode=de(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){const i=de({scope:t});this.add(i),this.stack.push(i)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,i){return typeof i=="string"?t.addText(i):i.children&&(t.openNode(i),i.children.forEach(u=>this._walk(t,u)),t.closeNode(i)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(i=>typeof i=="string")?t.children=[t.children.join("")]:t.children.forEach(i=>{te._collapse(i)}))}}class et extends te{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,i){const u=t.root;i&&(u.scope=`language:${i}`),this.add(u)}toHTML(){return new me(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function P(e){return e?typeof e=="string"?e:e.source:null}function Oe(e){return C("(?=",e,")")}function tt(e){return C("(?:",e,")*")}function nt(e){return C("(?:",e,")?")}function C(...e){return e.map(i=>P(i)).join("")}function it(e){const t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function ne(...e){return"("+(it(e).capture?"":"?:")+e.map(u=>P(u)).join("|")+")"}function Re(e){return new RegExp(e.toString()+"|").exec("").length-1}function st(e,t){const i=e&&e.exec(t);return i&&i.index===0}const rt=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function ie(e,{joinWith:t}){let i=0;return e.map(u=>{i+=1;const b=i;let _=P(u),c="";for(;_.length>0;){const r=rt.exec(_);if(!r){c+=_;break}c+=_.substring(0,r.index),_=_.substring(r.index+r[0].length),r[0][0]==="\\"&&r[1]?c+="\\"+String(Number(r[1])+b):(c+=r[0],r[0]==="("&&i++)}return c}).map(u=>`(${u})`).join(t)}const ct=/\b\B/,ye="[a-zA-Z]\\w*",se="[a-zA-Z_]\\w*",Se="\\b\\d+(\\.\\d+)?",Ne="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",Ae="\\b(0b[01]+)",ot="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",at=(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=C(t,/.*\b/,e.binary,/\b.*/)),B({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(i,u)=>{i.index!==0&&u.ignoreMatch()}},e)},U={begin:"\\\\[\\s\\S]",relevance:0},lt={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[U]},ut={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[U]},ft={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Y=function(e,t,i={}){const u=B({scope:"comment",begin:e,end:t,contains:[]},i);u.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const b=ne("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return u.contains.push({begin:C(/[ ]+/,"(",b,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),u},gt=Y("//","$"),ht=Y("/\\*","\\*/"),pt=Y("#","$"),dt={scope:"number",begin:Se,relevance:0},Et={scope:"number",begin:Ne,relevance:0},bt={scope:"number",begin:Ae,relevance:0},_t={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[U,{begin:/\[/,end:/\]/,relevance:0,contains:[U]}]},Mt={scope:"title",begin:ye,relevance:0},xt={scope:"title",begin:se,relevance:0},wt={begin:"\\.\\s*"+se,relevance:0},Ot=function(e){return Object.assign(e,{"on:begin":(t,i)=>{i.data._beginMatch=t[1]},"on:end":(t,i)=>{i.data._beginMatch!==t[1]&&i.ignoreMatch()}})};var z=Object.freeze({__proto__:null,APOS_STRING_MODE:lt,BACKSLASH_ESCAPE:U,BINARY_NUMBER_MODE:bt,BINARY_NUMBER_RE:Ae,COMMENT:Y,C_BLOCK_COMMENT_MODE:ht,C_LINE_COMMENT_MODE:gt,C_NUMBER_MODE:Et,C_NUMBER_RE:Ne,END_SAME_AS_BEGIN:Ot,HASH_COMMENT_MODE:pt,IDENT_RE:ye,MATCH_NOTHING_RE:ct,METHOD_GUARD:wt,NUMBER_MODE:dt,NUMBER_RE:Se,PHRASAL_WORDS_MODE:ft,QUOTE_STRING_MODE:ut,REGEXP_MODE:_t,RE_STARTERS_RE:ot,SHEBANG:at,TITLE_MODE:Mt,UNDERSCORE_IDENT_RE:se,UNDERSCORE_TITLE_MODE:xt});function Rt(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function yt(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function St(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=Rt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Nt(e,t){Array.isArray(e.illegal)&&(e.illegal=ne(...e.illegal))}function At(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function kt(e,t){e.relevance===void 0&&(e.relevance=1)}const Tt=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");const i=Object.assign({},e);Object.keys(e).forEach(u=>{delete e[u]}),e.keywords=i.keywords,e.begin=C(i.beforeMatch,Oe(i.begin)),e.starts={relevance:0,contains:[Object.assign(i,{endsParent:!0})]},e.relevance=0,delete i.beforeMatch},It=["of","and","for","in","not","or","if","then","parent","list","value"],Bt="keyword";function ke(e,t,i=Bt){const u=Object.create(null);return typeof e=="string"?b(i,e.split(" ")):Array.isArray(e)?b(i,e):Object.keys(e).forEach(function(_){Object.assign(u,ke(e[_],t,_))}),u;function b(_,c){t&&(c=c.map(r=>r.toLowerCase())),c.forEach(function(r){const l=r.split("|");u[l[0]]=[_,Dt(l[0],l[1])]})}}function Dt(e,t){return t?Number(t):vt(e)?0:1}function vt(e){return It.includes(e.toLowerCase())}const Ee={},v=e=>{console.error(e)},be=(e,...t)=>{console.log(`WARN: ${e}`,...t)},L=(e,t)=>{Ee[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Ee[`${e}/${t}`]=!0)},X=new Error;function Te(e,t,{key:i}){let u=0;const b=e[i],_={},c={};for(let r=1;r<=t.length;r++)c[r+u]=b[r],_[r+u]=!0,u+=Re(t[r-1]);e[i]=c,e[i]._emit=_,e[i]._multi=!0}function Ct(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw v("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),X;if(typeof e.beginScope!="object"||e.beginScope===null)throw v("beginScope must be object"),X;Te(e,e.begin,{key:"beginScope"}),e.begin=ie(e.begin,{joinWith:""})}}function Lt(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw v("skip, excludeEnd, returnEnd not compatible with endScope: {}"),X;if(typeof e.endScope!="object"||e.endScope===null)throw v("endScope must be object"),X;Te(e,e.end,{key:"endScope"}),e.end=ie(e.end,{joinWith:""})}}function Ht(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function jt(e){Ht(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),Ct(e),Lt(e)}function Pt(e){function t(c,r){return new RegExp(P(c),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(r?"g":""))}class i{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(r,l){l.position=this.position++,this.matchIndexes[this.matchAt]=l,this.regexes.push([l,r]),this.matchAt+=Re(r)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const r=this.regexes.map(l=>l[1]);this.matcherRe=t(ie(r,{joinWith:"|"}),!0),this.lastIndex=0}exec(r){this.matcherRe.lastIndex=this.lastIndex;const l=this.matcherRe.exec(r);if(!l)return null;const w=l.findIndex((j,Z)=>Z>0&&j!==void 0),M=this.matchIndexes[w];return l.splice(0,w),Object.assign(l,M)}}class u{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(r){if(this.multiRegexes[r])return this.multiRegexes[r];const l=new i;return this.rules.slice(r).forEach(([w,M])=>l.addRule(w,M)),l.compile(),this.multiRegexes[r]=l,l}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(r,l){this.rules.push([r,l]),l.type==="begin"&&this.count++}exec(r){const l=this.getMatcher(this.regexIndex);l.lastIndex=this.lastIndex;let w=l.exec(r);if(this.resumingScanAtSamePosition()&&!(w&&w.index===this.lastIndex)){const M=this.getMatcher(0);M.lastIndex=this.lastIndex+1,w=M.exec(r)}return w&&(this.regexIndex+=w.position+1,this.regexIndex===this.count&&this.considerAll()),w}}function b(c){const r=new u;return c.contains.forEach(l=>r.addRule(l.begin,{rule:l,type:"begin"})),c.terminatorEnd&&r.addRule(c.terminatorEnd,{type:"end"}),c.illegal&&r.addRule(c.illegal,{type:"illegal"}),r}function _(c,r){const l=c;if(c.isCompiled)return l;[yt,At,jt,Tt].forEach(M=>M(c,r)),e.compilerExtensions.forEach(M=>M(c,r)),c.__beforeBegin=null,[St,Nt,kt].forEach(M=>M(c,r)),c.isCompiled=!0;let w=null;return typeof c.keywords=="object"&&c.keywords.$pattern&&(c.keywords=Object.assign({},c.keywords),w=c.keywords.$pattern,delete c.keywords.$pattern),w=w||/\w+/,c.keywords&&(c.keywords=ke(c.keywords,e.case_insensitive)),l.keywordPatternRe=t(w,!0),r&&(c.begin||(c.begin=/\B|\b/),l.beginRe=t(l.begin),!c.end&&!c.endsWithParent&&(c.end=/\B|\b/),c.end&&(l.endRe=t(l.end)),l.terminatorEnd=P(l.end)||"",c.endsWithParent&&r.terminatorEnd&&(l.terminatorEnd+=(c.end?"|":"")+r.terminatorEnd)),c.illegal&&(l.illegalRe=t(c.illegal)),c.contains||(c.contains=[]),c.contains=[].concat(...c.contains.map(function(M){return Ut(M==="self"?c:M)})),c.contains.forEach(function(M){_(M,l)}),c.starts&&_(c.starts,r),l.matcher=b(l),l}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=B(e.classNameAliases||{}),_(e)}function Ie(e){return e?e.endsWithParent||Ie(e.starts):!1}function Ut(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return B(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:Ie(e)?B(e,{starts:e.starts?B(e.starts):null}):Object.isFrozen(e)?B(e):e}var $t="11.11.1";class Gt extends Error{constructor(t,i){super(t),this.name="HTMLInjectionError",this.html=i}}const ee=we,_e=B,Me=Symbol("nomatch"),Wt=7,Be=function(e){const t=Object.create(null),i=Object.create(null),u=[];let b=!0;const _="Could not find the language '{}', did you forget to load/include a language module?",c={disableAutodetect:!0,name:"Plain text",contains:[]};let r={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:et};function l(n){return r.noHighlightRe.test(n)}function w(n){let a=n.className+" ";a+=n.parentNode?n.parentNode.className:"";const h=r.languageDetectRe.exec(a);if(h){const d=T(h[1]);return d||(be(_.replace("{}",h[1])),be("Falling back to no-highlight mode for this block.",n)),d?h[1]:"no-highlight"}return a.split(/\s+/).find(d=>l(d)||T(d))}function M(n,a,h){let d="",x="";typeof a=="object"?(d=n,h=a.ignoreIllegals,x=a.language):(L("10.7.0","highlight(lang, code, ...args) has been deprecated."),L("10.7.0",`Please use highlight(code, options) instead.
1
+ import{g as Ve}from"./index-CgHrw_VR.js";function xe(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const i=e[t],u=typeof i;(u==="object"||u==="function")&&!Object.isFrozen(i)&&xe(i)}),e}class he{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function we(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function B(e,...t){const i=Object.create(null);for(const u in e)i[u]=e[u];return t.forEach(function(u){for(const b in u)i[b]=u[b]}),i}const qe="</span>",pe=e=>!!e.scope,Qe=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const i=e.split(".");return[`${t}${i.shift()}`,...i.map((u,b)=>`${u}${"_".repeat(b+1)}`)].join(" ")}return`${t}${e}`};class me{constructor(t,i){this.buffer="",this.classPrefix=i.classPrefix,t.walk(this)}addText(t){this.buffer+=we(t)}openNode(t){if(!pe(t))return;const i=Qe(t.scope,{prefix:this.classPrefix});this.span(i)}closeNode(t){pe(t)&&(this.buffer+=qe)}value(){return this.buffer}span(t){this.buffer+=`<span class="${t}">`}}const de=(e={})=>{const t={children:[]};return Object.assign(t,e),t};class te{constructor(){this.rootNode=de(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){const i=de({scope:t});this.add(i),this.stack.push(i)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,i){return typeof i=="string"?t.addText(i):i.children&&(t.openNode(i),i.children.forEach(u=>this._walk(t,u)),t.closeNode(i)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(i=>typeof i=="string")?t.children=[t.children.join("")]:t.children.forEach(i=>{te._collapse(i)}))}}class et extends te{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,i){const u=t.root;i&&(u.scope=`language:${i}`),this.add(u)}toHTML(){return new me(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function P(e){return e?typeof e=="string"?e:e.source:null}function Oe(e){return C("(?=",e,")")}function tt(e){return C("(?:",e,")*")}function nt(e){return C("(?:",e,")?")}function C(...e){return e.map(i=>P(i)).join("")}function it(e){const t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function ne(...e){return"("+(it(e).capture?"":"?:")+e.map(u=>P(u)).join("|")+")"}function Re(e){return new RegExp(e.toString()+"|").exec("").length-1}function st(e,t){const i=e&&e.exec(t);return i&&i.index===0}const rt=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function ie(e,{joinWith:t}){let i=0;return e.map(u=>{i+=1;const b=i;let _=P(u),c="";for(;_.length>0;){const r=rt.exec(_);if(!r){c+=_;break}c+=_.substring(0,r.index),_=_.substring(r.index+r[0].length),r[0][0]==="\\"&&r[1]?c+="\\"+String(Number(r[1])+b):(c+=r[0],r[0]==="("&&i++)}return c}).map(u=>`(${u})`).join(t)}const ct=/\b\B/,ye="[a-zA-Z]\\w*",se="[a-zA-Z_]\\w*",Se="\\b\\d+(\\.\\d+)?",Ne="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",Ae="\\b(0b[01]+)",ot="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",at=(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=C(t,/.*\b/,e.binary,/\b.*/)),B({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(i,u)=>{i.index!==0&&u.ignoreMatch()}},e)},U={begin:"\\\\[\\s\\S]",relevance:0},lt={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[U]},ut={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[U]},ft={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Y=function(e,t,i={}){const u=B({scope:"comment",begin:e,end:t,contains:[]},i);u.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const b=ne("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return u.contains.push({begin:C(/[ ]+/,"(",b,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),u},gt=Y("//","$"),ht=Y("/\\*","\\*/"),pt=Y("#","$"),dt={scope:"number",begin:Se,relevance:0},Et={scope:"number",begin:Ne,relevance:0},bt={scope:"number",begin:Ae,relevance:0},_t={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[U,{begin:/\[/,end:/\]/,relevance:0,contains:[U]}]},Mt={scope:"title",begin:ye,relevance:0},xt={scope:"title",begin:se,relevance:0},wt={begin:"\\.\\s*"+se,relevance:0},Ot=function(e){return Object.assign(e,{"on:begin":(t,i)=>{i.data._beginMatch=t[1]},"on:end":(t,i)=>{i.data._beginMatch!==t[1]&&i.ignoreMatch()}})};var z=Object.freeze({__proto__:null,APOS_STRING_MODE:lt,BACKSLASH_ESCAPE:U,BINARY_NUMBER_MODE:bt,BINARY_NUMBER_RE:Ae,COMMENT:Y,C_BLOCK_COMMENT_MODE:ht,C_LINE_COMMENT_MODE:gt,C_NUMBER_MODE:Et,C_NUMBER_RE:Ne,END_SAME_AS_BEGIN:Ot,HASH_COMMENT_MODE:pt,IDENT_RE:ye,MATCH_NOTHING_RE:ct,METHOD_GUARD:wt,NUMBER_MODE:dt,NUMBER_RE:Se,PHRASAL_WORDS_MODE:ft,QUOTE_STRING_MODE:ut,REGEXP_MODE:_t,RE_STARTERS_RE:ot,SHEBANG:at,TITLE_MODE:Mt,UNDERSCORE_IDENT_RE:se,UNDERSCORE_TITLE_MODE:xt});function Rt(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function yt(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function St(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=Rt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Nt(e,t){Array.isArray(e.illegal)&&(e.illegal=ne(...e.illegal))}function At(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function kt(e,t){e.relevance===void 0&&(e.relevance=1)}const Tt=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");const i=Object.assign({},e);Object.keys(e).forEach(u=>{delete e[u]}),e.keywords=i.keywords,e.begin=C(i.beforeMatch,Oe(i.begin)),e.starts={relevance:0,contains:[Object.assign(i,{endsParent:!0})]},e.relevance=0,delete i.beforeMatch},It=["of","and","for","in","not","or","if","then","parent","list","value"],Bt="keyword";function ke(e,t,i=Bt){const u=Object.create(null);return typeof e=="string"?b(i,e.split(" ")):Array.isArray(e)?b(i,e):Object.keys(e).forEach(function(_){Object.assign(u,ke(e[_],t,_))}),u;function b(_,c){t&&(c=c.map(r=>r.toLowerCase())),c.forEach(function(r){const l=r.split("|");u[l[0]]=[_,Dt(l[0],l[1])]})}}function Dt(e,t){return t?Number(t):vt(e)?0:1}function vt(e){return It.includes(e.toLowerCase())}const Ee={},v=e=>{console.error(e)},be=(e,...t)=>{console.log(`WARN: ${e}`,...t)},L=(e,t)=>{Ee[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Ee[`${e}/${t}`]=!0)},X=new Error;function Te(e,t,{key:i}){let u=0;const b=e[i],_={},c={};for(let r=1;r<=t.length;r++)c[r+u]=b[r],_[r+u]=!0,u+=Re(t[r-1]);e[i]=c,e[i]._emit=_,e[i]._multi=!0}function Ct(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw v("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),X;if(typeof e.beginScope!="object"||e.beginScope===null)throw v("beginScope must be object"),X;Te(e,e.begin,{key:"beginScope"}),e.begin=ie(e.begin,{joinWith:""})}}function Lt(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw v("skip, excludeEnd, returnEnd not compatible with endScope: {}"),X;if(typeof e.endScope!="object"||e.endScope===null)throw v("endScope must be object"),X;Te(e,e.end,{key:"endScope"}),e.end=ie(e.end,{joinWith:""})}}function Ht(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function jt(e){Ht(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),Ct(e),Lt(e)}function Pt(e){function t(c,r){return new RegExp(P(c),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(r?"g":""))}class i{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(r,l){l.position=this.position++,this.matchIndexes[this.matchAt]=l,this.regexes.push([l,r]),this.matchAt+=Re(r)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const r=this.regexes.map(l=>l[1]);this.matcherRe=t(ie(r,{joinWith:"|"}),!0),this.lastIndex=0}exec(r){this.matcherRe.lastIndex=this.lastIndex;const l=this.matcherRe.exec(r);if(!l)return null;const w=l.findIndex((j,Z)=>Z>0&&j!==void 0),M=this.matchIndexes[w];return l.splice(0,w),Object.assign(l,M)}}class u{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(r){if(this.multiRegexes[r])return this.multiRegexes[r];const l=new i;return this.rules.slice(r).forEach(([w,M])=>l.addRule(w,M)),l.compile(),this.multiRegexes[r]=l,l}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(r,l){this.rules.push([r,l]),l.type==="begin"&&this.count++}exec(r){const l=this.getMatcher(this.regexIndex);l.lastIndex=this.lastIndex;let w=l.exec(r);if(this.resumingScanAtSamePosition()&&!(w&&w.index===this.lastIndex)){const M=this.getMatcher(0);M.lastIndex=this.lastIndex+1,w=M.exec(r)}return w&&(this.regexIndex+=w.position+1,this.regexIndex===this.count&&this.considerAll()),w}}function b(c){const r=new u;return c.contains.forEach(l=>r.addRule(l.begin,{rule:l,type:"begin"})),c.terminatorEnd&&r.addRule(c.terminatorEnd,{type:"end"}),c.illegal&&r.addRule(c.illegal,{type:"illegal"}),r}function _(c,r){const l=c;if(c.isCompiled)return l;[yt,At,jt,Tt].forEach(M=>M(c,r)),e.compilerExtensions.forEach(M=>M(c,r)),c.__beforeBegin=null,[St,Nt,kt].forEach(M=>M(c,r)),c.isCompiled=!0;let w=null;return typeof c.keywords=="object"&&c.keywords.$pattern&&(c.keywords=Object.assign({},c.keywords),w=c.keywords.$pattern,delete c.keywords.$pattern),w=w||/\w+/,c.keywords&&(c.keywords=ke(c.keywords,e.case_insensitive)),l.keywordPatternRe=t(w,!0),r&&(c.begin||(c.begin=/\B|\b/),l.beginRe=t(l.begin),!c.end&&!c.endsWithParent&&(c.end=/\B|\b/),c.end&&(l.endRe=t(l.end)),l.terminatorEnd=P(l.end)||"",c.endsWithParent&&r.terminatorEnd&&(l.terminatorEnd+=(c.end?"|":"")+r.terminatorEnd)),c.illegal&&(l.illegalRe=t(c.illegal)),c.contains||(c.contains=[]),c.contains=[].concat(...c.contains.map(function(M){return Ut(M==="self"?c:M)})),c.contains.forEach(function(M){_(M,l)}),c.starts&&_(c.starts,r),l.matcher=b(l),l}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=B(e.classNameAliases||{}),_(e)}function Ie(e){return e?e.endsWithParent||Ie(e.starts):!1}function Ut(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return B(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:Ie(e)?B(e,{starts:e.starts?B(e.starts):null}):Object.isFrozen(e)?B(e):e}var $t="11.11.1";class Gt extends Error{constructor(t,i){super(t),this.name="HTMLInjectionError",this.html=i}}const ee=we,_e=B,Me=Symbol("nomatch"),Wt=7,Be=function(e){const t=Object.create(null),i=Object.create(null),u=[];let b=!0;const _="Could not find the language '{}', did you forget to load/include a language module?",c={disableAutodetect:!0,name:"Plain text",contains:[]};let r={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:et};function l(n){return r.noHighlightRe.test(n)}function w(n){let a=n.className+" ";a+=n.parentNode?n.parentNode.className:"";const h=r.languageDetectRe.exec(a);if(h){const d=T(h[1]);return d||(be(_.replace("{}",h[1])),be("Falling back to no-highlight mode for this block.",n)),d?h[1]:"no-highlight"}return a.split(/\s+/).find(d=>l(d)||T(d))}function M(n,a,h){let d="",x="";typeof a=="object"?(d=n,h=a.ignoreIllegals,x=a.language):(L("10.7.0","highlight(lang, code, ...args) has been deprecated."),L("10.7.0",`Please use highlight(code, options) instead.
2
2
  https://github.com/highlightjs/highlight.js/issues/2277`),x=n,d=a),h===void 0&&(h=!0);const S={code:d,language:x};G("before:highlight",S);const I=S.result?S.result:j(S.language,S.code,h);return I.code=S.code,G("after:highlight",I),I}function j(n,a,h,d){const x=Object.create(null);function S(s,o){return s.keywords[o]}function I(){if(!f.keywords){O.addText(E);return}let s=0;f.keywordPatternRe.lastIndex=0;let o=f.keywordPatternRe.exec(E),g="";for(;o;){g+=E.substring(s,o.index);const p=A.case_insensitive?o[0].toLowerCase():o[0],R=S(f,p);if(R){const[k,Ze]=R;if(O.addText(g),g="",x[p]=(x[p]||0)+1,x[p]<=Wt&&(F+=Ze),k.startsWith("_"))g+=o[0];else{const Je=A.classNameAliases[k]||k;N(o[0],Je)}}else g+=o[0];s=f.keywordPatternRe.lastIndex,o=f.keywordPatternRe.exec(E)}g+=E.substring(s),O.addText(g)}function W(){if(E==="")return;let s=null;if(typeof f.subLanguage=="string"){if(!t[f.subLanguage]){O.addText(E);return}s=j(f.subLanguage,E,!0,ge[f.subLanguage]),ge[f.subLanguage]=s._top}else s=J(E,f.subLanguage.length?f.subLanguage:null);f.relevance>0&&(F+=s.relevance),O.__addSublanguage(s._emitter,s.language)}function y(){f.subLanguage!=null?W():I(),E=""}function N(s,o){s!==""&&(O.startScope(o),O.addText(s),O.endScope())}function ae(s,o){let g=1;const p=o.length-1;for(;g<=p;){if(!s._emit[g]){g++;continue}const R=A.classNameAliases[s[g]]||s[g],k=o[g];R?N(k,R):(E=k,I(),E=""),g++}}function le(s,o){return s.scope&&typeof s.scope=="string"&&O.openNode(A.classNameAliases[s.scope]||s.scope),s.beginScope&&(s.beginScope._wrap?(N(E,A.classNameAliases[s.beginScope._wrap]||s.beginScope._wrap),E=""):s.beginScope._multi&&(ae(s.beginScope,o),E="")),f=Object.create(s,{parent:{value:f}}),f}function ue(s,o,g){let p=st(s.endRe,g);if(p){if(s["on:end"]){const R=new he(s);s["on:end"](o,R),R.isMatchIgnored&&(p=!1)}if(p){for(;s.endsParent&&s.parent;)s=s.parent;return s}}if(s.endsWithParent)return ue(s.parent,o,g)}function Ke(s){return f.matcher.regexIndex===0?(E+=s[0],1):(m=!0,0)}function Fe(s){const o=s[0],g=s.rule,p=new he(g),R=[g.__beforeBegin,g["on:begin"]];for(const k of R)if(k&&(k(s,p),p.isMatchIgnored))return Ke(o);return g.skip?E+=o:(g.excludeBegin&&(E+=o),y(),!g.returnBegin&&!g.excludeBegin&&(E=o)),le(g,s),g.returnBegin?0:o.length}function ze(s){const o=s[0],g=a.substring(s.index),p=ue(f,s,g);if(!p)return Me;const R=f;f.endScope&&f.endScope._wrap?(y(),N(o,f.endScope._wrap)):f.endScope&&f.endScope._multi?(y(),ae(f.endScope,s)):R.skip?E+=o:(R.returnEnd||R.excludeEnd||(E+=o),y(),R.excludeEnd&&(E=o));do f.scope&&O.closeNode(),!f.skip&&!f.subLanguage&&(F+=f.relevance),f=f.parent;while(f!==p.parent);return p.starts&&le(p.starts,s),R.returnEnd?0:o.length}function Xe(){const s=[];for(let o=f;o!==A;o=o.parent)o.scope&&s.unshift(o.scope);s.forEach(o=>O.openNode(o))}let K={};function fe(s,o){const g=o&&o[0];if(E+=s,g==null)return y(),0;if(K.type==="begin"&&o.type==="end"&&K.index===o.index&&g===""){if(E+=a.slice(o.index,o.index+1),!b){const p=new Error(`0 width match regex (${n})`);throw p.languageName=n,p.badRule=K.rule,p}return 1}if(K=o,o.type==="begin")return Fe(o);if(o.type==="illegal"&&!h){const p=new Error('Illegal lexeme "'+g+'" for mode "'+(f.scope||"<unnamed>")+'"');throw p.mode=f,p}else if(o.type==="end"){const p=ze(o);if(p!==Me)return p}if(o.type==="illegal"&&g==="")return E+=`
3
3
  `,1;if(Q>1e5&&Q>o.index*3)throw new Error("potential infinite loop, way more iterations than matches");return E+=g,g.length}const A=T(n);if(!A)throw v(_.replace("{}",n)),new Error('Unknown language: "'+n+'"');const Ye=Pt(A);let q="",f=d||Ye;const ge={},O=new r.__emitter(r);Xe();let E="",F=0,D=0,Q=0,m=!1;try{if(A.__emitTokens)A.__emitTokens(a,O);else{for(f.matcher.considerAll();;){Q++,m?m=!1:f.matcher.considerAll(),f.matcher.lastIndex=D;const s=f.matcher.exec(a);if(!s)break;const o=a.substring(D,s.index),g=fe(o,s);D=s.index+g}fe(a.substring(D))}return O.finalize(),q=O.toHTML(),{language:n,value:q,relevance:F,illegal:!1,_emitter:O,_top:f}}catch(s){if(s.message&&s.message.includes("Illegal"))return{language:n,value:ee(a),illegal:!0,relevance:0,_illegalBy:{message:s.message,index:D,context:a.slice(D-100,D+100),mode:s.mode,resultSoFar:q},_emitter:O};if(b)return{language:n,value:ee(a),illegal:!1,relevance:0,errorRaised:s,_emitter:O,_top:f};throw s}}function Z(n){const a={value:ee(n),illegal:!1,relevance:0,_top:c,_emitter:new r.__emitter(r)};return a._emitter.addText(n),a}function J(n,a){a=a||r.languages||Object.keys(t);const h=Z(n),d=a.filter(T).filter(oe).map(y=>j(y,n,!1));d.unshift(h);const x=d.sort((y,N)=>{if(y.relevance!==N.relevance)return N.relevance-y.relevance;if(y.language&&N.language){if(T(y.language).supersetOf===N.language)return 1;if(T(N.language).supersetOf===y.language)return-1}return 0}),[S,I]=x,W=S;return W.secondBest=I,W}function De(n,a,h){const d=a&&i[a]||h;n.classList.add("hljs"),n.classList.add(`language-${d}`)}function V(n){let a=null;const h=w(n);if(l(h))return;if(G("before:highlightElement",{el:n,language:h}),n.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",n);return}if(n.children.length>0&&(r.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(n)),r.throwUnescapedHTML))throw new Gt("One of your code blocks includes unescaped HTML.",n.innerHTML);a=n;const d=a.textContent,x=h?M(d,{language:h,ignoreIllegals:!0}):J(d);n.innerHTML=x.value,n.dataset.highlighted="yes",De(n,h,x.language),n.result={language:x.language,re:x.relevance,relevance:x.relevance},x.secondBest&&(n.secondBest={language:x.secondBest.language,relevance:x.secondBest.relevance}),G("after:highlightElement",{el:n,result:x,text:d})}function ve(n){r=_e(r,n)}const Ce=()=>{$(),L("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")};function Le(){$(),L("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")}let re=!1;function $(){function n(){$()}if(document.readyState==="loading"){re||window.addEventListener("DOMContentLoaded",n,!1),re=!0;return}document.querySelectorAll(r.cssSelector).forEach(V)}function He(n,a){let h=null;try{h=a(e)}catch(d){if(v("Language definition for '{}' could not be registered.".replace("{}",n)),b)v(d);else throw d;h=c}h.name||(h.name=n),t[n]=h,h.rawDefinition=a.bind(null,e),h.aliases&&ce(h.aliases,{languageName:n})}function je(n){delete t[n];for(const a of Object.keys(i))i[a]===n&&delete i[a]}function Pe(){return Object.keys(t)}function T(n){return n=(n||"").toLowerCase(),t[n]||t[i[n]]}function ce(n,{languageName:a}){typeof n=="string"&&(n=[n]),n.forEach(h=>{i[h.toLowerCase()]=a})}function oe(n){const a=T(n);return a&&!a.disableAutodetect}function Ue(n){n["before:highlightBlock"]&&!n["before:highlightElement"]&&(n["before:highlightElement"]=a=>{n["before:highlightBlock"](Object.assign({block:a.el},a))}),n["after:highlightBlock"]&&!n["after:highlightElement"]&&(n["after:highlightElement"]=a=>{n["after:highlightBlock"](Object.assign({block:a.el},a))})}function $e(n){Ue(n),u.push(n)}function Ge(n){const a=u.indexOf(n);a!==-1&&u.splice(a,1)}function G(n,a){const h=n;u.forEach(function(d){d[h]&&d[h](a)})}function We(n){return L("10.7.0","highlightBlock will be removed entirely in v12.0"),L("10.7.0","Please use highlightElement now."),V(n)}Object.assign(e,{highlight:M,highlightAuto:J,highlightAll:$,highlightElement:V,highlightBlock:We,configure:ve,initHighlighting:Ce,initHighlightingOnLoad:Le,registerLanguage:He,unregisterLanguage:je,listLanguages:Pe,getLanguage:T,registerAliases:ce,autoDetection:oe,inherit:_e,addPlugin:$e,removePlugin:Ge}),e.debugMode=function(){b=!1},e.safeMode=function(){b=!0},e.versionString=$t,e.regex={concat:C,lookahead:Oe,either:ne,optional:nt,anyNumberOfTimes:tt};for(const n in z)typeof z[n]=="object"&&xe(z[n]);return Object.assign(e,z),e},H=Be({});H.newInstance=()=>Be({});var Kt=H;H.HighlightJS=H;H.default=H;const zt=Ve(Kt);export{zt as HighlightJS,zt as default};