@idl3/claude-control 0.4.0 → 1.0.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/server.js CHANGED
@@ -42,7 +42,8 @@ import { listSkills, readSkill } from './lib/skills.js';
42
42
  // library auto-selects the FIRST offered one (the non-secret WS_PROTOCOL label)
43
43
  // and echoes it, so we never reflect the raw token back and need no custom
44
44
  // handleProtocols here. checkWsToken just verifies the token is among the offers.
45
- import { checkToken as authCheckToken, checkWsToken } from './lib/auth.js';
45
+ import { checkToken as authCheckToken, checkWsToken, safeTokenEqual } from './lib/auth.js';
46
+ import { pruneDeadClients } from './lib/ws-heartbeat.js';
46
47
 
47
48
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
48
49
  // Prefer the built assistant-ui app (web/dist) when present; otherwise fall back
@@ -152,7 +153,7 @@ function checkTerminalToken(reqUrl) {
152
153
  if (!CONFIG.token) return true;
153
154
  try {
154
155
  const u = new URL(reqUrl, 'http://localhost');
155
- return u.searchParams.get('token') === CONFIG.token;
156
+ return safeTokenEqual(u.searchParams.get('token'), CONFIG.token);
156
157
  } catch {
157
158
  return false;
158
159
  }
@@ -204,6 +205,7 @@ const _tls = loadTls();
204
205
  const _scheme = _tls ? 'https' : 'http';
205
206
 
206
207
  const _handler = (req, res) => {
208
+ try {
207
209
  const u = new URL(req.url, 'http://localhost');
208
210
 
209
211
  if (u.pathname === '/api/sessions') {
@@ -388,8 +390,16 @@ const _handler = (req, res) => {
388
390
  return proxyTerminalHttp(req, res, u);
389
391
  }
390
392
 
393
+ // Unknown /api/* path: return JSON 404 instead of falling through to the SPA.
394
+ if (u.pathname.startsWith('/api/')) return endJson(res, 404, { error: 'not found' });
395
+
391
396
  // static
392
397
  serveStatic(u.pathname, res);
398
+ } catch (e) {
399
+ // eslint-disable-next-line no-console
400
+ console.error('[handler] uncaught error:', e?.stack || e);
401
+ endJson(res, 500, { error: 'internal' });
402
+ }
393
403
  };
394
404
 
395
405
  const server = _tls
@@ -420,6 +430,7 @@ function handleUpdate(res) {
420
430
  }
421
431
 
422
432
  function endJson(res, code, obj) {
433
+ if (res.headersSent || res.writableEnded) return;
423
434
  const body = JSON.stringify(obj);
424
435
  res.writeHead(code, { 'content-type': MIME['.json'], 'content-length': Buffer.byteLength(body) });
425
436
  res.end(body);
@@ -953,6 +964,47 @@ function serveIndexHtml(res) {
953
964
  });
954
965
  }
955
966
 
967
+ // --- Per-target WS op serialisation ----------------------------------------
968
+ // Multiple browser/device clients on the same session can fire overlapping
969
+ // send-keys ops concurrently. Two such ops dispatched to the same tmux pane
970
+ // interleave keystrokes mid-sequence. We prevent this with a per-target FIFO
971
+ // promise chain: each send-keys op appends to the tail of its target's chain
972
+ // and runs only after its predecessor settles. Different targets run in
973
+ // parallel. Read-only ops (subscribe, capture, shell-capture, …) are NOT
974
+ // enqueued — they never touch the pane input buffer.
975
+ const _opChains = new Map(); // target → current-tail Promise
976
+
977
+ /**
978
+ * Enqueue `fn` behind any in-flight op on `target`.
979
+ *
980
+ * Contract:
981
+ * - The returned promise settles exactly as fn() settles (value / throw).
982
+ * - A rejected op does NOT poison the next op on the same target — the chain
983
+ * continues regardless of whether prev settled fulfilled or rejected.
984
+ * - The Map entry is deleted once the queued op is the sole tail and it has
985
+ * settled, preventing unbounded growth on idle targets.
986
+ *
987
+ * @param {string} target tmux pane target (the serialisation key)
988
+ * @param {() => Promise<any>} fn async work to serialise
989
+ * @returns {Promise<any>}
990
+ */
991
+ function runSerial(target, fn) {
992
+ const prev = _opChains.get(target) ?? Promise.resolve();
993
+ // chain: run fn after prev regardless of prev's outcome
994
+ const tail = prev.then(fn, fn);
995
+ // Store the tail so the NEXT enqueue can chain behind it.
996
+ // Suppress any rejection on the stored promise so Node's
997
+ // unhandledRejection handler never fires on the chain itself —
998
+ // the caller's `tail` reference will surface the error to the caller.
999
+ const stored = tail.then(() => {}, () => {});
1000
+ _opChains.set(target, stored);
1001
+ // Clean up once this op is the last in the chain and it has settled.
1002
+ stored.finally(() => {
1003
+ if (_opChains.get(target) === stored) _opChains.delete(target);
1004
+ });
1005
+ return tail;
1006
+ }
1007
+
956
1008
  // --- WebSocket --------------------------------------------------------------
957
1009
  // 1 MB cap: control messages are tiny; this prevents a single huge frame from
958
1010
  // forcing a multi-hundred-MB string allocation in the cockpit process.
@@ -1139,20 +1191,27 @@ function ensureSubscription(id) {
1139
1191
  function startPromptPoller(id, sub) {
1140
1192
  if (sub.promptTimer) return;
1141
1193
  sub._lastPrompt = undefined;
1194
+ sub._promptTicking = false;
1142
1195
  const tick = async () => {
1143
- const session = sessionById(id);
1144
- if (!session || !tmux.isValidTarget(session.target)) return;
1145
- let prompt = null;
1196
+ if (sub._promptTicking) return;
1197
+ sub._promptTicking = true;
1146
1198
  try {
1147
- const cap = await tmux.capturePane(session.target, 40);
1148
- prompt = parsePanePrompt(cap);
1149
- } catch {
1150
- return;
1151
- }
1152
- const json = prompt ? JSON.stringify(prompt) : null;
1153
- if (json !== sub._lastPrompt) {
1154
- sub._lastPrompt = json;
1155
- broadcastTo(id, { type: 'prompt', id, prompt });
1199
+ const session = sessionById(id);
1200
+ if (!session || !tmux.isValidTarget(session.target)) return;
1201
+ let prompt = null;
1202
+ try {
1203
+ const cap = await tmux.capturePane(session.target, 40);
1204
+ prompt = parsePanePrompt(cap);
1205
+ } catch {
1206
+ return;
1207
+ }
1208
+ const json = prompt ? JSON.stringify(prompt) : null;
1209
+ if (json !== sub._lastPrompt) {
1210
+ sub._lastPrompt = json;
1211
+ broadcastTo(id, { type: 'prompt', id, prompt });
1212
+ }
1213
+ } finally {
1214
+ sub._promptTicking = false;
1156
1215
  }
1157
1216
  };
1158
1217
  sub.promptTimer = setInterval(() => tick().catch(() => {}), 2000);
@@ -1171,6 +1230,9 @@ function maybeTeardown(id) {
1171
1230
  }
1172
1231
 
1173
1232
  wss.on('connection', (ws) => {
1233
+ ws.isAlive = true;
1234
+ ws.on('pong', () => { ws.isAlive = true; });
1235
+
1174
1236
  send(ws, { type: 'sessions', sessions: registry.getSessions() });
1175
1237
  send(ws, { type: 'resources', snapshot: resources.snapshot() });
1176
1238
  ws._subs = new Set();
@@ -1193,6 +1255,9 @@ wss.on('connection', (ws) => {
1193
1255
  });
1194
1256
  });
1195
1257
 
1258
+ const heartbeatInterval = setInterval(() => pruneDeadClients(wss.clients), 30000);
1259
+ heartbeatInterval.unref();
1260
+
1196
1261
  async function handleClientMessage(ws, msg) {
1197
1262
  switch (msg.type) {
1198
1263
  case 'subscribe': {
@@ -1228,8 +1293,11 @@ async function handleClientMessage(ws, msg) {
1228
1293
  const session = sessionById(msg.id);
1229
1294
  if (!session) throw new Error('unknown session');
1230
1295
  if (!tmux.isValidTarget(session.target)) throw new Error('invalid tmux target');
1231
- await tmux.sendText(session.target, String(msg.text ?? ''));
1232
- return send(ws, { type: 'ack', op: 'reply', ok: true });
1296
+ const replyText = String(msg.text ?? '');
1297
+ return runSerial(session.target, async () => {
1298
+ await tmux.sendText(session.target, replyText);
1299
+ send(ws, { type: 'ack', op: 'reply', ok: true });
1300
+ });
1233
1301
  }
1234
1302
  case 'answer': {
1235
1303
  const session = sessionById(msg.id);
@@ -1244,6 +1312,7 @@ async function handleClientMessage(ws, msg) {
1244
1312
  throw new Error('stale question (already answered or changed)');
1245
1313
  }
1246
1314
 
1315
+ return runSerial(session.target, async () => {
1247
1316
  // ── Capture-driven path ──────────────────────────────────────────────
1248
1317
  // Attempt to navigate by parsing the live picker render. Falls back to
1249
1318
  // the static buildAnswerProgram on ANY parse failure, unknown label, or
@@ -1449,7 +1518,8 @@ async function handleClientMessage(ws, msg) {
1449
1518
  console.log(`[answer] sent toolUseId=${msg.toolUseId} via dynamic path`);
1450
1519
  }
1451
1520
 
1452
- return send(ws, { type: 'ack', op: 'answer', ok: true });
1521
+ send(ws, { type: 'ack', op: 'answer', ok: true });
1522
+ }); // end runSerial
1453
1523
  }
1454
1524
  case 'capture': {
1455
1525
  const session = sessionById(msg.id);
@@ -1467,16 +1537,22 @@ async function handleClientMessage(ws, msg) {
1467
1537
  const session = sessionById(msg.id);
1468
1538
  if (!session) throw new Error('unknown session');
1469
1539
  if (!tmux.isValidTarget(session.target)) throw new Error('invalid tmux target');
1470
- await tmux.sendLiteral(session.target, String(msg.text ?? ''));
1471
- return send(ws, { type: 'ack', op: 'pane-text', ok: true });
1540
+ const paneText = String(msg.text ?? '');
1541
+ return runSerial(session.target, async () => {
1542
+ await tmux.sendLiteral(session.target, paneText);
1543
+ send(ws, { type: 'ack', op: 'pane-text', ok: true });
1544
+ });
1472
1545
  }
1473
1546
  case 'pane-key': {
1474
1547
  const session = sessionById(msg.id);
1475
1548
  if (!session) throw new Error('unknown session');
1476
1549
  if (!tmux.isValidTarget(session.target)) throw new Error('invalid tmux target');
1477
1550
  if (!shell.SHELL_KEYS.has(String(msg.key ?? ''))) throw new Error('key not allowed');
1478
- await tmux.sendRawKeys(session.target, [String(msg.key)]);
1479
- return send(ws, { type: 'ack', op: 'pane-key', ok: true });
1551
+ const paneKey = String(msg.key);
1552
+ return runSerial(session.target, async () => {
1553
+ await tmux.sendRawKeys(session.target, [paneKey]);
1554
+ send(ws, { type: 'ack', op: 'pane-key', ok: true });
1555
+ });
1480
1556
  }
1481
1557
  case 'promptkey': {
1482
1558
  // Respond to a live TUI selection prompt (permission/menu). Whitelisted
@@ -1486,11 +1562,14 @@ async function handleClientMessage(ws, msg) {
1486
1562
  if (!tmux.isValidTarget(session.target)) throw new Error('invalid tmux target');
1487
1563
  const ALLOWED = new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9', 'Enter', 'Escape', 'Up', 'Down']);
1488
1564
  if (!ALLOWED.has(msg.key)) throw new Error('key not allowed');
1489
- await tmux.sendRawKeys(session.target, [msg.key]);
1490
- // Force the next poll tick to broadcast (the prompt should now change/clear).
1491
- const sub = subscriptions.get(msg.id);
1492
- if (sub) sub._lastPrompt = '__force__';
1493
- return send(ws, { type: 'ack', op: 'promptkey', ok: true });
1565
+ const promptKey = msg.key;
1566
+ return runSerial(session.target, async () => {
1567
+ await tmux.sendRawKeys(session.target, [promptKey]);
1568
+ // Force the next poll tick to broadcast (the prompt should now change/clear).
1569
+ const sub = subscriptions.get(msg.id);
1570
+ if (sub) sub._lastPrompt = '__force__';
1571
+ send(ws, { type: 'ack', op: 'promptkey', ok: true });
1572
+ });
1494
1573
  }
1495
1574
  case 'promptselect': {
1496
1575
  // Respond to a live TUI multi-select checkbox prompt (surfaced via pane-scrape
@@ -1503,57 +1582,61 @@ async function handleClientMessage(ws, msg) {
1503
1582
  const labels = Array.isArray(msg.labels) ? msg.labels.map(String) : [];
1504
1583
  if (labels.length === 0) throw new Error('no labels provided');
1505
1584
 
1506
- const SETTLE_MS = 300;
1585
+ return runSerial(session.target, async () => {
1586
+ const SETTLE_MS = 300;
1507
1587
 
1508
- // 1. Capture current picker state.
1509
- let capture;
1510
- try {
1511
- capture = await tmux.capturePane(session.target);
1512
- } catch (captureErr) {
1513
- throw new Error(`promptselect: capture failed: ${captureErr?.message}`);
1514
- }
1588
+ // 1. Capture current picker state.
1589
+ let capture;
1590
+ try {
1591
+ capture = await tmux.capturePane(session.target);
1592
+ } catch (captureErr) {
1593
+ throw new Error(`promptselect: capture failed: ${captureErr?.message}`);
1594
+ }
1515
1595
 
1516
- // 2. Parse into a structured picker model.
1517
- const parsed = parsePicker(capture);
1518
- if (parsed.confidence !== 'ok') {
1519
- return send(ws, {
1520
- type: 'ack',
1521
- op: 'promptselect',
1522
- ok: false,
1523
- error: 'promptselect: picker not found or low confidence — please retry',
1524
- });
1525
- }
1596
+ // 2. Parse into a structured picker model.
1597
+ const parsed = parsePicker(capture);
1598
+ if (parsed.confidence !== 'ok') {
1599
+ send(ws, {
1600
+ type: 'ack',
1601
+ op: 'promptselect',
1602
+ ok: false,
1603
+ error: 'promptselect: picker not found or low confidence — please retry',
1604
+ });
1605
+ return;
1606
+ }
1526
1607
 
1527
- // 3. Build a synthetic single-question descriptor (multiSelect=true) so
1528
- // planStep can calculate Space-toggle + action-row Enter keys.
1529
- const syntheticQuestion = {
1530
- multiSelect: true,
1531
- options: parsed.rows
1532
- .filter((r) => r.kind === 'option')
1533
- .map((r) => ({ label: r.label })),
1534
- };
1535
-
1536
- // 4. Plan keystrokes via the tested planStep function.
1537
- const keys = planStep(parsed, syntheticQuestion, labels);
1538
- if (!keys) {
1539
- console.log(`[promptselect] planStep returned null for labels=${JSON.stringify(labels)} — low confidence`);
1540
- return send(ws, {
1541
- type: 'ack',
1542
- op: 'promptselect',
1543
- ok: false,
1544
- error: 'promptselect: could not map labels to picker rows — please retry',
1545
- });
1546
- }
1608
+ // 3. Build a synthetic single-question descriptor (multiSelect=true) so
1609
+ // planStep can calculate Space-toggle + action-row Enter keys.
1610
+ const syntheticQuestion = {
1611
+ multiSelect: true,
1612
+ options: parsed.rows
1613
+ .filter((r) => r.kind === 'option')
1614
+ .map((r) => ({ label: r.label })),
1615
+ };
1616
+
1617
+ // 4. Plan keystrokes via the tested planStep function.
1618
+ const keys = planStep(parsed, syntheticQuestion, labels);
1619
+ if (!keys) {
1620
+ console.log(`[promptselect] planStep returned null for labels=${JSON.stringify(labels)} — low confidence`);
1621
+ send(ws, {
1622
+ type: 'ack',
1623
+ op: 'promptselect',
1624
+ ok: false,
1625
+ error: 'promptselect: could not map labels to picker rows — please retry',
1626
+ });
1627
+ return;
1628
+ }
1547
1629
 
1548
- console.log(`[promptselect] id=${msg.id} labels=${JSON.stringify(labels)} keys=${JSON.stringify(keys)}`);
1630
+ console.log(`[promptselect] id=${msg.id} labels=${JSON.stringify(labels)} keys=${JSON.stringify(keys)}`);
1549
1631
 
1550
- // 5. Send keys sequenced with settle delay (same as case 'answer' dynamic path).
1551
- await tmux.sendRawKeysSequenced(session.target, keys, SETTLE_MS);
1632
+ // 5. Send keys sequenced with settle delay (same as case 'answer' dynamic path).
1633
+ await tmux.sendRawKeysSequenced(session.target, keys, SETTLE_MS);
1552
1634
 
1553
- // Force the next poll tick to broadcast (the prompt should now change/clear).
1554
- const promptSub = subscriptions.get(msg.id);
1555
- if (promptSub) promptSub._lastPrompt = '__force__';
1556
- return send(ws, { type: 'ack', op: 'promptselect', ok: true });
1635
+ // Force the next poll tick to broadcast (the prompt should now change/clear).
1636
+ const promptSub = subscriptions.get(msg.id);
1637
+ if (promptSub) promptSub._lastPrompt = '__force__';
1638
+ send(ws, { type: 'ack', op: 'promptselect', ok: true });
1639
+ });
1557
1640
  }
1558
1641
  // Composer terminal mode (>_): each Claude session has its OWN sister shell
1559
1642
  // pane in its window. Resolve the session by id → its target + cwd, then act
@@ -1561,20 +1644,29 @@ async function handleClientMessage(ws, msg) {
1561
1644
  case 'shell-input': {
1562
1645
  const s = sessionById(msg.id);
1563
1646
  if (!s) throw new Error('unknown session');
1564
- await shell.shellInput(s.target, s.cwd, String(msg.line ?? ''));
1565
- return send(ws, { type: 'ack', op: 'shell-input', ok: true });
1647
+ const shellInputLine = String(msg.line ?? '');
1648
+ return runSerial(s.target + ':shell', async () => {
1649
+ await shell.shellInput(s.target, s.cwd, shellInputLine);
1650
+ send(ws, { type: 'ack', op: 'shell-input', ok: true });
1651
+ });
1566
1652
  }
1567
1653
  case 'shell-text': {
1568
1654
  const s = sessionById(msg.id);
1569
1655
  if (!s) throw new Error('unknown session');
1570
- await shell.shellText(s.target, s.cwd, String(msg.text ?? ''));
1571
- return send(ws, { type: 'ack', op: 'shell-text', ok: true });
1656
+ const shellTextVal = String(msg.text ?? '');
1657
+ return runSerial(s.target + ':shell', async () => {
1658
+ await shell.shellText(s.target, s.cwd, shellTextVal);
1659
+ send(ws, { type: 'ack', op: 'shell-text', ok: true });
1660
+ });
1572
1661
  }
1573
1662
  case 'shell-key': {
1574
1663
  const s = sessionById(msg.id);
1575
1664
  if (!s) throw new Error('unknown session');
1576
- await shell.shellKey(s.target, s.cwd, String(msg.key ?? ''));
1577
- return send(ws, { type: 'ack', op: 'shell-key', ok: true });
1665
+ const shellKeyVal = String(msg.key ?? '');
1666
+ return runSerial(s.target + ':shell', async () => {
1667
+ await shell.shellKey(s.target, s.cwd, shellKeyVal);
1668
+ send(ws, { type: 'ack', op: 'shell-key', ok: true });
1669
+ });
1578
1670
  }
1579
1671
  case 'shell-capture': {
1580
1672
  const s = sessionById(msg.id);
@@ -1691,8 +1783,10 @@ async function main() {
1691
1783
  }
1692
1784
 
1693
1785
  function shutdown() {
1786
+ clearInterval(heartbeatInterval);
1694
1787
  for (const [, sub] of subscriptions) sub.tailer?.stop();
1695
1788
  terminal.shutdownAll();
1789
+ mlx.shutdown();
1696
1790
  registry.stop();
1697
1791
  resources.stop();
1698
1792
  if (uploadSweepTimer) clearInterval(uploadSweepTimer);
@@ -1702,4 +1796,21 @@ function shutdown() {
1702
1796
  process.on('SIGINT', shutdown);
1703
1797
  process.on('SIGTERM', shutdown);
1704
1798
 
1705
- main();
1799
+ // Safety nets: log unhandled async rejections; exit on truly uncaught sync
1800
+ // exceptions so Node doesn't continue with a corrupted process state.
1801
+ process.on('unhandledRejection', (e) => {
1802
+ // eslint-disable-next-line no-console
1803
+ console.error('[unhandledRejection]', e?.stack || e);
1804
+ });
1805
+ process.on('uncaughtException', (e) => {
1806
+ // eslint-disable-next-line no-console
1807
+ console.error('[uncaughtException]', e?.stack || e);
1808
+ process.exit(1);
1809
+ });
1810
+
1811
+ // Guard: only run the server when executed directly, not when imported for testing.
1812
+ const _isMain = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
1813
+ if (_isMain) main();
1814
+
1815
+ // Exported for unit testing only — not part of the public API.
1816
+ export { endJson, _handler, runSerial };
@@ -1,3 +1,3 @@
1
- import{g as Ve}from"./index-D41aOqTB.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-DFru8Gzx.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};