@oyehello/chat 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -139,18 +139,18 @@ var OyehelloChat = (function (exports) {
139
139
  const emitMessages = () => emit({ type: "messages", messages: messages.slice() });
140
140
  const onEvent = (ev) => {
141
141
  if (ev.type === "token") {
142
- let m = streamingId ? messages.find((x) => x.id === streamingId) : void 0;
143
- if (!m) {
144
- m = { id: uid("m"), role: "assistant", text: "", streaming: true };
145
- messages.push(m);
146
- streamingId = m.id;
142
+ let m2 = streamingId ? messages.find((x2) => x2.id === streamingId) : void 0;
143
+ if (!m2) {
144
+ m2 = { id: uid("m"), role: "assistant", text: "", streaming: true };
145
+ messages.push(m2);
146
+ streamingId = m2.id;
147
147
  }
148
- m.text += ev.text;
148
+ m2.text += ev.text;
149
149
  emitMessages();
150
150
  } else if (ev.type === "message") {
151
151
  if (seenTurnIds.has(ev.turnId)) {
152
152
  if (streamingId) {
153
- const idx = messages.findIndex((x) => x.id === streamingId);
153
+ const idx = messages.findIndex((x2) => x2.id === streamingId);
154
154
  if (idx !== -1) messages.splice(idx, 1);
155
155
  streamingId = null;
156
156
  emitMessages();
@@ -158,20 +158,20 @@ var OyehelloChat = (function (exports) {
158
158
  return;
159
159
  }
160
160
  seenTurnIds.add(ev.turnId);
161
- const m = streamingId ? messages.find((x) => x.id === streamingId) : void 0;
162
- if (m) {
163
- m.text = ev.text;
164
- m.streaming = false;
165
- m.turnId = ev.turnId;
161
+ const m2 = streamingId ? messages.find((x2) => x2.id === streamingId) : void 0;
162
+ if (m2) {
163
+ m2.text = ev.text || m2.text;
164
+ m2.streaming = false;
165
+ m2.turnId = ev.turnId;
166
166
  } else {
167
167
  messages.push({ id: uid("m"), role: "assistant", text: ev.text, streaming: false, turnId: ev.turnId });
168
168
  }
169
169
  streamingId = null;
170
170
  emitMessages();
171
171
  } else if (ev.type === "citations") {
172
- const m = messages.find((x) => x.turnId === ev.turnId);
173
- if (m) {
174
- m.sources = ev.sources;
172
+ const m2 = messages.find((x2) => x2.turnId === ev.turnId);
173
+ if (m2) {
174
+ m2.sources = ev.sources;
175
175
  emitMessages();
176
176
  }
177
177
  } else if (ev.type === "error") {
@@ -196,9 +196,9 @@ var OyehelloChat = (function (exports) {
196
196
  })();
197
197
  } else if (ev.type === "attachment") {
198
198
  const items = ev.items;
199
- const alreadyRendered = messages.some((m) => m.attachments?.some((a) => items.some((i) => i.storageRef === a.storageRef)));
199
+ const alreadyRendered = messages.some((m2) => m2.attachments?.some((a) => items.some((i) => i.storageRef === a.storageRef)));
200
200
  if (alreadyRendered) return;
201
- const target = [...messages].reverse().find((m) => m.role === "user" && !m.attachments);
201
+ const target = [...messages].reverse().find((m2) => m2.role === "user" && !m2.attachments);
202
202
  if (target) target.attachments = items;
203
203
  else messages.push({ id: uid("u"), role: "user", text: "", streaming: false, attachments: items });
204
204
  emitMessages();
@@ -282,7 +282,10 @@ var OyehelloChat = (function (exports) {
282
282
  return getAttachmentUrl({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, storageRef, fetchImpl });
283
283
  },
284
284
  async start() {
285
- if (state !== "idle") return;
285
+ if (state === "opening" || state === "ready") return;
286
+ closed = false;
287
+ clearReconnect();
288
+ reconnectAttempts = 0;
286
289
  setState("opening");
287
290
  try {
288
291
  await open();
@@ -291,95 +294,3398 @@ var OyehelloChat = (function (exports) {
291
294
  setState("error");
292
295
  emit({ type: "error", error: err });
293
296
  }
294
- },
295
- async sendMessage(text, files) {
296
- if (!session) {
297
- emit({ type: "error", error: new Error("call start() before sendMessage") });
298
- return;
297
+ },
298
+ async sendMessage(text2, files) {
299
+ if (!session) {
300
+ emit({ type: "error", error: new Error("call start() before sendMessage") });
301
+ return;
302
+ }
303
+ const fileList = files ?? [];
304
+ if (fileList.length > maxAttachments) {
305
+ emit({ type: "error", error: new Error(`too many attachments: max ${maxAttachments} per message`) });
306
+ return;
307
+ }
308
+ const oversized = fileList.find((f2) => f2.size > maxAttachmentBytes);
309
+ if (oversized) {
310
+ emit({ type: "error", error: new Error(`attachment too large: ${oversized.name} exceeds ${maxAttachmentBytes} bytes`) });
311
+ return;
312
+ }
313
+ let attachments = [];
314
+ if (fileList.length > 0) {
315
+ try {
316
+ attachments = await uploadFiles(fileList);
317
+ } catch (err) {
318
+ emit({ type: "error", error: err });
319
+ return;
320
+ }
321
+ }
322
+ messages.push({ id: uid("u"), role: "user", text: text2, streaming: false, attachments: attachments.length > 0 ? attachments : void 0 });
323
+ emitMessages();
324
+ try {
325
+ await postMessage({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, text: text2, attachments, fetchImpl });
326
+ } catch (err) {
327
+ if (err instanceof ChatApiError && err.code === "session_expired") {
328
+ try {
329
+ await open();
330
+ const freshAttachments = fileList.length ? await uploadFiles(fileList) : [];
331
+ await postMessage({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, text: text2, attachments: freshAttachments, fetchImpl });
332
+ } catch (retryErr) {
333
+ emit({ type: "error", error: retryErr });
334
+ }
335
+ } else {
336
+ emit({ type: "error", error: err });
337
+ }
338
+ }
339
+ },
340
+ async end() {
341
+ closed = true;
342
+ clearReconnect();
343
+ if (session) await endSession({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, fetchImpl });
344
+ es?.close();
345
+ es = null;
346
+ setState("ended");
347
+ }
348
+ };
349
+ }
350
+
351
+ // ../../node_modules/marked/lib/marked.esm.js
352
+ function A() {
353
+ return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
354
+ }
355
+ var T = A();
356
+ function j(u3) {
357
+ T = u3;
358
+ }
359
+ var E = { exec: () => null };
360
+ function I(u3) {
361
+ let e = [];
362
+ return (t) => {
363
+ let n = Math.max(0, Math.min(3, t - 1)), s = e[n];
364
+ return s || (s = u3(n), e[n] = s), s;
365
+ };
366
+ }
367
+ function k(u3, e = "") {
368
+ let t = typeof u3 == "string" ? u3 : u3.source, n = { replace: (s, r) => {
369
+ let o = typeof r == "string" ? r : r.source;
370
+ return o = o.replace(m.caret, "$1"), t = t.replace(s, o), n;
371
+ }, getRegex: () => new RegExp(t, e) };
372
+ return n;
373
+ }
374
+ var Te = ((u3 = "") => {
375
+ try {
376
+ return !!new RegExp("(?<=1)(?<!1)" + u3);
377
+ } catch {
378
+ return false;
379
+ }
380
+ })();
381
+ var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, endingSpaceTabChar: /[ \t]$/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (u3) => new RegExp(`^( {0,3}${u3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: I((u3) => new RegExp(`^ {0,${u3}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)), hrRegex: I((u3) => new RegExp(`^ {0,${u3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}(?:\`\`\`|~~~)`)), headingBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}#`)), htmlBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}>`)) };
382
+ var Oe = /^(?:[ \t]*(?:\n|$))+/;
383
+ var we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
384
+ var ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
385
+ var q = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
386
+ var Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
387
+ var U = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
388
+ var oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
389
+ var ae = k(oe).replace(/bull/g, U).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
390
+ var Se = k(oe).replace(/bull/g, U).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
391
+ var K = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \t]+\n)[^\n]+)*)/;
392
+ var _e = /^[^\n]+/;
393
+ var W = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
394
+ var $e = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", W).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
395
+ var Le = k(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, U).getRegex();
396
+ var Q = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
397
+ var X = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
398
+ var ze = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][a-z0-9-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][a-z0-9-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", X).replace("tag", Q).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
399
+ var le = (u3) => k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", u3).replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
400
+ var Ee = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
401
+ var Me = le(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/);
402
+ var Ae = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Me).getRegex();
403
+ var J = { blockquote: Ae, code: we, def: $e, fences: ye, heading: Pe, hr: q, html: ze, lheading: ae, list: Le, newline: Oe, paragraph: Ee, table: E, text: _e };
404
+ var se = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
405
+ var Ie = { ...J, lheading: Se, table: se, paragraph: k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex() };
406
+ var Ce = { ...J, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", X).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: E, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(K).replace("hr", q).replace("heading", ` *#{1,6} *[^
407
+ ]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
408
+ var Be = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
409
+ var De = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
410
+ var ue = /^( {2,}|\\)\n(?!\s*$)/;
411
+ var qe = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
412
+ var _ = /[\p{P}\p{S}]/u;
413
+ var C = /[\s\p{P}\p{S}]/u;
414
+ var v = /[^\s\p{P}\p{S}]/u;
415
+ var ve = k(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, C).getRegex();
416
+ var He = /[\p{Pi}\p{Ps}"']/u;
417
+ var pe = /(?!~)[\p{P}\p{S}]/u;
418
+ var Ze = /(?!~)[\s\p{P}\p{S}]/u;
419
+ var Ge = /(?:[^\s\p{P}\p{S}]|~)/u;
420
+ var Qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
421
+ var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
422
+ var Ne = k(ce, "u").replace(/punct/g, _).getRegex();
423
+ var je = k(ce, "u").replace(/punct/g, pe).getRegex();
424
+ var Fe = /^(?:\*+(?:((?!\*)(?!openQuote)punct)|([^\s*]))?)|^_+(?:((?!_)(?!openQuote)punct)|([^\s_]))?/;
425
+ var Ue = k(Fe, "u").replace(/openQuote/g, He).replace(/punct/g, _).getRegex();
426
+ var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
427
+ var Ke = k(he, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).replace(/punct/g, _).getRegex();
428
+ var We = k(he, "gu").replace(/notPunctSpace/g, Ge).replace(/punctSpace/g, Ze).replace(/punct/g, pe).getRegex();
429
+ var Xe = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)[\\s](\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|(?:(?!\\*)punct|notPunctSpace)(\\*+)(?!\\*)(?=notPunctSpace)";
430
+ var Je = k(Xe, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).replace(/punct/g, _).getRegex();
431
+ var Ve = k("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).replace(/punct/g, _).getRegex();
432
+ var Ye = "^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)[\\s](_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)|(?:(?!_)punct|notPunctSpace)(_+)(?!_)(?=notPunctSpace)";
433
+ var et = k(Ye, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).replace(/punct/g, _).getRegex();
434
+ var tt = k(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, _).getRegex();
435
+ var nt = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)";
436
+ var rt = k(nt, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).replace(/punct/g, _).getRegex();
437
+ var st = k(/\\(punct)/, "gu").replace(/punct/g, _).getRegex();
438
+ var it = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
439
+ var ot = k(X).replace("(?:-->|$)", "-->").getRegex();
440
+ var at = k("^comment|^</[a-zA-Z][a-zA-Z0-9-]*\\s*>|^<[a-zA-Z][a-zA-Z0-9-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", ot).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
441
+ var lt = /\[(?:\\[\s\S]|[^\[\]\\])*\]/;
442
+ var G = k(/(?:\[(?:brackets|\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/).replace("brackets", lt).getRegex();
443
+ var ut = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", G).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
444
+ var ke = k(/^!?\[(label)\]\[(ref)\]/).replace("label", G).replace("ref", W).getRegex();
445
+ var de = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", W).getRegex();
446
+ var pt = k("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
447
+ var ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
448
+ var V = { _backpedal: E, anyPunctuation: st, autolink: it, blockSkip: Qe, br: ue, code: De, del: E, delLDelim: E, delRDelim: E, emStrongLDelim: Ne, emStrongRDelimAst: Ke, emStrongRDelimUnd: Ve, escape: Be, link: ut, nolink: de, punctuation: ve, reflink: ke, reflinkSearch: pt, tag: at, text: qe, url: E };
449
+ var ct = { ...V, emStrongLDelim: Ue, emStrongRDelimAst: Je, emStrongRDelimUnd: et, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", G).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", G).getRegex() };
450
+ var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![\w-])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", ie).getRegex() };
451
+ var ht = { ...F, br: k(ue).replace("{2,}", "*").getRegex(), text: k(F.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
452
+ var H = { normal: J, gfm: Ie, pedantic: Ce };
453
+ var B = { normal: V, gfm: F, breaks: ht, pedantic: ct };
454
+ var kt = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
455
+ var ge = (u3) => kt[u3];
456
+ function R(u3, e) {
457
+ if (e) {
458
+ if (m.escapeTest.test(u3)) return u3.replace(m.escapeReplace, ge);
459
+ } else if (m.escapeTestNoEncode.test(u3)) return u3.replace(m.escapeReplaceNoEncode, ge);
460
+ return u3;
461
+ }
462
+ function Y(u3) {
463
+ try {
464
+ u3 = encodeURI(u3).replace(m.percentDecode, "%");
465
+ } catch {
466
+ return null;
467
+ }
468
+ return u3;
469
+ }
470
+ function ee(u3, e) {
471
+ let t = u3.replace(m.findPipe, (r, o, i) => {
472
+ let l = false, a = o;
473
+ for (; --a >= 0 && i[a] === "\\"; ) l = !l;
474
+ return l ? "|" : " |";
475
+ }), n = t.split(m.splitPipe), s = 0;
476
+ if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
477
+ else for (; n.length < e; ) n.push("");
478
+ for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|");
479
+ return n;
480
+ }
481
+ function $(u3, e, t) {
482
+ let n = u3.length;
483
+ if (n === 0) return "";
484
+ let s = 0;
485
+ for (; s < n; ) {
486
+ let r = u3.charAt(n - s - 1);
487
+ if (r === e && true) s++;
488
+ else break;
489
+ }
490
+ return u3.slice(0, n - s);
491
+ }
492
+ function te(u3) {
493
+ let e = u3.split(`
494
+ `), t = e.length - 1;
495
+ for (; t >= 0 && m.blankLine.test(e[t]); ) t--;
496
+ return e.length - t <= 2 ? u3 : e.slice(0, t + 1).join(`
497
+ `);
498
+ }
499
+ function fe(u3, e) {
500
+ if (u3.indexOf(e[1]) === -1) return -1;
501
+ let t = 0;
502
+ for (let n = 0; n < u3.length; n++) if (u3[n] === "\\") n++;
503
+ else if (u3[n] === e[0]) t++;
504
+ else if (u3[n] === e[1] && (t--, t < 0)) return n;
505
+ return t > 0 ? -2 : -1;
506
+ }
507
+ function me(u3, e = 0) {
508
+ let t = e, n = "";
509
+ for (let s of u3) if (s === " ") {
510
+ let r = 4 - t % 4;
511
+ n += " ".repeat(r), t += r;
512
+ } else n += s, t++;
513
+ return n;
514
+ }
515
+ function xe(u3, e, t, n, s) {
516
+ let r = e.href, o = e.title || null, i = u3[1].replace(s.other.outputLinkReplace, "$1"), l = u3[0].charAt(0) === "!";
517
+ n.state.inLink = true;
518
+ let a = n.state.linkEmitted, p = n.state.inRawBlock;
519
+ n.state.linkEmitted = false;
520
+ let c = n.inlineTokens(i), h = n.state.linkEmitted;
521
+ if (n.state.linkEmitted = a, n.state.inLink = false, !l) {
522
+ if (h) {
523
+ n.state.inRawBlock = p;
524
+ return;
525
+ }
526
+ n.state.linkEmitted = true;
527
+ }
528
+ return { type: l ? "image" : "link", raw: t, href: r, title: o, text: i, tokens: c };
529
+ }
530
+ function dt(u3, e, t) {
531
+ let n = u3.match(t.other.indentCodeCompensation);
532
+ if (n === null) return e;
533
+ let s = n[1];
534
+ return e.split(`
535
+ `).map((r) => {
536
+ let o = r.match(t.other.beginningSpace);
537
+ if (o === null) return r;
538
+ let [i] = o;
539
+ return r.slice(Math.min(i.length, s.length));
540
+ }).join(`
541
+ `);
542
+ }
543
+ var y = class {
544
+ options;
545
+ rules;
546
+ lexer;
547
+ constructor(e) {
548
+ this.options = e || T;
549
+ }
550
+ space(e) {
551
+ let t = this.rules.block.newline.exec(e);
552
+ if (t && t[0].length > 0) return { type: "space", raw: t[0] };
553
+ }
554
+ code(e) {
555
+ let t = this.rules.block.code.exec(e);
556
+ if (t) {
557
+ let n = this.options.pedantic ? t[0] : te(t[0]), s = n.replace(this.rules.other.codeRemoveIndent, "");
558
+ return { type: "code", raw: n, codeBlockStyle: "indented", text: s };
559
+ }
560
+ }
561
+ fences(e) {
562
+ let t = this.rules.block.fences.exec(e);
563
+ if (t) {
564
+ let n = t[0], s = dt(n, t[3] || "", this.rules);
565
+ return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s };
566
+ }
567
+ }
568
+ heading(e) {
569
+ let t = this.rules.block.heading.exec(e);
570
+ if (t) {
571
+ let n = t[2].trim();
572
+ if (this.rules.other.endingHash.test(n)) {
573
+ let s = $(n, "#");
574
+ (this.options.pedantic || !s || this.rules.other.endingSpaceTabChar.test(s)) && (n = s.trim());
575
+ }
576
+ return { type: "heading", raw: $(t[0], `
577
+ `), depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
578
+ }
579
+ }
580
+ hr(e) {
581
+ let t = this.rules.block.hr.exec(e);
582
+ if (t) return { type: "hr", raw: $(t[0], `
583
+ `) };
584
+ }
585
+ blockquote(e) {
586
+ let t = this.rules.block.blockquote.exec(e);
587
+ if (t) {
588
+ let n = $(t[0], `
589
+ `).split(`
590
+ `), s = "", r = "", o = [];
591
+ for (; n.length > 0; ) {
592
+ let i = false, l = [], a;
593
+ for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a])) l.push(n[a]), i = true;
594
+ else if (!i) l.push(n[a]);
595
+ else break;
596
+ n = n.slice(a);
597
+ let p = l.join(`
598
+ `), c = p.replace(this.rules.other.blockquoteSetextReplace, `
599
+ $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
600
+ s = s ? `${s}
601
+ ${p}` : p, r = r ? `${r}
602
+ ${c}` : c;
603
+ let h = this.lexer.state.top;
604
+ if (this.lexer.state.top = true, this.lexer.blockTokens(c, o, true), this.lexer.state.top = h, n.length === 0) break;
605
+ let d = o.at(-1);
606
+ if (d?.type === "code") break;
607
+ if (d?.type === "blockquote") {
608
+ let O = d, g = n.join(`
609
+ `), w = O.raw + `
610
+ ` + g.replace(this.rules.other.blockquoteSetextReplace2, ""), z = this.blockquote(w);
611
+ o[o.length - 1] = z, s = `${s}
612
+ ${g}`, r = r.substring(0, r.length - O.text.length) + z.text;
613
+ break;
614
+ } else if (d?.type === "list") {
615
+ let O = d, g = O.raw + `
616
+ ` + n.join(`
617
+ `), w = this.list(g);
618
+ o[o.length - 1] = w, s = s.substring(0, s.length - d.raw.length) + w.raw, r = r.substring(0, r.length - O.raw.length) + w.raw, n = g.substring(o.at(-1).raw.length).split(`
619
+ `);
620
+ continue;
621
+ }
622
+ }
623
+ return { type: "blockquote", raw: s, tokens: o, text: r };
624
+ }
625
+ }
626
+ list(e) {
627
+ let t = this.rules.block.list.exec(e);
628
+ if (t) {
629
+ let n = t[1].trim(), s = n.length > 1, r = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] };
630
+ n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
631
+ let o = this.rules.other.listItemRegex(n), i = false;
632
+ for (; e; ) {
633
+ let a = false, p = "", c = "";
634
+ if (!(t = o.exec(e)) || this.rules.block.hr.test(e)) break;
635
+ p = t[0], e = e.substring(p.length);
636
+ let h = me(t[2].split(`
637
+ `, 1)[0], t[1].length), d = e.split(`
638
+ `, 1)[0], O = !h.trim(), g = 0;
639
+ if (this.options.pedantic ? (g = 2, c = h.trimStart()) : O ? g = t[1].length + 1 : (g = h.search(this.rules.other.nonSpaceChar), g = g > 4 ? 1 : g, c = h.slice(g), g += t[1].length), O && this.rules.other.blankLine.test(d) && (p += d + `
640
+ `, e = e.substring(d.length + 1), a = true), !a) {
641
+ let w = this.rules.other.nextBulletRegex(g), z = this.rules.other.hrRegex(g), ne = this.rules.other.fencesBeginRegex(g), re = this.rules.other.headingBeginRegex(g), be = this.rules.other.htmlBeginRegex(g), Re = this.rules.other.blockquoteBeginRegex(g);
642
+ for (; e; ) {
643
+ let N = e.split(`
644
+ `, 1)[0], D;
645
+ if (d = N, this.options.pedantic ? (d = d.replace(this.rules.other.listReplaceNesting, " "), D = d) : D = d.replace(this.rules.other.tabCharGlobal, " "), ne.test(d) || re.test(d) || be.test(d) || Re.test(d) || w.test(d) || z.test(d)) break;
646
+ if (D.search(this.rules.other.nonSpaceChar) >= g || !d.trim()) c += `
647
+ ` + D.slice(g);
648
+ else {
649
+ if (O || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || z.test(h)) break;
650
+ c += `
651
+ ` + d;
652
+ }
653
+ O = !d.trim(), p += N + `
654
+ `, e = e.substring(N.length + 1), h = D.slice(g);
655
+ }
656
+ }
657
+ r.loose || (i ? r.loose = true : this.rules.other.doubleBlankLine.test(p) && (i = true)), r.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), r.raw += p;
658
+ }
659
+ let l = r.items.at(-1);
660
+ if (l) l.raw = l.raw.trimEnd(), l.text = l.text.trimEnd();
661
+ else return;
662
+ r.raw = r.raw.trimEnd();
663
+ for (let a of r.items) if (this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []), !r.loose) {
664
+ let p = a.tokens.filter((h) => h.type === "space"), c = p.length > 0 && p.some((h) => this.rules.other.anyLine.test(h.raw));
665
+ r.loose = c;
666
+ }
667
+ for (let a of r.items) {
668
+ let p = a.tokens[0];
669
+ if (a.task && (p?.type === "text" || p?.type === "paragraph")) {
670
+ a.text = a.text.replace(this.rules.other.listReplaceTask, ""), p.raw = p.raw.replace(this.rules.other.listReplaceTask, ""), p.text = p.text.replace(this.rules.other.listReplaceTask, "");
671
+ for (let h = this.lexer.inlineQueue.length - 1; h >= 0; h--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)) {
672
+ this.lexer.inlineQueue[h].src = this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask, "");
673
+ break;
674
+ }
675
+ let c = this.rules.other.listTaskCheckbox.exec(a.raw);
676
+ if (c) {
677
+ let h = { type: "checkbox", raw: c[0] + " ", checked: c[0] !== "[ ]" };
678
+ a.checked = h.checked, r.loose ? a.tokens[0] && ["paragraph", "text"].includes(a.tokens[0].type) && "tokens" in a.tokens[0] && a.tokens[0].tokens ? (a.tokens[0].raw = h.raw + a.tokens[0].raw, a.tokens[0].text = h.raw + a.tokens[0].text, a.tokens[0].tokens.unshift(h)) : a.tokens.unshift({ type: "paragraph", raw: h.raw, text: h.raw, tokens: [h] }) : a.tokens.unshift(h);
679
+ }
680
+ } else a.task && (a.task = false);
681
+ }
682
+ if (r.loose) for (let a of r.items) {
683
+ a.loose = true;
684
+ for (let p of a.tokens) p.type === "text" && (p.type = "paragraph");
685
+ }
686
+ return r;
687
+ }
688
+ }
689
+ html(e) {
690
+ let t = this.rules.block.html.exec(e);
691
+ if (t) {
692
+ let n = te(t[0]);
693
+ return { type: "html", block: true, raw: n, pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: n };
694
+ }
695
+ }
696
+ def(e) {
697
+ let t = this.rules.block.def.exec(e);
698
+ if (t) {
699
+ let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", r = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
700
+ return { type: "def", tag: n, raw: $(t[0], `
701
+ `), href: s, title: r };
702
+ }
703
+ }
704
+ table(e) {
705
+ let t = this.rules.block.table.exec(e);
706
+ if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
707
+ let n = ee(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), r = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
708
+ `) : [], o = { type: "table", raw: $(t[0], `
709
+ `), header: [], align: [], rows: [] };
710
+ if (n.length === s.length) {
711
+ for (let i of s) this.rules.other.tableAlignRight.test(i) ? o.align.push("right") : this.rules.other.tableAlignCenter.test(i) ? o.align.push("center") : this.rules.other.tableAlignLeft.test(i) ? o.align.push("left") : o.align.push(null);
712
+ for (let i = 0; i < n.length; i++) o.header.push({ text: n[i], tokens: this.lexer.inline(n[i]), header: true, align: o.align[i] });
713
+ for (let i of r) o.rows.push(ee(i, o.header.length).map((l, a) => ({ text: l, tokens: this.lexer.inline(l), header: false, align: o.align[a] })));
714
+ return o;
715
+ }
716
+ }
717
+ lheading(e) {
718
+ let t = this.rules.block.lheading.exec(e);
719
+ if (t) {
720
+ let n = t[1].trim();
721
+ return { type: "heading", raw: $(t[0], `
722
+ `), depth: t[2].charAt(0) === "=" ? 1 : 2, text: n, tokens: this.lexer.inline(n) };
723
+ }
724
+ }
725
+ paragraph(e) {
726
+ let t = this.rules.block.paragraph.exec(e);
727
+ if (t) {
728
+ let n = t[1].charAt(t[1].length - 1) === `
729
+ ` ? t[1].slice(0, -1) : t[1];
730
+ return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
731
+ }
732
+ }
733
+ text(e) {
734
+ let t = this.rules.block.text.exec(e);
735
+ if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
736
+ }
737
+ escape(e) {
738
+ let t = this.rules.inline.escape.exec(e);
739
+ if (t) return { type: "escape", raw: t[0], text: t[1] };
740
+ }
741
+ tag(e) {
742
+ let t = this.rules.inline.tag.exec(e);
743
+ if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] };
744
+ }
745
+ link(e) {
746
+ let t = this.rules.inline.link.exec(e);
747
+ if (t) {
748
+ let n = t[2].trim();
749
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
750
+ if (!this.rules.other.endAngleBracket.test(n)) return;
751
+ let o = $(n.slice(0, -1), "\\");
752
+ if ((n.length - o.length) % 2 === 0) return;
753
+ } else {
754
+ let o = fe(t[2], "()");
755
+ if (o === -2) return;
756
+ if (o > -1) {
757
+ let l = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + o;
758
+ t[2] = t[2].substring(0, o), t[0] = t[0].substring(0, l).trim(), t[3] = "";
759
+ }
760
+ }
761
+ let s = t[2], r = "";
762
+ if (this.options.pedantic) {
763
+ let o = this.rules.other.pedanticHrefTitle.exec(s);
764
+ o && (s = o[1], r = o[3]);
765
+ } else r = t[3] ? t[3].slice(1, -1) : "";
766
+ return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), xe(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: r && r.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
767
+ }
768
+ }
769
+ reflink(e, t) {
770
+ let n;
771
+ if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
772
+ let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), r = t[s.toLowerCase()];
773
+ if (!r) {
774
+ let o = n[0].charAt(0);
775
+ return { type: "text", raw: o, text: o };
776
+ }
777
+ return xe(n, r, n[0], this.lexer, this.rules);
778
+ }
779
+ }
780
+ emStrong(e, t, n = "") {
781
+ let s = this.rules.inline.emStrongLDelim.exec(e);
782
+ if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
783
+ if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
784
+ let o = [...s[0]].length - 1, i, l, a = o, p = 0, c = s[0][0], h = n === c, d = c === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
785
+ for (d.lastIndex = 0, t = t.slice(-1 * e.length + o); (s = d.exec(t)) !== null; ) {
786
+ if (i = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !i) continue;
787
+ if (l = [...i].length, s[3] || s[4]) {
788
+ a += l;
789
+ continue;
790
+ } else if (s[5] || s[6]) {
791
+ if (o % 3 && !((o + l) % 3)) {
792
+ p += l;
793
+ continue;
794
+ }
795
+ if (h) break;
796
+ }
797
+ if (a -= l, a > 0) continue;
798
+ l = Math.min(l, l + a + p);
799
+ let O = [...s[0]][0].length, g = e.slice(0, o + s.index + O + l);
800
+ if (Math.min(o, l) % 2) {
801
+ let z = g.slice(1, -1);
802
+ return { type: "em", raw: g, text: z, tokens: this.lexer.inlineTokens(z) };
803
+ }
804
+ let w = g.slice(2, -2);
805
+ return { type: "strong", raw: g, text: w, tokens: this.lexer.inlineTokens(w) };
806
+ }
807
+ }
808
+ }
809
+ codespan(e) {
810
+ let t = this.rules.inline.code.exec(e);
811
+ if (t) {
812
+ let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), s = this.rules.other.nonSpaceChar.test(n), r = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
813
+ return s && r && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
814
+ }
815
+ }
816
+ br(e) {
817
+ let t = this.rules.inline.br.exec(e);
818
+ if (t) return { type: "br", raw: t[0] };
819
+ }
820
+ del(e, t, n = "") {
821
+ let s = this.rules.inline.delLDelim.exec(e);
822
+ if (!s) return;
823
+ if (!(s[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
824
+ let o = [...s[0]].length - 1, i, l, a = o, p = this.rules.inline.delRDelim;
825
+ for (p.lastIndex = 0, t = t.slice(-1 * e.length + o); (s = p.exec(t)) !== null; ) {
826
+ if (i = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !i || (l = [...i].length, l !== o)) continue;
827
+ if (s[3] || s[4]) {
828
+ a += l;
829
+ continue;
830
+ }
831
+ if (a -= l, a > 0) continue;
832
+ l = Math.min(l, l + a);
833
+ let c = [...s[0]][0].length, h = e.slice(0, o + s.index + c + l), d = h.slice(o, -o);
834
+ return { type: "del", raw: h, text: d, tokens: this.lexer.inlineTokens(d) };
835
+ }
836
+ }
837
+ }
838
+ autolink(e) {
839
+ let t = this.rules.inline.autolink.exec(e);
840
+ if (t) {
841
+ let n, s;
842
+ return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, autolink: true, tokens: [{ type: "text", raw: n, text: n }] };
843
+ }
844
+ }
845
+ url(e) {
846
+ let t;
847
+ if (t = this.rules.inline.url.exec(e)) {
848
+ let n, s;
849
+ if (t[2] === "@") n = t[0], s = "mailto:" + n;
850
+ else {
851
+ let r;
852
+ do
853
+ r = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
854
+ while (r !== t[0]);
855
+ n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0];
856
+ }
857
+ return { type: "link", raw: t[0], text: n, href: s, autolink: true, tokens: [{ type: "text", raw: n, text: n }] };
858
+ }
859
+ }
860
+ inlineText(e) {
861
+ let t = this.rules.inline.text.exec(e);
862
+ if (t) {
863
+ let n = this.lexer.state.inRawBlock;
864
+ return { type: "text", raw: t[0], text: t[0], escaped: n };
865
+ }
866
+ }
867
+ };
868
+ var x = class u {
869
+ tokens;
870
+ options;
871
+ state;
872
+ inlineQueue;
873
+ tokenizer;
874
+ constructor(e) {
875
+ this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new y(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, linkEmitted: false, top: true };
876
+ let t = { other: m, block: H.normal, inline: B.normal };
877
+ this.options.pedantic ? (t.block = H.pedantic, t.inline = B.pedantic) : this.options.gfm && (t.block = H.gfm, this.options.breaks ? t.inline = B.breaks : t.inline = B.gfm), this.tokenizer.rules = t;
878
+ }
879
+ static get rules() {
880
+ return { block: H, inline: B };
881
+ }
882
+ static lex(e, t) {
883
+ return new u(t).lex(e);
884
+ }
885
+ static lexInline(e, t) {
886
+ return new u(t).inlineTokens(e);
887
+ }
888
+ lex(e) {
889
+ e = e.replace(m.carriageReturn, `
890
+ `), this.blockTokens(e, this.tokens);
891
+ for (let t = 0; t < this.inlineQueue.length; t++) {
892
+ let n = this.inlineQueue[t];
893
+ this.inlineTokens(n.src, n.tokens);
894
+ }
895
+ return this.inlineQueue = [], this.tokens;
896
+ }
897
+ blockTokens(e, t = [], n = false) {
898
+ this.tokenizer.lexer = this, this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, ""));
899
+ let s = 1 / 0;
900
+ for (; e; ) {
901
+ if (e.length < s) s = e.length;
902
+ else {
903
+ this.infiniteLoopError(e.charCodeAt(0));
904
+ break;
905
+ }
906
+ let r;
907
+ if (this.options.extensions?.block?.some((i) => (r = i.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
908
+ if (r = this.tokenizer.space(e)) {
909
+ e = e.substring(r.raw.length);
910
+ let i = t.at(-1);
911
+ r.raw.length === 1 && i !== void 0 ? i.raw += `
912
+ ` : t.push(r);
913
+ continue;
914
+ }
915
+ if (r = this.tokenizer.code(e)) {
916
+ e = e.substring(r.raw.length);
917
+ let i = t.at(-1);
918
+ i?.type === "paragraph" || i?.type === "text" ? (i.raw += (i.raw.endsWith(`
919
+ `) ? "" : `
920
+ `) + r.raw, i.text += `
921
+ ` + r.text, this.inlineQueue.at(-1).src = i.text) : t.push(r);
922
+ continue;
923
+ }
924
+ if (r = this.tokenizer.fences(e)) {
925
+ e = e.substring(r.raw.length), t.push(r);
926
+ continue;
927
+ }
928
+ if (r = this.tokenizer.heading(e)) {
929
+ e = e.substring(r.raw.length), t.push(r);
930
+ continue;
931
+ }
932
+ if (r = this.tokenizer.hr(e)) {
933
+ e = e.substring(r.raw.length), t.push(r);
934
+ continue;
935
+ }
936
+ if (r = this.tokenizer.blockquote(e)) {
937
+ e = e.substring(r.raw.length), t.push(r);
938
+ continue;
939
+ }
940
+ if (r = this.tokenizer.list(e)) {
941
+ e = e.substring(r.raw.length), t.push(r);
942
+ continue;
943
+ }
944
+ if (r = this.tokenizer.html(e)) {
945
+ e = e.substring(r.raw.length), t.push(r);
946
+ continue;
947
+ }
948
+ if (r = this.tokenizer.def(e)) {
949
+ e = e.substring(r.raw.length);
950
+ let i = t.at(-1);
951
+ i?.type === "paragraph" || i?.type === "text" ? (i.raw += (i.raw.endsWith(`
952
+ `) ? "" : `
953
+ `) + r.raw, i.text += `
954
+ ` + r.raw, this.inlineQueue.at(-1).src = i.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
955
+ continue;
956
+ }
957
+ if (r = this.tokenizer.table(e)) {
958
+ e = e.substring(r.raw.length), t.push(r);
959
+ continue;
960
+ }
961
+ if (r = this.tokenizer.lheading(e)) {
962
+ e = e.substring(r.raw.length), t.push(r);
963
+ continue;
964
+ }
965
+ let o = e;
966
+ if (this.options.extensions?.startBlock) {
967
+ let i = 1 / 0, l = e.slice(1), a;
968
+ this.options.extensions.startBlock.forEach((p) => {
969
+ a = p.call({ lexer: this }, l), typeof a == "number" && a >= 0 && (i = Math.min(i, a));
970
+ }), i < 1 / 0 && i >= 0 && (o = e.substring(0, i + 1));
971
+ }
972
+ if (this.state.top && (r = this.tokenizer.paragraph(o))) {
973
+ let i = t.at(-1);
974
+ n && i?.type === "paragraph" ? (i.raw += (i.raw.endsWith(`
975
+ `) ? "" : `
976
+ `) + r.raw, i.text += `
977
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = i.text) : t.push(r), n = o.length !== e.length, e = e.substring(r.raw.length);
978
+ continue;
979
+ }
980
+ if (r = this.tokenizer.text(e)) {
981
+ e = e.substring(r.raw.length);
982
+ let i = t.at(-1);
983
+ i?.type === "text" ? (i.raw += (i.raw.endsWith(`
984
+ `) ? "" : `
985
+ `) + r.raw, i.text += `
986
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = i.text) : t.push(r);
987
+ continue;
988
+ }
989
+ if (e) {
990
+ this.infiniteLoopError(e.charCodeAt(0));
991
+ break;
992
+ }
993
+ }
994
+ return this.state.top = true, t;
995
+ }
996
+ inline(e, t = []) {
997
+ return this.inlineQueue.push({ src: e, tokens: t }), t;
998
+ }
999
+ linkInText(e) {
1000
+ if (!e.includes("[")) return false;
1001
+ let t = this.tokenizer.rules.inline.link;
1002
+ for (let n of e.matchAll(this.tokenizer.rules.inline.blockSkip)) if (t.test(n[0]) && e.charAt(n.index - 1) !== "!") return true;
1003
+ for (let n of e.matchAll(this.tokenizer.rules.inline.reflinkSearch)) {
1004
+ let s = n[0], r = s.lastIndexOf("[");
1005
+ if (!(s.charAt(0) === "!" || !Object.hasOwn(this.tokens.links, s.slice(r + 1, -1))) && !(r > 1 && this.linkInText(s.slice(1, r - 1)))) return true;
1006
+ }
1007
+ return false;
1008
+ }
1009
+ inlineTokens(e, t = []) {
1010
+ this.tokenizer.lexer = this;
1011
+ let n = e;
1012
+ if (this.tokens.links && e.includes("[")) {
1013
+ let i = this.tokenizer.rules.inline.reflinkSearch, l = (a) => {
1014
+ let p = a.lastIndexOf("[");
1015
+ if (!Object.hasOwn(this.tokens.links, a.slice(p + 1, -1))) return a;
1016
+ if (p > 1 && a.charAt(0) !== "!") {
1017
+ let c = a.slice(1, p - 1);
1018
+ if (this.linkInText(c)) return "[" + c.replace(i, l) + "][" + "a".repeat(a.length - p - 2) + "]";
1019
+ }
1020
+ return "[" + "a".repeat(a.length - 2) + "]";
1021
+ };
1022
+ n = n.replace(i, l);
1023
+ }
1024
+ n = n.replace(this.tokenizer.rules.inline.anyPunctuation, (i) => "+".repeat(i.length)), n = n.replace(this.tokenizer.rules.inline.blockSkip, (i, l, a) => {
1025
+ let p = a ? a.length : 0;
1026
+ return i.slice(0, p) + "[" + "a".repeat(i.length - p - 2) + "]";
1027
+ }), n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
1028
+ let s = false, r = "", o = 1 / 0;
1029
+ for (; e; ) {
1030
+ if (e.length < o) o = e.length;
1031
+ else {
1032
+ this.infiniteLoopError(e.charCodeAt(0));
1033
+ break;
1034
+ }
1035
+ s || (r = ""), s = false;
1036
+ let i;
1037
+ if (this.options.extensions?.inline?.some((a) => (i = a.call({ lexer: this }, e, t)) ? (e = e.substring(i.raw.length), t.push(i), true) : false)) continue;
1038
+ if (i = this.tokenizer.escape(e)) {
1039
+ e = e.substring(i.raw.length), t.push(i);
1040
+ continue;
1041
+ }
1042
+ if (i = this.tokenizer.tag(e)) {
1043
+ e = e.substring(i.raw.length), t.push(i);
1044
+ continue;
1045
+ }
1046
+ if (i = this.tokenizer.link(e)) {
1047
+ e = e.substring(i.raw.length), t.push(i);
1048
+ continue;
1049
+ }
1050
+ if (i = this.tokenizer.reflink(e, this.tokens.links)) {
1051
+ e = e.substring(i.raw.length);
1052
+ let a = t.at(-1);
1053
+ i.type === "text" && a?.type === "text" ? (a.raw += i.raw, a.text += i.text) : t.push(i);
1054
+ continue;
1055
+ }
1056
+ if (i = this.tokenizer.emStrong(e, n, r)) {
1057
+ e = e.substring(i.raw.length), t.push(i);
1058
+ continue;
1059
+ }
1060
+ if (i = this.tokenizer.codespan(e)) {
1061
+ e = e.substring(i.raw.length), t.push(i);
1062
+ continue;
1063
+ }
1064
+ if (i = this.tokenizer.br(e)) {
1065
+ e = e.substring(i.raw.length), t.push(i);
1066
+ continue;
1067
+ }
1068
+ if (i = this.tokenizer.del(e, n, r)) {
1069
+ e = e.substring(i.raw.length), t.push(i);
1070
+ continue;
1071
+ }
1072
+ if (i = this.tokenizer.autolink(e)) {
1073
+ e = e.substring(i.raw.length), t.push(i);
1074
+ continue;
1075
+ }
1076
+ if (!this.state.inLink && (i = this.tokenizer.url(e))) {
1077
+ e = e.substring(i.raw.length), t.push(i);
1078
+ continue;
1079
+ }
1080
+ let l = e;
1081
+ if (this.options.extensions?.startInline) {
1082
+ let a = 1 / 0, p = e.slice(1), c;
1083
+ this.options.extensions.startInline.forEach((h) => {
1084
+ c = h.call({ lexer: this }, p), typeof c == "number" && c >= 0 && (a = Math.min(a, c));
1085
+ }), a < 1 / 0 && a >= 0 && (l = e.substring(0, a + 1));
1086
+ }
1087
+ if (i = this.tokenizer.inlineText(l)) {
1088
+ e = e.substring(i.raw.length), i.raw.slice(-1) !== "_" && (r = i.raw.slice(-1)), s = true;
1089
+ let a = t.at(-1);
1090
+ a?.type === "text" ? (a.raw += i.raw, a.text += i.text) : t.push(i);
1091
+ continue;
1092
+ }
1093
+ if (e) {
1094
+ this.infiniteLoopError(e.charCodeAt(0));
1095
+ break;
1096
+ }
1097
+ }
1098
+ return t;
1099
+ }
1100
+ infiniteLoopError(e) {
1101
+ let t = "Infinite loop on byte: " + e;
1102
+ if (this.options.silent) console.error(t);
1103
+ else throw new Error(t);
1104
+ }
1105
+ };
1106
+ var P = class {
1107
+ options;
1108
+ parser;
1109
+ constructor(e) {
1110
+ this.options = e || T;
1111
+ }
1112
+ space(e) {
1113
+ return "";
1114
+ }
1115
+ code({ text: e, lang: t, escaped: n }) {
1116
+ let s = (t || "").match(m.notSpaceStart)?.[0], r = e ? e.replace(m.endingNewline, "") + `
1117
+ ` : "";
1118
+ return s ? '<pre><code class="language-' + R(s) + '">' + (n ? r : R(r, true)) + `</code></pre>
1119
+ ` : "<pre><code>" + (n ? r : R(r, true)) + `</code></pre>
1120
+ `;
1121
+ }
1122
+ blockquote({ tokens: e }) {
1123
+ return `<blockquote>
1124
+ ${this.parser.parse(e)}</blockquote>
1125
+ `;
1126
+ }
1127
+ html({ text: e }) {
1128
+ return e;
1129
+ }
1130
+ def(e) {
1131
+ return "";
1132
+ }
1133
+ heading({ tokens: e, depth: t }) {
1134
+ return `<h${t}>${this.parser.parseInline(e)}</h${t}>
1135
+ `;
1136
+ }
1137
+ hr(e) {
1138
+ return `<hr>
1139
+ `;
1140
+ }
1141
+ list(e) {
1142
+ let t = e.ordered, n = e.start, s = "";
1143
+ for (let i = 0; i < e.items.length; i++) {
1144
+ let l = e.items[i];
1145
+ s += this.listitem(l);
1146
+ }
1147
+ let r = t ? "ol" : "ul", o = t && n !== 1 ? ' start="' + n + '"' : "";
1148
+ return "<" + r + o + `>
1149
+ ` + s + "</" + r + `>
1150
+ `;
1151
+ }
1152
+ listitem(e) {
1153
+ return `<li>${this.parser.parse(e.tokens)}</li>
1154
+ `;
1155
+ }
1156
+ checkbox({ checked: e }) {
1157
+ return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"> ';
1158
+ }
1159
+ paragraph({ tokens: e }) {
1160
+ return `<p>${this.parser.parseInline(e)}</p>
1161
+ `;
1162
+ }
1163
+ table(e) {
1164
+ let t = "", n = "";
1165
+ for (let r = 0; r < e.header.length; r++) n += this.tablecell(e.header[r]);
1166
+ t += this.tablerow({ text: n });
1167
+ let s = "";
1168
+ for (let r = 0; r < e.rows.length; r++) {
1169
+ let o = e.rows[r];
1170
+ n = "";
1171
+ for (let i = 0; i < o.length; i++) n += this.tablecell(o[i]);
1172
+ s += this.tablerow({ text: n });
1173
+ }
1174
+ return s && (s = `<tbody>${s}</tbody>`), `<table>
1175
+ <thead>
1176
+ ` + t + `</thead>
1177
+ ` + s + `</table>
1178
+ `;
1179
+ }
1180
+ tablerow({ text: e }) {
1181
+ return `<tr>
1182
+ ${e}</tr>
1183
+ `;
1184
+ }
1185
+ tablecell(e) {
1186
+ let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
1187
+ return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
1188
+ `;
1189
+ }
1190
+ strong({ tokens: e }) {
1191
+ return `<strong>${this.parser.parseInline(e)}</strong>`;
1192
+ }
1193
+ em({ tokens: e }) {
1194
+ return `<em>${this.parser.parseInline(e)}</em>`;
1195
+ }
1196
+ codespan({ text: e }) {
1197
+ return `<code>${R(e, true)}</code>`;
1198
+ }
1199
+ br(e) {
1200
+ return "<br>";
1201
+ }
1202
+ del({ tokens: e }) {
1203
+ return `<del>${this.parser.parseInline(e)}</del>`;
1204
+ }
1205
+ link({ href: e, title: t, text: n, tokens: s, autolink: r }) {
1206
+ let o = r ? R(n, true) : this.parser.parseInline(s), i = Y(e);
1207
+ if (i === null) return o;
1208
+ e = R(i, r);
1209
+ let l = '<a href="' + e + '"';
1210
+ return t && (l += ' title="' + R(t) + '"'), l += ">" + o + "</a>", l;
1211
+ }
1212
+ image({ href: e, title: t, text: n, tokens: s }) {
1213
+ s && (n = this.parser.parseInline(s, this.parser.textRenderer));
1214
+ let r = Y(e);
1215
+ if (r === null) return R(n);
1216
+ e = r;
1217
+ let o = `<img src="${R(e)}" alt="${R(n)}"`;
1218
+ return t && (o += ` title="${R(t)}"`), o += ">", o;
1219
+ }
1220
+ text(e) {
1221
+ return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : R(e.text);
1222
+ }
1223
+ };
1224
+ var L = class {
1225
+ strong({ text: e }) {
1226
+ return e;
1227
+ }
1228
+ em({ text: e }) {
1229
+ return e;
1230
+ }
1231
+ codespan({ text: e }) {
1232
+ return e;
1233
+ }
1234
+ del({ text: e }) {
1235
+ return e;
1236
+ }
1237
+ html({ text: e }) {
1238
+ return e;
1239
+ }
1240
+ text({ text: e }) {
1241
+ return e;
1242
+ }
1243
+ link({ text: e }) {
1244
+ return "" + e;
1245
+ }
1246
+ image({ text: e }) {
1247
+ return "" + e;
1248
+ }
1249
+ br() {
1250
+ return "";
1251
+ }
1252
+ checkbox({ raw: e }) {
1253
+ return e;
1254
+ }
1255
+ };
1256
+ var b = class u2 {
1257
+ options;
1258
+ renderer;
1259
+ textRenderer;
1260
+ constructor(e) {
1261
+ this.options = e || T, this.options.renderer = this.options.renderer || new P(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new L();
1262
+ }
1263
+ static parse(e, t) {
1264
+ return new u2(t).parse(e);
1265
+ }
1266
+ static parseInline(e, t) {
1267
+ return new u2(t).parseInline(e);
1268
+ }
1269
+ parse(e) {
1270
+ this.renderer.parser = this;
1271
+ let t = "";
1272
+ for (let n = 0; n < e.length; n++) {
1273
+ let s = e[n];
1274
+ if (this.options.extensions?.renderers?.[s.type]) {
1275
+ let o = s, i = this.options.extensions.renderers[o.type].call({ parser: this }, o);
1276
+ if (i !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "checkbox", "html", "def", "paragraph", "text"].includes(o.type)) {
1277
+ t += i || "";
1278
+ continue;
1279
+ }
1280
+ }
1281
+ let r = s;
1282
+ switch (r.type) {
1283
+ case "space": {
1284
+ t += this.renderer.space(r);
1285
+ break;
1286
+ }
1287
+ case "hr": {
1288
+ t += this.renderer.hr(r);
1289
+ break;
1290
+ }
1291
+ case "heading": {
1292
+ t += this.renderer.heading(r);
1293
+ break;
1294
+ }
1295
+ case "code": {
1296
+ t += this.renderer.code(r);
1297
+ break;
1298
+ }
1299
+ case "table": {
1300
+ t += this.renderer.table(r);
1301
+ break;
1302
+ }
1303
+ case "blockquote": {
1304
+ t += this.renderer.blockquote(r);
1305
+ break;
1306
+ }
1307
+ case "list": {
1308
+ t += this.renderer.list(r);
1309
+ break;
1310
+ }
1311
+ case "checkbox": {
1312
+ t += this.renderer.checkbox(r);
1313
+ break;
1314
+ }
1315
+ case "html": {
1316
+ t += this.renderer.html(r);
1317
+ break;
1318
+ }
1319
+ case "def": {
1320
+ t += this.renderer.def(r);
1321
+ break;
1322
+ }
1323
+ case "paragraph": {
1324
+ t += this.renderer.paragraph(r);
1325
+ break;
1326
+ }
1327
+ case "text": {
1328
+ t += this.renderer.text(r);
1329
+ break;
1330
+ }
1331
+ default: {
1332
+ let o = 'Token with "' + r.type + '" type was not found.';
1333
+ if (this.options.silent) return console.error(o), "";
1334
+ throw new Error(o);
1335
+ }
1336
+ }
1337
+ }
1338
+ return t;
1339
+ }
1340
+ parseInline(e, t = this.renderer) {
1341
+ this.renderer.parser = this;
1342
+ let n = "";
1343
+ for (let s = 0; s < e.length; s++) {
1344
+ let r = e[s];
1345
+ if (this.options.extensions?.renderers?.[r.type]) {
1346
+ let i = this.options.extensions.renderers[r.type].call({ parser: this }, r);
1347
+ if (i !== false || !["escape", "html", "link", "image", "checkbox", "strong", "em", "codespan", "br", "del", "text"].includes(r.type)) {
1348
+ n += i || "";
1349
+ continue;
1350
+ }
1351
+ }
1352
+ let o = r;
1353
+ switch (o.type) {
1354
+ case "escape": {
1355
+ n += t.text(o);
1356
+ break;
1357
+ }
1358
+ case "html": {
1359
+ n += t.html(o);
1360
+ break;
1361
+ }
1362
+ case "link": {
1363
+ n += t.link(o);
1364
+ break;
1365
+ }
1366
+ case "image": {
1367
+ n += t.image(o);
1368
+ break;
1369
+ }
1370
+ case "checkbox": {
1371
+ n += t.checkbox(o);
1372
+ break;
1373
+ }
1374
+ case "strong": {
1375
+ n += t.strong(o);
1376
+ break;
1377
+ }
1378
+ case "em": {
1379
+ n += t.em(o);
1380
+ break;
1381
+ }
1382
+ case "codespan": {
1383
+ n += t.codespan(o);
1384
+ break;
1385
+ }
1386
+ case "br": {
1387
+ n += t.br(o);
1388
+ break;
1389
+ }
1390
+ case "del": {
1391
+ n += t.del(o);
1392
+ break;
1393
+ }
1394
+ case "text": {
1395
+ n += t.text(o);
1396
+ break;
1397
+ }
1398
+ default: {
1399
+ let i = 'Token with "' + o.type + '" type was not found.';
1400
+ if (this.options.silent) return console.error(i), "";
1401
+ throw new Error(i);
1402
+ }
1403
+ }
1404
+ }
1405
+ return n;
1406
+ }
1407
+ };
1408
+ var S = class {
1409
+ options;
1410
+ block;
1411
+ constructor(e) {
1412
+ this.options = e || T;
1413
+ }
1414
+ static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
1415
+ static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
1416
+ preprocess(e) {
1417
+ return e;
1418
+ }
1419
+ postprocess(e) {
1420
+ return e;
1421
+ }
1422
+ processAllTokens(e) {
1423
+ return e;
1424
+ }
1425
+ emStrongMask(e) {
1426
+ return e;
1427
+ }
1428
+ provideLexer(e = this.block) {
1429
+ return e ? x.lex : x.lexInline;
1430
+ }
1431
+ provideParser(e = this.block) {
1432
+ return e ? b.parse : b.parseInline;
1433
+ }
1434
+ };
1435
+ var Z = class {
1436
+ defaults = A();
1437
+ options = this.setOptions;
1438
+ parse = this.parseMarkdown(true);
1439
+ parseInline = this.parseMarkdown(false);
1440
+ Parser = b;
1441
+ Renderer = P;
1442
+ TextRenderer = L;
1443
+ Lexer = x;
1444
+ Tokenizer = y;
1445
+ Hooks = S;
1446
+ constructor(...e) {
1447
+ this.use(...e);
1448
+ }
1449
+ walkTokens(e, t) {
1450
+ let n = [];
1451
+ for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) {
1452
+ case "table": {
1453
+ let r = s;
1454
+ for (let o of r.header) n = n.concat(this.walkTokens(o.tokens, t));
1455
+ for (let o of r.rows) for (let i of o) n = n.concat(this.walkTokens(i.tokens, t));
1456
+ break;
1457
+ }
1458
+ case "list": {
1459
+ let r = s;
1460
+ n = n.concat(this.walkTokens(r.items, t));
1461
+ break;
1462
+ }
1463
+ default: {
1464
+ let r = s;
1465
+ this.defaults.extensions?.childTokens?.[r.type] ? this.defaults.extensions.childTokens[r.type].forEach((o) => {
1466
+ let i = r[o].flat(1 / 0);
1467
+ n = n.concat(this.walkTokens(i, t));
1468
+ }) : r.tokens && (n = n.concat(this.walkTokens(r.tokens, t)));
1469
+ }
1470
+ }
1471
+ return n;
1472
+ }
1473
+ use(...e) {
1474
+ let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
1475
+ return e.forEach((n) => {
1476
+ let s = { ...n };
1477
+ if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((r) => {
1478
+ if (!r.name) throw new Error("extension name required");
1479
+ if ("renderer" in r) {
1480
+ let o = t.renderers[r.name];
1481
+ o ? t.renderers[r.name] = function(...i) {
1482
+ let l = r.renderer.apply(this, i);
1483
+ return l === false && (l = o.apply(this, i)), l;
1484
+ } : t.renderers[r.name] = r.renderer;
1485
+ }
1486
+ if ("tokenizer" in r) {
1487
+ if (!r.level || r.level !== "block" && r.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
1488
+ let o = t[r.level];
1489
+ o ? o.unshift(r.tokenizer) : t[r.level] = [r.tokenizer], r.start && (r.level === "block" ? t.startBlock ? t.startBlock.push(r.start) : t.startBlock = [r.start] : r.level === "inline" && (t.startInline ? t.startInline.push(r.start) : t.startInline = [r.start]));
1490
+ }
1491
+ "childTokens" in r && r.childTokens && (t.childTokens[r.name] = r.childTokens);
1492
+ }), s.extensions = t), n.renderer) {
1493
+ let r = this.defaults.renderer || new P(this.defaults);
1494
+ for (let o in n.renderer) {
1495
+ if (!(o in r)) throw new Error(`renderer '${o}' does not exist`);
1496
+ if (["options", "parser"].includes(o)) continue;
1497
+ let i = o, l = n.renderer[i], a = r[i];
1498
+ r[i] = (...p) => {
1499
+ let c = l.apply(r, p);
1500
+ return c === false && (c = a.apply(r, p)), c || "";
1501
+ };
1502
+ }
1503
+ s.renderer = r;
1504
+ }
1505
+ if (n.tokenizer) {
1506
+ let r = this.defaults.tokenizer || new y(this.defaults);
1507
+ for (let o in n.tokenizer) {
1508
+ if (!(o in r)) throw new Error(`tokenizer '${o}' does not exist`);
1509
+ if (["options", "rules", "lexer"].includes(o)) continue;
1510
+ let i = o, l = n.tokenizer[i], a = r[i];
1511
+ r[i] = (...p) => {
1512
+ let c = l.apply(r, p);
1513
+ return c === false && (c = a.apply(r, p)), c;
1514
+ };
1515
+ }
1516
+ s.tokenizer = r;
1517
+ }
1518
+ if (n.hooks) {
1519
+ let r = this.defaults.hooks || new S();
1520
+ for (let o in n.hooks) {
1521
+ if (!(o in r)) throw new Error(`hook '${o}' does not exist`);
1522
+ if (["options", "block"].includes(o)) continue;
1523
+ let i = o, l = n.hooks[i], a = r[i];
1524
+ S.passThroughHooks.has(o) ? r[i] = (p) => {
1525
+ if (this.defaults.async && S.passThroughHooksRespectAsync.has(o)) return (async () => {
1526
+ let h = await l.call(r, p);
1527
+ return a.call(r, h);
1528
+ })();
1529
+ let c = l.call(r, p);
1530
+ return a.call(r, c);
1531
+ } : r[i] = (...p) => {
1532
+ if (this.defaults.async) return (async () => {
1533
+ let h = await l.apply(r, p);
1534
+ return h === false && (h = await a.apply(r, p)), h;
1535
+ })();
1536
+ let c = l.apply(r, p);
1537
+ return c === false && (c = a.apply(r, p)), c;
1538
+ };
1539
+ }
1540
+ s.hooks = r;
1541
+ }
1542
+ if (n.walkTokens) {
1543
+ let r = this.defaults.walkTokens, o = n.walkTokens;
1544
+ s.walkTokens = function(i) {
1545
+ let l = [];
1546
+ return l.push(o.call(this, i)), r && (l = l.concat(r.call(this, i))), l;
1547
+ };
1548
+ }
1549
+ this.defaults = { ...this.defaults, ...s };
1550
+ }), this;
1551
+ }
1552
+ setOptions(e) {
1553
+ return this.defaults = { ...this.defaults, ...e }, this;
1554
+ }
1555
+ lexer(e, t) {
1556
+ return x.lex(e, t ?? this.defaults);
1557
+ }
1558
+ parser(e, t) {
1559
+ return b.parse(e, t ?? this.defaults);
1560
+ }
1561
+ parseMarkdown(e) {
1562
+ return (n, s) => {
1563
+ let r = { ...s }, o = { ...this.defaults, ...r }, i = this.onError(!!o.silent, !!o.async);
1564
+ if (this.defaults.async === true && r.async === false) return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
1565
+ if (typeof n > "u" || n === null) return i(new Error("marked(): input parameter is undefined or null"));
1566
+ if (typeof n != "string") return i(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
1567
+ if (o.hooks && (o.hooks.options = o, o.hooks.block = e), o.async) return (async () => {
1568
+ let l = o.hooks ? await o.hooks.preprocess(n) : n, p = await (o.hooks ? await o.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(l, o), c = o.hooks ? await o.hooks.processAllTokens(p) : p;
1569
+ o.walkTokens && await Promise.all(this.walkTokens(c, o.walkTokens));
1570
+ let d = await (o.hooks ? await o.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, o);
1571
+ return o.hooks ? await o.hooks.postprocess(d) : d;
1572
+ })().catch(i);
1573
+ try {
1574
+ o.hooks && (n = o.hooks.preprocess(n));
1575
+ let a = (o.hooks ? o.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, o);
1576
+ o.hooks && (a = o.hooks.processAllTokens(a)), o.walkTokens && this.walkTokens(a, o.walkTokens);
1577
+ let c = (o.hooks ? o.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, o);
1578
+ return o.hooks && (c = o.hooks.postprocess(c)), c;
1579
+ } catch (l) {
1580
+ return i(l);
1581
+ }
1582
+ };
1583
+ }
1584
+ onError(e, t) {
1585
+ return (n) => {
1586
+ if (n.message += `
1587
+ Please report this to https://github.com/markedjs/marked.`, e) {
1588
+ let s = "<p>An error occurred:</p><pre>" + R(n.message + "", true) + "</pre>";
1589
+ return t ? Promise.resolve(s) : s;
1590
+ }
1591
+ if (t) return Promise.reject(n);
1592
+ throw n;
1593
+ };
1594
+ }
1595
+ };
1596
+ var M = new Z();
1597
+ function f(u3, e) {
1598
+ return M.parse(u3, e);
1599
+ }
1600
+ f.options = f.setOptions = function(u3) {
1601
+ return M.setOptions(u3), f.defaults = M.defaults, j(f.defaults), f;
1602
+ };
1603
+ f.getDefaults = A;
1604
+ f.defaults = T;
1605
+ function gt(...u3) {
1606
+ return M.use(...u3), f.defaults = M.defaults, j(f.defaults), f;
1607
+ }
1608
+ f.use = gt;
1609
+ f.walkTokens = function(u3, e) {
1610
+ return M.walkTokens(u3, e);
1611
+ };
1612
+ f.parseInline = M.parseInline;
1613
+ f.Parser = b;
1614
+ f.parser = b.parse;
1615
+ f.Renderer = P;
1616
+ f.TextRenderer = L;
1617
+ f.Lexer = x;
1618
+ f.lexer = x.lex;
1619
+ f.Tokenizer = y;
1620
+ f.Hooks = S;
1621
+ f.parse = f;
1622
+ f.options;
1623
+ f.setOptions;
1624
+ f.walkTokens;
1625
+ f.parseInline;
1626
+ b.parse;
1627
+ x.lex;
1628
+
1629
+ // ../../node_modules/dompurify/dist/purify.es.mjs
1630
+ function _arrayLikeToArray(r, a) {
1631
+ (null == a || a > r.length) && (a = r.length);
1632
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
1633
+ return n;
1634
+ }
1635
+ function _arrayWithHoles(r) {
1636
+ if (Array.isArray(r)) return r;
1637
+ }
1638
+ function _iterableToArrayLimit(r, l) {
1639
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
1640
+ if (null != t) {
1641
+ var e, n, i, u3, a = [], f2 = true, o = false;
1642
+ try {
1643
+ if (i = (t = t.call(r)).next, 0 === l) ;
1644
+ else for (; !(f2 = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f2 = true) ;
1645
+ } catch (r2) {
1646
+ o = true, n = r2;
1647
+ } finally {
1648
+ try {
1649
+ if (!f2 && null != t.return && (u3 = t.return(), Object(u3) !== u3)) return;
1650
+ } finally {
1651
+ if (o) throw n;
1652
+ }
1653
+ }
1654
+ return a;
1655
+ }
1656
+ }
1657
+ function _nonIterableRest() {
1658
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1659
+ }
1660
+ function _slicedToArray(r, e) {
1661
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
1662
+ }
1663
+ function _unsupportedIterableToArray(r, a) {
1664
+ if (r) {
1665
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
1666
+ var t = {}.toString.call(r).slice(8, -1);
1667
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
1668
+ }
1669
+ }
1670
+ var entries = Object.entries;
1671
+ var setPrototypeOf = Object.setPrototypeOf;
1672
+ var isFrozen = Object.isFrozen;
1673
+ var getPrototypeOf = Object.getPrototypeOf;
1674
+ var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1675
+ var freeze = Object.freeze;
1676
+ var seal = Object.seal;
1677
+ var create = Object.create;
1678
+ var _ref = typeof Reflect !== "undefined" && Reflect;
1679
+ var apply = _ref.apply;
1680
+ var construct = _ref.construct;
1681
+ if (!freeze) {
1682
+ freeze = function freeze2(x2) {
1683
+ return x2;
1684
+ };
1685
+ }
1686
+ if (!seal) {
1687
+ seal = function seal2(x2) {
1688
+ return x2;
1689
+ };
1690
+ }
1691
+ if (!apply) {
1692
+ apply = function apply2(func, thisArg) {
1693
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
1694
+ args[_key - 2] = arguments[_key];
1695
+ }
1696
+ return func.apply(thisArg, args);
1697
+ };
1698
+ }
1699
+ if (!construct) {
1700
+ construct = function construct2(Func) {
1701
+ for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1702
+ args[_key2 - 1] = arguments[_key2];
1703
+ }
1704
+ return new Func(...args);
1705
+ };
1706
+ }
1707
+ var arrayForEach = unapply(Array.prototype.forEach);
1708
+ var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
1709
+ var arrayPop = unapply(Array.prototype.pop);
1710
+ var arrayPush = unapply(Array.prototype.push);
1711
+ var arraySplice = unapply(Array.prototype.splice);
1712
+ var arrayIsArray = Array.isArray;
1713
+ var stringToLowerCase = unapply(String.prototype.toLowerCase);
1714
+ var stringToString = unapply(String.prototype.toString);
1715
+ var stringMatch = unapply(String.prototype.match);
1716
+ var stringReplace = unapply(String.prototype.replace);
1717
+ var stringIndexOf = unapply(String.prototype.indexOf);
1718
+ var stringTrim = unapply(String.prototype.trim);
1719
+ var numberToString = unapply(Number.prototype.toString);
1720
+ var booleanToString = unapply(Boolean.prototype.toString);
1721
+ var bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
1722
+ var symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
1723
+ var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
1724
+ var objectToString = unapply(Object.prototype.toString);
1725
+ var regExpTest = unapply(RegExp.prototype.test);
1726
+ var typeErrorCreate = unconstruct(TypeError);
1727
+ function unapply(func) {
1728
+ return function(thisArg) {
1729
+ if (thisArg instanceof RegExp) {
1730
+ thisArg.lastIndex = 0;
1731
+ }
1732
+ for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1733
+ args[_key3 - 1] = arguments[_key3];
1734
+ }
1735
+ return apply(func, thisArg, args);
1736
+ };
1737
+ }
1738
+ function unconstruct(Func) {
1739
+ return function() {
1740
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1741
+ args[_key4] = arguments[_key4];
1742
+ }
1743
+ return construct(Func, args);
1744
+ };
1745
+ }
1746
+ function addToSet(set, array) {
1747
+ let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
1748
+ if (setPrototypeOf) {
1749
+ setPrototypeOf(set, null);
1750
+ }
1751
+ if (!arrayIsArray(array)) {
1752
+ return set;
1753
+ }
1754
+ let l = array.length;
1755
+ while (l--) {
1756
+ let element = array[l];
1757
+ if (typeof element === "string") {
1758
+ const lcElement = transformCaseFunc(element);
1759
+ if (lcElement !== element) {
1760
+ if (!isFrozen(array)) {
1761
+ array[l] = lcElement;
1762
+ }
1763
+ element = lcElement;
1764
+ }
1765
+ }
1766
+ set[element] = true;
1767
+ }
1768
+ return set;
1769
+ }
1770
+ function cleanArray(array) {
1771
+ for (let index = 0; index < array.length; index++) {
1772
+ const isPropertyExist = objectHasOwnProperty(array, index);
1773
+ if (!isPropertyExist) {
1774
+ array[index] = null;
1775
+ }
1776
+ }
1777
+ return array;
1778
+ }
1779
+ function clone(object) {
1780
+ const newObject = create(null);
1781
+ for (const _ref2 of entries(object)) {
1782
+ var _ref3 = _slicedToArray(_ref2, 2);
1783
+ const property = _ref3[0];
1784
+ const value = _ref3[1];
1785
+ const isPropertyExist = objectHasOwnProperty(object, property);
1786
+ if (isPropertyExist) {
1787
+ if (arrayIsArray(value)) {
1788
+ newObject[property] = cleanArray(value);
1789
+ } else if (value && typeof value === "object" && value.constructor === Object) {
1790
+ newObject[property] = clone(value);
1791
+ } else {
1792
+ newObject[property] = value;
1793
+ }
1794
+ }
1795
+ }
1796
+ return newObject;
1797
+ }
1798
+ function stringifyValue(value) {
1799
+ switch (typeof value) {
1800
+ case "string": {
1801
+ return value;
1802
+ }
1803
+ case "number": {
1804
+ return numberToString(value);
1805
+ }
1806
+ case "boolean": {
1807
+ return booleanToString(value);
1808
+ }
1809
+ case "bigint": {
1810
+ return bigintToString ? bigintToString(value) : "0";
1811
+ }
1812
+ case "symbol": {
1813
+ return symbolToString ? symbolToString(value) : "Symbol()";
1814
+ }
1815
+ case "undefined": {
1816
+ return objectToString(value);
1817
+ }
1818
+ case "function":
1819
+ case "object": {
1820
+ if (value === null) {
1821
+ return objectToString(value);
1822
+ }
1823
+ const valueAsRecord = value;
1824
+ const valueToString = lookupGetter(valueAsRecord, "toString");
1825
+ if (typeof valueToString === "function") {
1826
+ const stringified = valueToString(valueAsRecord);
1827
+ return typeof stringified === "string" ? stringified : objectToString(stringified);
1828
+ }
1829
+ return objectToString(value);
1830
+ }
1831
+ default: {
1832
+ return objectToString(value);
1833
+ }
1834
+ }
1835
+ }
1836
+ function lookupGetter(object, prop) {
1837
+ while (object !== null) {
1838
+ const desc = getOwnPropertyDescriptor(object, prop);
1839
+ if (desc) {
1840
+ if (desc.get) {
1841
+ return unapply(desc.get);
1842
+ }
1843
+ if (typeof desc.value === "function") {
1844
+ return unapply(desc.value);
1845
+ }
1846
+ }
1847
+ object = getPrototypeOf(object);
1848
+ }
1849
+ function fallbackValue() {
1850
+ return null;
1851
+ }
1852
+ return fallbackValue;
1853
+ }
1854
+ function isRegex(value) {
1855
+ try {
1856
+ regExpTest(value, "");
1857
+ return true;
1858
+ } catch (_unused) {
1859
+ return false;
1860
+ }
1861
+ }
1862
+ var html$1 = freeze(["a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "search", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]);
1863
+ var svg$1 = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "enterkeyhint", "exportparts", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "inputmode", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "part", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]);
1864
+ var svgFilters = freeze(["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence"]);
1865
+ var svgDisallowed = freeze(["animate", "color-profile", "cursor", "discard", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignobject", "hatch", "hatchpath", "mesh", "meshgradient", "meshpatch", "meshrow", "missing-glyph", "script", "set", "solidcolor", "unknown", "use"]);
1866
+ var mathMl$1 = freeze(["math", "menclose", "merror", "mfenced", "mfrac", "mglyph", "mi", "mlabeledtr", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msup", "msubsup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "mprescripts"]);
1867
+ var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
1868
+ var text = freeze(["#text"]);
1869
+ var html = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "command", "commandfor", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "exportparts", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inert", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "part", "pattern", "placeholder", "playsinline", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "slot", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "wrap", "xmlns"]);
1870
+ var svg = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "amplitude", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dominant-baseline", "dur", "edgemode", "elevation", "end", "exponent", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "intercept", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "mask-type", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "pointer-events", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "slope", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "tablevalues", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-orientation", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "vector-effect", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]);
1871
+ var mathMl = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnalign", "columnlines", "columnspacing", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lquote", "lspace", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns"]);
1872
+ var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
1873
+ var MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
1874
+ var ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
1875
+ var TMPLIT_EXPR = seal(/\${[\w\W]*/g);
1876
+ var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
1877
+ var ARIA_ATTR = seal(/^aria-[\-\w]+$/);
1878
+ var IS_ALLOWED_URI = seal(
1879
+ /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
1880
+ // eslint-disable-line no-useless-escape
1881
+ );
1882
+ var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
1883
+ var ATTR_WHITESPACE = seal(
1884
+ /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
1885
+ // eslint-disable-line no-control-regex
1886
+ );
1887
+ var DOCTYPE_NAME = seal(/^html$/i);
1888
+ var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
1889
+ var ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
1890
+ var COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
1891
+ var FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
1892
+ var SELF_CLOSING_TAG = seal(/\/>/i);
1893
+ var NODE_TYPE = {
1894
+ element: 1,
1895
+ attribute: 2,
1896
+ text: 3,
1897
+ cdataSection: 4,
1898
+ entityReference: 5,
1899
+ // Deprecated
1900
+ entityNode: 6,
1901
+ // Deprecated
1902
+ processingInstruction: 7,
1903
+ comment: 8,
1904
+ document: 9,
1905
+ documentType: 10,
1906
+ documentFragment: 11,
1907
+ notation: 12
1908
+ // Deprecated
1909
+ };
1910
+ var LITERAL_TEXT_ELEMENT_NAMES = ["style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript"];
1911
+ var LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));
1912
+ var LITERAL_TEXT_CLOSE = (function() {
1913
+ const map = {};
1914
+ arrayForEach(LITERAL_TEXT_ELEMENT_NAMES, (name) => {
1915
+ map[name] = seal(new RegExp("</" + name + "(?=[\\t\\n\\f\\r />])", "i"));
1916
+ });
1917
+ return freeze(map);
1918
+ })();
1919
+ var getGlobal = function getGlobal2() {
1920
+ return typeof window === "undefined" ? null : window;
1921
+ };
1922
+ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, purifyHostElement) {
1923
+ if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") {
1924
+ return null;
1925
+ }
1926
+ let suffix = null;
1927
+ const ATTR_NAME = "data-tt-policy-suffix";
1928
+ if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
1929
+ suffix = purifyHostElement.getAttribute(ATTR_NAME);
1930
+ }
1931
+ const policyName = "dompurify" + (suffix ? "#" + suffix : "");
1932
+ try {
1933
+ return trustedTypes.createPolicy(policyName, {
1934
+ createHTML(html2) {
1935
+ return html2;
1936
+ },
1937
+ createScriptURL(scriptUrl) {
1938
+ return scriptUrl;
1939
+ }
1940
+ });
1941
+ } catch (_2) {
1942
+ console.warn("TrustedTypes policy " + policyName + " could not be created.");
1943
+ return null;
1944
+ }
1945
+ };
1946
+ var _createHooksMap = function _createHooksMap2() {
1947
+ return {
1948
+ afterSanitizeAttributes: [],
1949
+ afterSanitizeElements: [],
1950
+ afterSanitizeShadowDOM: [],
1951
+ beforeSanitizeAttributes: [],
1952
+ beforeSanitizeElements: [],
1953
+ beforeSanitizeShadowDOM: [],
1954
+ uponSanitizeAttribute: [],
1955
+ uponSanitizeElement: [],
1956
+ uponSanitizeShadowNode: []
1957
+ };
1958
+ };
1959
+ var _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
1960
+ return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
1961
+ };
1962
+ var _resolveObjectOption = function _resolveObjectOption2(cfg, key, makeFallback) {
1963
+ const value = objectHasOwnProperty(cfg, key) ? cfg[key] : void 0;
1964
+ return value && typeof value === "object" ? clone(value) : makeFallback();
1965
+ };
1966
+ function createDOMPurify() {
1967
+ let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
1968
+ const DOMPurify = (root) => createDOMPurify(root);
1969
+ DOMPurify.version = "3.4.15";
1970
+ DOMPurify.removed = [];
1971
+ if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
1972
+ DOMPurify.isSupported = false;
1973
+ return DOMPurify;
1974
+ }
1975
+ let document = window2.document;
1976
+ const originalDocument = document;
1977
+ const currentScript = originalDocument.currentScript;
1978
+ window2.DocumentFragment;
1979
+ const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap;
1980
+ _window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap;
1981
+ window2.HTMLFormElement;
1982
+ const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
1983
+ const ElementPrototype = Element.prototype;
1984
+ const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
1985
+ const remove = lookupGetter(ElementPrototype, "remove");
1986
+ const removeAttributeNode = lookupGetter(ElementPrototype, "removeAttributeNode");
1987
+ const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
1988
+ const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
1989
+ const getParentNode = lookupGetter(ElementPrototype, "parentNode");
1990
+ const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
1991
+ const getAttributes = lookupGetter(ElementPrototype, "attributes");
1992
+ const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
1993
+ const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
1994
+ const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, "ownerDocument") : null;
1995
+ const _readNodeType = function _readNodeType2(node) {
1996
+ return getNodeType ? getNodeType(node) : node.nodeType;
1997
+ };
1998
+ const _readNodeName = function _readNodeName2(node) {
1999
+ return getNodeName ? getNodeName(node) : node.nodeName;
2000
+ };
2001
+ if (typeof HTMLTemplateElement === "function") {
2002
+ const template = document.createElement("template");
2003
+ if (template.content && template.content.ownerDocument) {
2004
+ document = template.content.ownerDocument;
2005
+ }
2006
+ }
2007
+ let trustedTypesPolicy;
2008
+ let emptyHTML = "";
2009
+ let defaultTrustedTypesPolicy;
2010
+ let defaultTrustedTypesPolicyResolved = false;
2011
+ let IN_TRUSTED_TYPES_POLICY = 0;
2012
+ const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy2() {
2013
+ if (IN_TRUSTED_TYPES_POLICY > 0) {
2014
+ throw typeErrorCreate('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.');
2015
+ }
2016
+ };
2017
+ const _createTrustedHTML = function _createTrustedHTML2(html2) {
2018
+ _assertNotInTrustedTypesPolicy();
2019
+ IN_TRUSTED_TYPES_POLICY++;
2020
+ try {
2021
+ return trustedTypesPolicy.createHTML(html2);
2022
+ } finally {
2023
+ IN_TRUSTED_TYPES_POLICY--;
2024
+ }
2025
+ };
2026
+ const _createTrustedScriptURL = function _createTrustedScriptURL2(scriptUrl) {
2027
+ _assertNotInTrustedTypesPolicy();
2028
+ IN_TRUSTED_TYPES_POLICY++;
2029
+ try {
2030
+ return trustedTypesPolicy.createScriptURL(scriptUrl);
2031
+ } finally {
2032
+ IN_TRUSTED_TYPES_POLICY--;
2033
+ }
2034
+ };
2035
+ const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy2() {
2036
+ if (!defaultTrustedTypesPolicyResolved) {
2037
+ defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
2038
+ defaultTrustedTypesPolicyResolved = true;
2039
+ }
2040
+ return defaultTrustedTypesPolicy;
2041
+ };
2042
+ const _document = document, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
2043
+ const importNode = originalDocument.importNode;
2044
+ let hooks = _createHooksMap();
2045
+ DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
2046
+ const MUSTACHE_EXPR$1 = MUSTACHE_EXPR, ERB_EXPR$1 = ERB_EXPR, TMPLIT_EXPR$1 = TMPLIT_EXPR, DATA_ATTR$1 = DATA_ATTR, ARIA_ATTR$1 = ARIA_ATTR, IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA, ATTR_WHITESPACE$1 = ATTR_WHITESPACE, CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
2047
+ let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
2048
+ let ALLOWED_TAGS2 = null;
2049
+ const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
2050
+ let ALLOWED_ATTR2 = null;
2051
+ const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
2052
+ let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
2053
+ tagNameCheck: {
2054
+ writable: true,
2055
+ configurable: false,
2056
+ enumerable: true,
2057
+ value: null
2058
+ },
2059
+ attributeNameCheck: {
2060
+ writable: true,
2061
+ configurable: false,
2062
+ enumerable: true,
2063
+ value: null
2064
+ },
2065
+ allowCustomizedBuiltInElements: {
2066
+ writable: true,
2067
+ configurable: false,
2068
+ enumerable: true,
2069
+ value: false
2070
+ }
2071
+ }));
2072
+ let FORBID_TAGS = null;
2073
+ let FORBID_ATTR = null;
2074
+ const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
2075
+ tagCheck: {
2076
+ writable: true,
2077
+ configurable: false,
2078
+ enumerable: true,
2079
+ value: null
2080
+ },
2081
+ attributeCheck: {
2082
+ writable: true,
2083
+ configurable: false,
2084
+ enumerable: true,
2085
+ value: null
2086
+ }
2087
+ }));
2088
+ let ALLOW_ARIA_ATTR = true;
2089
+ let ALLOW_DATA_ATTR = true;
2090
+ let ALLOW_UNKNOWN_PROTOCOLS = false;
2091
+ let ALLOW_SELF_CLOSE_IN_ATTR = true;
2092
+ let SAFE_FOR_TEMPLATES = false;
2093
+ let SAFE_FOR_XML = true;
2094
+ let WHOLE_DOCUMENT = false;
2095
+ let SET_CONFIG = false;
2096
+ let SET_CONFIG_ALLOWED_TAGS = null;
2097
+ let SET_CONFIG_ALLOWED_ATTR = null;
2098
+ let FORCE_BODY = false;
2099
+ let RETURN_DOM = false;
2100
+ let RETURN_DOM_FRAGMENT = false;
2101
+ let RETURN_TRUSTED_TYPE = false;
2102
+ let SANITIZE_DOM = true;
2103
+ let SANITIZE_NAMED_PROPS = false;
2104
+ const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
2105
+ let KEEP_CONTENT = true;
2106
+ let IN_PLACE = false;
2107
+ let USE_PROFILES = {};
2108
+ let FORBID_CONTENTS = null;
2109
+ const DEFAULT_FORBID_CONTENTS = addToSet({}, [
2110
+ "annotation-xml",
2111
+ "audio",
2112
+ "colgroup",
2113
+ "desc",
2114
+ "foreignobject",
2115
+ "head",
2116
+ "iframe",
2117
+ "math",
2118
+ "mi",
2119
+ "mn",
2120
+ "mo",
2121
+ "ms",
2122
+ "mtext",
2123
+ "noembed",
2124
+ "noframes",
2125
+ "noscript",
2126
+ "plaintext",
2127
+ "script",
2128
+ // <selectedcontent> mirrors the selected <option>'s subtree, cloned by
2129
+ // the UA (customizable <select>) — including any on* handlers — and the
2130
+ // engine re-mirrors synchronously whenever a removal changes which
2131
+ // option/selectedcontent is current, even inside DOMPurify's inert
2132
+ // DOMParser document. Hoisting its children on removal re-inserts a fresh
2133
+ // mirror target ahead of the walk, which the engine refills, looping
2134
+ // forever (DoS) and amplifying output. Dropping its content on removal
2135
+ // (rather than hoisting) breaks that cascade; the content is a duplicate
2136
+ // of the option, which is sanitized on its own. See campaign-3 F1/F6.
2137
+ "selectedcontent",
2138
+ "style",
2139
+ "svg",
2140
+ "template",
2141
+ "thead",
2142
+ "title",
2143
+ "video",
2144
+ "xmp"
2145
+ ]);
2146
+ let DATA_URI_TAGS = null;
2147
+ const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
2148
+ let URI_SAFE_ATTRIBUTES = null;
2149
+ const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ["alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns"]);
2150
+ const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
2151
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
2152
+ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
2153
+ let NAMESPACE = HTML_NAMESPACE;
2154
+ let IS_EMPTY_INPUT = false;
2155
+ let ALLOWED_NAMESPACES = null;
2156
+ const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
2157
+ const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(["mi", "mo", "mn", "ms", "mtext"]);
2158
+ let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
2159
+ const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
2160
+ let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
2161
+ const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
2162
+ let PARSER_MEDIA_TYPE = null;
2163
+ const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
2164
+ const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
2165
+ let transformCaseFunc = null;
2166
+ let CONFIG = null;
2167
+ const formElement = document.createElement("form");
2168
+ const isRegexOrFunction = function isRegexOrFunction2(testValue) {
2169
+ return testValue instanceof RegExp || testValue instanceof Function;
2170
+ };
2171
+ const _parseConfig = function _parseConfig2() {
2172
+ let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
2173
+ if (CONFIG && CONFIG === cfg) {
2174
+ return;
2175
+ }
2176
+ if (!cfg || typeof cfg !== "object") {
2177
+ cfg = {};
2178
+ }
2179
+ cfg = clone(cfg);
2180
+ PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
2181
+ SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
2182
+ transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
2183
+ ALLOWED_TAGS2 = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, {
2184
+ transform: transformCaseFunc
2185
+ });
2186
+ ALLOWED_ATTR2 = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, {
2187
+ transform: transformCaseFunc
2188
+ });
2189
+ ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, {
2190
+ transform: stringToString
2191
+ });
2192
+ URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
2193
+ transform: transformCaseFunc,
2194
+ base: DEFAULT_URI_SAFE_ATTRIBUTES
2195
+ });
2196
+ DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
2197
+ transform: transformCaseFunc,
2198
+ base: DEFAULT_DATA_URI_TAGS
2199
+ });
2200
+ FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, {
2201
+ transform: transformCaseFunc
2202
+ });
2203
+ FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), {
2204
+ transform: transformCaseFunc
2205
+ });
2206
+ FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), {
2207
+ transform: transformCaseFunc
2208
+ });
2209
+ USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
2210
+ ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
2211
+ ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
2212
+ ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
2213
+ ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
2214
+ SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
2215
+ SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
2216
+ WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
2217
+ RETURN_DOM = cfg.RETURN_DOM || false;
2218
+ RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
2219
+ RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
2220
+ FORCE_BODY = cfg.FORCE_BODY || false;
2221
+ SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
2222
+ SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
2223
+ KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
2224
+ IN_PLACE = cfg.IN_PLACE || false;
2225
+ IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
2226
+ NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
2227
+ MATHML_TEXT_INTEGRATION_POINTS = _resolveObjectOption(
2228
+ cfg,
2229
+ "MATHML_TEXT_INTEGRATION_POINTS",
2230
+ () => addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS)
2231
+ // Default built-in map
2232
+ );
2233
+ HTML_INTEGRATION_POINTS = _resolveObjectOption(
2234
+ cfg,
2235
+ "HTML_INTEGRATION_POINTS",
2236
+ () => addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS)
2237
+ // Default built-in map
2238
+ );
2239
+ const customElementHandling = _resolveObjectOption(cfg, "CUSTOM_ELEMENT_HANDLING", () => create(null));
2240
+ CUSTOM_ELEMENT_HANDLING = create(null);
2241
+ if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
2242
+ CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
2243
+ }
2244
+ if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
2245
+ CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
2246
+ }
2247
+ if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
2248
+ CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
2249
+ }
2250
+ seal(CUSTOM_ELEMENT_HANDLING);
2251
+ if (SAFE_FOR_TEMPLATES) {
2252
+ ALLOW_DATA_ATTR = false;
2253
+ }
2254
+ if (RETURN_DOM_FRAGMENT) {
2255
+ RETURN_DOM = true;
2256
+ }
2257
+ if (USE_PROFILES) {
2258
+ ALLOWED_TAGS2 = addToSet({}, text);
2259
+ ALLOWED_ATTR2 = create(null);
2260
+ if (USE_PROFILES.html === true) {
2261
+ addToSet(ALLOWED_TAGS2, html$1);
2262
+ addToSet(ALLOWED_ATTR2, html);
2263
+ }
2264
+ if (USE_PROFILES.svg === true) {
2265
+ addToSet(ALLOWED_TAGS2, svg$1);
2266
+ addToSet(ALLOWED_ATTR2, svg);
2267
+ addToSet(ALLOWED_ATTR2, xml);
2268
+ }
2269
+ if (USE_PROFILES.svgFilters === true) {
2270
+ addToSet(ALLOWED_TAGS2, svgFilters);
2271
+ addToSet(ALLOWED_ATTR2, svg);
2272
+ addToSet(ALLOWED_ATTR2, xml);
2273
+ }
2274
+ if (USE_PROFILES.mathMl === true) {
2275
+ addToSet(ALLOWED_TAGS2, mathMl$1);
2276
+ addToSet(ALLOWED_ATTR2, mathMl);
2277
+ addToSet(ALLOWED_ATTR2, xml);
2278
+ }
2279
+ }
2280
+ EXTRA_ELEMENT_HANDLING.tagCheck = null;
2281
+ EXTRA_ELEMENT_HANDLING.attributeCheck = null;
2282
+ if (objectHasOwnProperty(cfg, "ADD_TAGS")) {
2283
+ if (typeof cfg.ADD_TAGS === "function") {
2284
+ EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
2285
+ } else if (arrayIsArray(cfg.ADD_TAGS)) {
2286
+ if (ALLOWED_TAGS2 === DEFAULT_ALLOWED_TAGS) {
2287
+ ALLOWED_TAGS2 = clone(ALLOWED_TAGS2);
2288
+ }
2289
+ addToSet(ALLOWED_TAGS2, cfg.ADD_TAGS, transformCaseFunc);
2290
+ }
2291
+ }
2292
+ if (objectHasOwnProperty(cfg, "ADD_ATTR")) {
2293
+ if (typeof cfg.ADD_ATTR === "function") {
2294
+ EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
2295
+ } else if (arrayIsArray(cfg.ADD_ATTR)) {
2296
+ if (ALLOWED_ATTR2 === DEFAULT_ALLOWED_ATTR) {
2297
+ ALLOWED_ATTR2 = clone(ALLOWED_ATTR2);
2298
+ }
2299
+ addToSet(ALLOWED_ATTR2, cfg.ADD_ATTR, transformCaseFunc);
2300
+ }
2301
+ }
2302
+ if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
2303
+ if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
2304
+ FORBID_CONTENTS = clone(FORBID_CONTENTS);
2305
+ }
2306
+ addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
2307
+ }
2308
+ if (KEEP_CONTENT) {
2309
+ ALLOWED_TAGS2["#text"] = true;
2310
+ }
2311
+ if (WHOLE_DOCUMENT) {
2312
+ addToSet(ALLOWED_TAGS2, ["html", "head", "body"]);
2313
+ }
2314
+ if (ALLOWED_TAGS2.table) {
2315
+ addToSet(ALLOWED_TAGS2, ["tbody"]);
2316
+ delete FORBID_TAGS.tbody;
2317
+ }
2318
+ if (cfg.TRUSTED_TYPES_POLICY) {
2319
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") {
2320
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
2321
+ }
2322
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
2323
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
2324
+ }
2325
+ const previousTrustedTypesPolicy = trustedTypesPolicy;
2326
+ trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
2327
+ try {
2328
+ emptyHTML = _createTrustedHTML("");
2329
+ } catch (error) {
2330
+ trustedTypesPolicy = previousTrustedTypesPolicy;
2331
+ throw error;
2332
+ }
2333
+ } else if (cfg.TRUSTED_TYPES_POLICY === null) {
2334
+ trustedTypesPolicy = void 0;
2335
+ emptyHTML = "";
2336
+ } else {
2337
+ if (trustedTypesPolicy === void 0) {
2338
+ trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
2339
+ }
2340
+ if (trustedTypesPolicy && typeof emptyHTML === "string") {
2341
+ emptyHTML = _createTrustedHTML("");
2342
+ }
2343
+ }
2344
+ if (freeze) {
2345
+ freeze(cfg);
2346
+ }
2347
+ CONFIG = cfg;
2348
+ };
2349
+ const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
2350
+ const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
2351
+ const _checkSvgNamespace = function _checkSvgNamespace2(tagName, parent, parentTagName) {
2352
+ if (parent.namespaceURI === HTML_NAMESPACE) {
2353
+ return tagName === "svg";
2354
+ }
2355
+ if (parent.namespaceURI === MATHML_NAMESPACE) {
2356
+ return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
2357
+ }
2358
+ return Boolean(ALL_SVG_TAGS[tagName]);
2359
+ };
2360
+ const _checkMathMlNamespace = function _checkMathMlNamespace2(tagName, parent, parentTagName) {
2361
+ if (parent.namespaceURI === HTML_NAMESPACE) {
2362
+ return tagName === "math";
2363
+ }
2364
+ if (parent.namespaceURI === SVG_NAMESPACE) {
2365
+ return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
2366
+ }
2367
+ return Boolean(ALL_MATHML_TAGS[tagName]);
2368
+ };
2369
+ const _checkHtmlNamespace = function _checkHtmlNamespace2(tagName, parent, parentTagName) {
2370
+ if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
2371
+ return false;
2372
+ }
2373
+ if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
2374
+ return false;
2375
+ }
2376
+ return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
2377
+ };
2378
+ const _checkValidNamespace = function _checkValidNamespace2(element) {
2379
+ let parent = getParentNode(element);
2380
+ if (!parent || !parent.tagName) {
2381
+ parent = {
2382
+ namespaceURI: NAMESPACE,
2383
+ tagName: "template"
2384
+ };
2385
+ }
2386
+ const tagName = stringToLowerCase(element.tagName);
2387
+ const parentTagName = stringToLowerCase(parent.tagName);
2388
+ if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
2389
+ return false;
2390
+ }
2391
+ if (element.namespaceURI === SVG_NAMESPACE) {
2392
+ return _checkSvgNamespace(tagName, parent, parentTagName);
2393
+ }
2394
+ if (element.namespaceURI === MATHML_NAMESPACE) {
2395
+ return _checkMathMlNamespace(tagName, parent, parentTagName);
2396
+ }
2397
+ if (element.namespaceURI === HTML_NAMESPACE) {
2398
+ return _checkHtmlNamespace(tagName, parent, parentTagName);
2399
+ }
2400
+ if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
2401
+ return true;
2402
+ }
2403
+ return false;
2404
+ };
2405
+ const _forceRemove = function _forceRemove2(node) {
2406
+ arrayPush(DOMPurify.removed, {
2407
+ element: node
2408
+ });
2409
+ try {
2410
+ getParentNode(node).removeChild(node);
2411
+ } catch (_2) {
2412
+ remove(node);
2413
+ if (!getParentNode(node)) {
2414
+ throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
2415
+ }
2416
+ }
2417
+ };
2418
+ const _stripAttributeNode = function _stripAttributeNode2(element, attribute, name) {
2419
+ try {
2420
+ removeAttributeNode(element, attribute);
2421
+ } catch (_2) {
2422
+ try {
2423
+ element.removeAttribute(name);
2424
+ } catch (_3) {
2425
+ }
2426
+ }
2427
+ };
2428
+ const _neutralizeRoot = function _neutralizeRoot2(root) {
2429
+ _neutralizeSubtree(root);
2430
+ const childNodes = getChildNodes(root);
2431
+ if (childNodes) {
2432
+ const snapshot = [];
2433
+ arrayForEach(childNodes, (child) => {
2434
+ arrayPush(snapshot, child);
2435
+ });
2436
+ arrayForEach(snapshot, (child) => {
2437
+ try {
2438
+ remove(child);
2439
+ } catch (_2) {
2440
+ }
2441
+ });
2442
+ }
2443
+ const attributes = getAttributes(root);
2444
+ if (attributes) {
2445
+ for (let i = attributes.length - 1; i >= 0; --i) {
2446
+ const attribute = attributes[i];
2447
+ const name = attribute && attribute.name;
2448
+ if (typeof name === "string") {
2449
+ _stripAttributeNode(root, attribute, name);
2450
+ }
2451
+ }
2452
+ }
2453
+ };
2454
+ const _removeAttribute = function _removeAttribute2(name, element, attr) {
2455
+ if (!attr) {
2456
+ try {
2457
+ attr = element.getAttributeNode(name);
2458
+ } catch (_2) {
2459
+ attr = null;
2460
+ }
2461
+ }
2462
+ arrayPush(DOMPurify.removed, {
2463
+ attribute: attr || null,
2464
+ from: element
2465
+ });
2466
+ try {
2467
+ if (attr) {
2468
+ removeAttributeNode(element, attr);
2469
+ } else {
2470
+ element.removeAttribute(name);
2471
+ }
2472
+ } catch (_2) {
2473
+ try {
2474
+ element.removeAttribute(name);
2475
+ } catch (_3) {
2476
+ }
2477
+ }
2478
+ if (name === "is") {
2479
+ if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
2480
+ try {
2481
+ _forceRemove(element);
2482
+ } catch (_2) {
2483
+ }
2484
+ } else {
2485
+ try {
2486
+ element.setAttribute(name, "");
2487
+ } catch (_2) {
2488
+ }
2489
+ }
2490
+ }
2491
+ };
2492
+ const _stripDisallowedAttributes = function _stripDisallowedAttributes2(element) {
2493
+ const attributes = getAttributes(element);
2494
+ if (!attributes) {
2495
+ return;
2496
+ }
2497
+ for (let i = attributes.length - 1; i >= 0; --i) {
2498
+ const attribute = attributes[i];
2499
+ const name = attribute && attribute.name;
2500
+ if (typeof name !== "string" || ALLOWED_ATTR2[transformCaseFunc(name)]) {
2501
+ continue;
2502
+ }
2503
+ _stripAttributeNode(element, attribute, name);
2504
+ }
2505
+ };
2506
+ const _neutralizeSubtree = function _neutralizeSubtree2(root) {
2507
+ const stack = [root];
2508
+ while (stack.length > 0) {
2509
+ const node = stack.pop();
2510
+ const nodeType = _readNodeType(node);
2511
+ if (nodeType === NODE_TYPE.element) {
2512
+ _stripDisallowedAttributes(node);
2513
+ }
2514
+ const childNodes = getChildNodes(node);
2515
+ if (childNodes) {
2516
+ for (let i = childNodes.length - 1; i >= 0; --i) {
2517
+ stack.push(childNodes[i]);
2518
+ }
2519
+ }
2520
+ }
2521
+ };
2522
+ const _isPatchLinkageAttribute = function _isPatchLinkageAttribute2(lcName, lcTag) {
2523
+ if (!SAFE_FOR_XML) {
2524
+ return false;
2525
+ }
2526
+ if (lcName === "patchsrc") {
2527
+ return true;
2528
+ }
2529
+ return lcName === "for" && lcTag !== "label" && lcTag !== "output";
2530
+ };
2531
+ const _neutralizePatchLinkage = function _neutralizePatchLinkage2(root) {
2532
+ if (!SAFE_FOR_XML) {
2533
+ return;
2534
+ }
2535
+ const stack = [root];
2536
+ while (stack.length > 0) {
2537
+ const node = stack.pop();
2538
+ const nodeType = _readNodeType(node);
2539
+ if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
2540
+ try {
2541
+ remove(node);
2542
+ } catch (_2) {
2543
+ }
2544
+ continue;
2545
+ }
2546
+ if (nodeType === NODE_TYPE.element) {
2547
+ const element = node;
2548
+ const lcTag = transformCaseFunc(_readNodeName(node));
2549
+ try {
2550
+ if (element.hasAttribute && element.hasAttribute("patchsrc")) {
2551
+ element.removeAttribute("patchsrc");
2552
+ }
2553
+ if (element.hasAttribute && element.hasAttribute("for") && _isPatchLinkageAttribute("for", lcTag)) {
2554
+ element.removeAttribute("for");
2555
+ }
2556
+ } catch (_2) {
2557
+ }
2558
+ }
2559
+ const childNodes = getChildNodes(node);
2560
+ if (childNodes) {
2561
+ for (let i = childNodes.length - 1; i >= 0; --i) {
2562
+ stack.push(childNodes[i]);
2563
+ }
2564
+ }
2565
+ }
2566
+ };
2567
+ const _initDocument = function _initDocument2(dirty) {
2568
+ let doc = null;
2569
+ let leadingWhitespace = null;
2570
+ if (FORCE_BODY) {
2571
+ dirty = "<remove></remove>" + dirty;
2572
+ } else {
2573
+ const matches = stringMatch(dirty, /^[\r\n\t ]+/);
2574
+ leadingWhitespace = matches && matches[0];
2575
+ }
2576
+ if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
2577
+ dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
2578
+ }
2579
+ const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
2580
+ if (NAMESPACE === HTML_NAMESPACE) {
2581
+ try {
2582
+ doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
2583
+ } catch (_2) {
2584
+ }
2585
+ }
2586
+ if (!doc || !doc.documentElement) {
2587
+ doc = implementation.createDocument(NAMESPACE, "template", null);
2588
+ try {
2589
+ doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
2590
+ } catch (_2) {
2591
+ }
2592
+ }
2593
+ const body = doc.body || doc.documentElement;
2594
+ if (dirty && leadingWhitespace) {
2595
+ body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
2596
+ }
2597
+ if (NAMESPACE === HTML_NAMESPACE) {
2598
+ return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
2599
+ }
2600
+ return WHOLE_DOCUMENT ? doc.documentElement : body;
2601
+ };
2602
+ const _createNodeIterator = function _createNodeIterator2(root) {
2603
+ const doc = getOwnerDocument ? getOwnerDocument(root) : root.ownerDocument;
2604
+ return createNodeIterator.call(
2605
+ doc || root,
2606
+ root,
2607
+ // eslint-disable-next-line no-bitwise
2608
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION,
2609
+ null
2610
+ );
2611
+ };
2612
+ const _stripTemplateExpressions = function _stripTemplateExpressions2(value) {
2613
+ value = stringReplace(value, MUSTACHE_EXPR$1, " ");
2614
+ value = stringReplace(value, ERB_EXPR$1, " ");
2615
+ value = stringReplace(value, TMPLIT_EXPR$1, " ");
2616
+ return value;
2617
+ };
2618
+ const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
2619
+ var _node$querySelectorAl;
2620
+ node.normalize();
2621
+ const doc = getOwnerDocument ? getOwnerDocument(node) : node.ownerDocument;
2622
+ const walker = createNodeIterator.call(
2623
+ doc || node,
2624
+ node,
2625
+ // eslint-disable-next-line no-bitwise
2626
+ NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION,
2627
+ null
2628
+ );
2629
+ let currentNode = walker.nextNode();
2630
+ while (currentNode) {
2631
+ currentNode.data = _stripTemplateExpressions(currentNode.data);
2632
+ currentNode = walker.nextNode();
2633
+ }
2634
+ const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
2635
+ if (templates) {
2636
+ arrayForEach(templates, (tmpl) => {
2637
+ if (_isDocumentFragment(tmpl.content)) {
2638
+ _scrubTemplateExpressions2(tmpl.content);
2639
+ }
2640
+ });
2641
+ }
2642
+ };
2643
+ const _isClobbered = function _isClobbered2(element) {
2644
+ const realTagName = getNodeName ? getNodeName(element) : null;
2645
+ if (typeof realTagName !== "string") {
2646
+ return false;
2647
+ }
2648
+ if (transformCaseFunc(realTagName) !== "form") {
2649
+ return false;
2650
+ }
2651
+ return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || // Realm-safe NamedNodeMap detection: equality against the cached
2652
+ // prototype getter. Clobbered .attributes (e.g. <input name="attributes">)
2653
+ // makes the direct read diverge from the cached read; a clean form
2654
+ // (same-realm OR foreign-realm) has both reads pointing at the same
2655
+ // canonical NamedNodeMap.
2656
+ element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || // A form descendant named "removeAttributeNode" or "getAttributeNode"
2657
+ // shadows these Attr-node methods via [LegacyOverrideBuiltIns].
2658
+ // _removeAttribute() / _stripAttributeNode() reach for
2659
+ // element.removeAttributeNode(attr) first; when it is shadowed the call
2660
+ // throws and the name-based fallback element.removeAttribute(name)
2661
+ // ASCII-lowercases its lookup key in an HTML document, silently missing
2662
+ // a case-preserved event-handler attribute (e.g. an ONANIMATIONSTART
2663
+ // that reached the sanitizer through an XML/XHTML parse). Flag the form
2664
+ // so it is removed wholesale, exactly as for the other shadowed methods.
2665
+ typeof element.removeAttributeNode !== "function" || typeof element.getAttributeNode !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || // NodeType clobbering probe. Cached Node.prototype.nodeType getter
2666
+ // returns the integer 1 for any Element regardless of realm; direct
2667
+ // read on a clobbered form (e.g. <input name="nodeType">) returns
2668
+ // the named child element. Cheap addition — nodeType is read from
2669
+ // an internal slot, no serialization cost — and removes a residual
2670
+ // clobbering surface used by several mXSS / PI / comment branches
2671
+ // in _sanitizeElements that compare currentNode.nodeType directly.
2672
+ element.nodeType !== getNodeType(element) || // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
2673
+ // "childNodes" shadows the prototype getter. Direct reads of
2674
+ // form.childNodes from a clobbered form return the named child
2675
+ // instead of the real NodeList, so any walk that reads it directly
2676
+ // skips the form's real children. Compare the direct read to the
2677
+ // cached Node.prototype getter — when the form's named-property
2678
+ // getter intercepts the read, the two values differ and we flag
2679
+ // the form. This catches every clobbering child type (input,
2680
+ // select, etc.) regardless of whether the named child happens to
2681
+ // carry a numeric .length, which a typeof-based probe would miss
2682
+ // (e.g. HTMLSelectElement.length is a defined unsigned-long).
2683
+ element.childNodes !== getChildNodes(element);
2684
+ };
2685
+ const _isDocumentFragment = function _isDocumentFragment2(value) {
2686
+ if (!getNodeType || typeof value !== "object" || value === null) {
2687
+ return false;
2688
+ }
2689
+ try {
2690
+ return getNodeType(value) === NODE_TYPE.documentFragment;
2691
+ } catch (_2) {
2692
+ return false;
2693
+ }
2694
+ };
2695
+ const _isNode = function _isNode2(value) {
2696
+ if (!getNodeType || typeof value !== "object" || value === null) {
2697
+ return false;
2698
+ }
2699
+ try {
2700
+ return typeof getNodeType(value) === "number";
2701
+ } catch (_2) {
2702
+ return false;
2703
+ }
2704
+ };
2705
+ function _executeHooks(hooks2, currentNode, data) {
2706
+ if (hooks2.length === 0) {
2707
+ return;
2708
+ }
2709
+ arrayForEach(hooks2, (hook) => {
2710
+ hook.call(DOMPurify, currentNode, data, CONFIG);
2711
+ });
2712
+ }
2713
+ const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
2714
+ if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
2715
+ return true;
2716
+ }
2717
+ if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && LITERAL_TEXT_ELEMENTS[tagName] && (_isNode(currentNode.firstElementChild) || typeof currentNode.textContent === "string" && regExpTest(LITERAL_TEXT_CLOSE[tagName], currentNode.textContent))) {
2718
+ return true;
2719
+ }
2720
+ if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
2721
+ return true;
2722
+ }
2723
+ if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
2724
+ return true;
2725
+ }
2726
+ return false;
2727
+ };
2728
+ const _matchesNameCheck = function _matchesNameCheck2(check, name) {
2729
+ if (check instanceof RegExp) {
2730
+ return regExpTest(check, name);
2731
+ }
2732
+ if (check instanceof Function) {
2733
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2734
+ args[_key - 2] = arguments[_key];
2735
+ }
2736
+ return Boolean(check(name, ...args));
2737
+ }
2738
+ return false;
2739
+ };
2740
+ const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName, root) {
2741
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
2742
+ return false;
2743
+ }
2744
+ if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
2745
+ const parentNode = getParentNode(currentNode);
2746
+ const childNodes = getChildNodes(currentNode);
2747
+ if (childNodes && parentNode) {
2748
+ const childCount = childNodes.length;
2749
+ for (let i = childCount - 1; i >= 0; --i) {
2750
+ const hoisted = currentNode === root ? cloneNode(childNodes[i], true) : childNodes[i];
2751
+ parentNode.insertBefore(hoisted, getNextSibling(currentNode));
2752
+ }
2753
+ }
2754
+ }
2755
+ _forceRemove(currentNode);
2756
+ return true;
2757
+ };
2758
+ const _forkSharedAllowlist = function _forkSharedAllowlist2(hookList, set, defaultSet, setConfigSet) {
2759
+ if (hookList.length === 0) {
2760
+ return set;
2761
+ }
2762
+ return set === defaultSet || set === setConfigSet ? clone(set) : set;
2763
+ };
2764
+ const _handleHookDetachedNode = function _handleHookDetachedNode2(currentNode, root) {
2765
+ if (currentNode === root || getParentNode(currentNode) !== null) {
2766
+ return false;
2767
+ }
2768
+ if (IN_PLACE) {
2769
+ _neutralizeSubtree(currentNode);
2770
+ }
2771
+ return true;
2772
+ };
2773
+ const _sanitizeElements = function _sanitizeElements2(currentNode, root) {
2774
+ _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
2775
+ if (_handleHookDetachedNode(currentNode, root)) {
2776
+ return true;
2777
+ }
2778
+ if (_isClobbered(currentNode)) {
2779
+ _forceRemove(currentNode);
2780
+ return true;
2781
+ }
2782
+ const tagName = transformCaseFunc(_readNodeName(currentNode));
2783
+ ALLOWED_TAGS2 = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS2, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
2784
+ _executeHooks(hooks.uponSanitizeElement, currentNode, {
2785
+ tagName,
2786
+ allowedTags: ALLOWED_TAGS2
2787
+ });
2788
+ if (_handleHookDetachedNode(currentNode, root)) {
2789
+ return true;
2790
+ }
2791
+ if (_isUnsafeNode(currentNode, tagName)) {
2792
+ _forceRemove(currentNode);
2793
+ return true;
2794
+ }
2795
+ if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS2[tagName]) {
2796
+ const removed = _sanitizeDisallowedNode(currentNode, tagName, root);
2797
+ if (removed === false) {
2798
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2799
+ }
2800
+ return removed;
2801
+ }
2802
+ const nt2 = _readNodeType(currentNode);
2803
+ if (nt2 === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
2804
+ _forceRemove(currentNode);
2805
+ return true;
2806
+ }
2807
+ if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
2808
+ _forceRemove(currentNode);
2809
+ return true;
2810
+ }
2811
+ if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
2812
+ const content = _stripTemplateExpressions(currentNode.textContent);
2813
+ if (currentNode.textContent !== content) {
2814
+ arrayPush(DOMPurify.removed, {
2815
+ element: currentNode.cloneNode()
2816
+ });
2817
+ currentNode.textContent = content;
299
2818
  }
300
- const fileList = files ?? [];
301
- if (fileList.length > maxAttachments) {
302
- emit({ type: "error", error: new Error(`too many attachments: max ${maxAttachments} per message`) });
303
- return;
2819
+ }
2820
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2821
+ return false;
2822
+ };
2823
+ const _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value) {
2824
+ if (FORBID_ATTR[lcName]) {
2825
+ return false;
2826
+ }
2827
+ if (_isPatchLinkageAttribute(lcName, lcTag)) {
2828
+ return false;
2829
+ }
2830
+ if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document || value in formElement)) {
2831
+ return false;
2832
+ }
2833
+ const nameIsPermitted = ALLOWED_ATTR2[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
2834
+ if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) {
2835
+ return true;
2836
+ }
2837
+ if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) {
2838
+ return true;
2839
+ }
2840
+ if (!nameIsPermitted) {
2841
+ return (
2842
+ // Condition a) covers a basically valid custom element tag name whose
2843
+ // tag passes the configured tagNameCheck and whose attribute name
2844
+ // passes the configured attributeNameCheck ...
2845
+ _isBasicCustomElement(lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName, lcTag) || // Condition b) covers an `is` attribute whose value passes the
2846
+ // configured tagNameCheck while customized built-in elements are
2847
+ // allowed.
2848
+ lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)
2849
+ );
2850
+ }
2851
+ if (URI_SAFE_ATTRIBUTES[lcName]) {
2852
+ return true;
2853
+ }
2854
+ if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) {
2855
+ return true;
2856
+ }
2857
+ if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) {
2858
+ return true;
2859
+ }
2860
+ if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) {
2861
+ return true;
2862
+ }
2863
+ return !value;
2864
+ };
2865
+ const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, ["annotation-xml", "color-profile", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "missing-glyph"]);
2866
+ const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
2867
+ return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
2868
+ };
2869
+ const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute2(lcTag, lcName, namespaceURI, value) {
2870
+ if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) {
2871
+ switch (trustedTypes.getAttributeType(lcTag, lcName)) {
2872
+ case "TrustedHTML": {
2873
+ return _createTrustedHTML(value);
2874
+ }
2875
+ case "TrustedScriptURL": {
2876
+ return _createTrustedScriptURL(value);
2877
+ }
304
2878
  }
305
- const oversized = fileList.find((f) => f.size > maxAttachmentBytes);
306
- if (oversized) {
307
- emit({ type: "error", error: new Error(`attachment too large: ${oversized.name} exceeds ${maxAttachmentBytes} bytes`) });
308
- return;
2879
+ }
2880
+ return value;
2881
+ };
2882
+ const _setAttributeValue = function _setAttributeValue2(currentNode, name, namespaceURI, value) {
2883
+ try {
2884
+ if (namespaceURI) {
2885
+ currentNode.setAttributeNS(namespaceURI, name, value);
2886
+ } else {
2887
+ currentNode.setAttribute(name, value);
309
2888
  }
310
- let attachments = [];
311
- if (fileList.length > 0) {
312
- try {
313
- attachments = await uploadFiles(fileList);
314
- } catch (err) {
315
- emit({ type: "error", error: err });
316
- return;
2889
+ if (_isClobbered(currentNode)) {
2890
+ _forceRemove(currentNode);
2891
+ return false;
2892
+ }
2893
+ return true;
2894
+ } catch (_2) {
2895
+ _removeAttribute(name, currentNode);
2896
+ return false;
2897
+ }
2898
+ };
2899
+ const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
2900
+ _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
2901
+ const attributes = currentNode.attributes;
2902
+ if (!attributes || _isClobbered(currentNode)) {
2903
+ return;
2904
+ }
2905
+ ALLOWED_ATTR2 = _forkSharedAllowlist(hooks.uponSanitizeAttribute, ALLOWED_ATTR2, DEFAULT_ALLOWED_ATTR, SET_CONFIG_ALLOWED_ATTR);
2906
+ const hookEvent = {
2907
+ attrName: "",
2908
+ attrValue: "",
2909
+ keepAttr: true,
2910
+ allowedAttributes: ALLOWED_ATTR2,
2911
+ forceKeepAttr: void 0
2912
+ };
2913
+ let l = attributes.length;
2914
+ const lcTag = transformCaseFunc(currentNode.nodeName);
2915
+ while (l--) {
2916
+ const attr = attributes[l];
2917
+ const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
2918
+ const lcName = transformCaseFunc(name);
2919
+ const initValue = attrValue;
2920
+ let value = name === "value" ? initValue : stringTrim(initValue);
2921
+ let recreatedNamedProp = false;
2922
+ hookEvent.attrName = lcName;
2923
+ hookEvent.attrValue = value;
2924
+ hookEvent.keepAttr = true;
2925
+ hookEvent.forceKeepAttr = void 0;
2926
+ _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
2927
+ value = hookEvent.attrValue;
2928
+ if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
2929
+ _removeAttribute(name, currentNode, attr);
2930
+ value = SANITIZE_NAMED_PROPS_PREFIX + value;
2931
+ recreatedNamedProp = true;
2932
+ }
2933
+ if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
2934
+ _removeAttribute(name, currentNode, attr);
2935
+ continue;
2936
+ }
2937
+ if (lcName === "attributename" && stringMatch(value, "href")) {
2938
+ _removeAttribute(name, currentNode, attr);
2939
+ continue;
2940
+ }
2941
+ if (hookEvent.forceKeepAttr) {
2942
+ continue;
2943
+ }
2944
+ if (!hookEvent.keepAttr) {
2945
+ _removeAttribute(name, currentNode, attr);
2946
+ continue;
2947
+ }
2948
+ if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
2949
+ _removeAttribute(name, currentNode, attr);
2950
+ continue;
2951
+ }
2952
+ if (SAFE_FOR_TEMPLATES) {
2953
+ value = _stripTemplateExpressions(value);
2954
+ }
2955
+ if (!_isValidAttribute(lcTag, lcName, value)) {
2956
+ _removeAttribute(name, currentNode, attr);
2957
+ continue;
2958
+ }
2959
+ value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
2960
+ if (value !== initValue) {
2961
+ const cleanWrite = _setAttributeValue(currentNode, name, namespaceURI, value);
2962
+ if (cleanWrite && recreatedNamedProp) {
2963
+ arrayPop(DOMPurify.removed);
317
2964
  }
318
2965
  }
319
- messages.push({ id: uid("u"), role: "user", text, streaming: false, attachments: attachments.length > 0 ? attachments : void 0 });
320
- emitMessages();
2966
+ }
2967
+ _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
2968
+ };
2969
+ const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
2970
+ let shadowNode = null;
2971
+ const shadowIterator = _createNodeIterator(fragment);
2972
+ _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
2973
+ while (shadowNode = shadowIterator.nextNode()) {
2974
+ _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
2975
+ _sanitizeElements(shadowNode, fragment);
2976
+ _sanitizeAttributes(shadowNode);
2977
+ if (_isDocumentFragment(shadowNode.content)) {
2978
+ _sanitizeShadowDOM2(shadowNode.content);
2979
+ }
2980
+ if (_readNodeType(shadowNode) === NODE_TYPE.element) {
2981
+ const innerSr = getShadowRoot(shadowNode);
2982
+ if (_isDocumentFragment(innerSr)) {
2983
+ _sanitizeAttachedShadowRoots(innerSr);
2984
+ _sanitizeShadowDOM2(innerSr);
2985
+ }
2986
+ }
2987
+ }
2988
+ _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
2989
+ };
2990
+ const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots2(root) {
2991
+ const stack = [{
2992
+ node: root,
2993
+ shadow: null
2994
+ }];
2995
+ while (stack.length > 0) {
2996
+ const item = stack.pop();
2997
+ if (item.shadow) {
2998
+ _sanitizeShadowDOM2(item.shadow);
2999
+ continue;
3000
+ }
3001
+ const node = item.node;
3002
+ const nodeType = _readNodeType(node);
3003
+ const isElement = nodeType === NODE_TYPE.element;
3004
+ const childNodes = getChildNodes(node);
3005
+ if (childNodes) {
3006
+ for (let i = childNodes.length - 1; i >= 0; --i) {
3007
+ stack.push({
3008
+ node: childNodes[i],
3009
+ shadow: null
3010
+ });
3011
+ }
3012
+ }
3013
+ if (isElement) {
3014
+ const rootName = getNodeName ? getNodeName(node) : null;
3015
+ if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
3016
+ const content = node.content;
3017
+ if (_isDocumentFragment(content)) {
3018
+ stack.push({
3019
+ node: content,
3020
+ shadow: null
3021
+ });
3022
+ }
3023
+ }
3024
+ }
3025
+ if (isElement) {
3026
+ const sr = getShadowRoot(node);
3027
+ if (_isDocumentFragment(sr)) {
3028
+ stack.push({
3029
+ node: null,
3030
+ shadow: sr
3031
+ }, {
3032
+ node: sr,
3033
+ shadow: null
3034
+ });
3035
+ }
3036
+ }
3037
+ }
3038
+ };
3039
+ DOMPurify.sanitize = function(dirty) {
3040
+ let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
3041
+ let body = null;
3042
+ let importedNode = null;
3043
+ let currentNode = null;
3044
+ let returnNode = null;
3045
+ IS_EMPTY_INPUT = !dirty;
3046
+ if (IS_EMPTY_INPUT) {
3047
+ dirty = "<!-->";
3048
+ }
3049
+ if (typeof dirty !== "string" && !_isNode(dirty)) {
3050
+ dirty = stringifyValue(dirty);
3051
+ if (typeof dirty !== "string") {
3052
+ throw typeErrorCreate("dirty is not a string, aborting");
3053
+ }
3054
+ }
3055
+ if (!DOMPurify.isSupported) {
3056
+ return dirty;
3057
+ }
3058
+ if (SET_CONFIG) {
3059
+ ALLOWED_TAGS2 = SET_CONFIG_ALLOWED_TAGS;
3060
+ ALLOWED_ATTR2 = SET_CONFIG_ALLOWED_ATTR;
3061
+ } else {
3062
+ _parseConfig(cfg);
3063
+ }
3064
+ if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) {
3065
+ ALLOWED_TAGS2 = clone(ALLOWED_TAGS2);
3066
+ }
3067
+ if (hooks.uponSanitizeAttribute.length > 0) {
3068
+ ALLOWED_ATTR2 = clone(ALLOWED_ATTR2);
3069
+ }
3070
+ DOMPurify.removed = [];
3071
+ const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
3072
+ if (inPlace) {
3073
+ _neutralizePatchLinkage(dirty);
3074
+ const nn = _readNodeName(dirty);
3075
+ if (typeof nn === "string") {
3076
+ const tagName = transformCaseFunc(nn);
3077
+ if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
3078
+ _neutralizeRoot(dirty);
3079
+ throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
3080
+ }
3081
+ }
3082
+ if (_isClobbered(dirty)) {
3083
+ _neutralizeRoot(dirty);
3084
+ throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
3085
+ }
321
3086
  try {
322
- await postMessage({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, text, attachments, fetchImpl });
323
- } catch (err) {
324
- if (err instanceof ChatApiError && err.code === "session_expired") {
325
- try {
326
- await open();
327
- const freshAttachments = fileList.length ? await uploadFiles(fileList) : [];
328
- await postMessage({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, text, attachments: freshAttachments, fetchImpl });
329
- } catch (retryErr) {
330
- emit({ type: "error", error: retryErr });
3087
+ _sanitizeAttachedShadowRoots(dirty);
3088
+ } catch (error) {
3089
+ _neutralizeRoot(dirty);
3090
+ throw error;
3091
+ }
3092
+ } else if (_isNode(dirty)) {
3093
+ body = _initDocument("<!---->");
3094
+ importedNode = body.ownerDocument.importNode(dirty, true);
3095
+ if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") {
3096
+ body = importedNode;
3097
+ } else if (importedNode.nodeName === "HTML") {
3098
+ body = importedNode;
3099
+ } else {
3100
+ body.appendChild(importedNode);
3101
+ }
3102
+ _sanitizeAttachedShadowRoots(body);
3103
+ } else {
3104
+ if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
3105
+ dirty.indexOf("<") === -1) {
3106
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
3107
+ }
3108
+ body = _initDocument(dirty);
3109
+ if (!body) {
3110
+ return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
3111
+ }
3112
+ }
3113
+ if (body && FORCE_BODY) {
3114
+ _forceRemove(body.firstChild);
3115
+ }
3116
+ const walkRoot = inPlace ? dirty : body;
3117
+ try {
3118
+ const nodeIterator = _createNodeIterator(walkRoot);
3119
+ while (currentNode = nodeIterator.nextNode()) {
3120
+ _sanitizeElements(currentNode, walkRoot);
3121
+ _sanitizeAttributes(currentNode);
3122
+ if (_isDocumentFragment(currentNode.content)) {
3123
+ _sanitizeShadowDOM2(currentNode.content);
3124
+ }
3125
+ }
3126
+ } catch (error) {
3127
+ if (inPlace) {
3128
+ _neutralizeRoot(dirty);
3129
+ arrayForEach(DOMPurify.removed, (entry) => {
3130
+ if (entry.element) {
3131
+ _neutralizeSubtree(entry.element);
331
3132
  }
332
- } else {
333
- emit({ type: "error", error: err });
3133
+ });
3134
+ }
3135
+ throw error;
3136
+ }
3137
+ if (inPlace) {
3138
+ arrayForEach(DOMPurify.removed, (entry) => {
3139
+ if (entry.element) {
3140
+ _neutralizeSubtree(entry.element);
334
3141
  }
3142
+ });
3143
+ if (SAFE_FOR_TEMPLATES) {
3144
+ _scrubTemplateExpressions2(dirty);
335
3145
  }
336
- },
337
- async end() {
338
- closed = true;
339
- clearReconnect();
340
- if (session) await endSession({ baseUrl: options.baseUrl, sessionId: session.sessionId, sessionToken: session.sessionToken, fetchImpl });
341
- es?.close();
342
- es = null;
343
- setState("ended");
3146
+ return dirty;
3147
+ }
3148
+ if (RETURN_DOM) {
3149
+ if (SAFE_FOR_TEMPLATES) {
3150
+ _scrubTemplateExpressions2(body);
3151
+ }
3152
+ if (RETURN_DOM_FRAGMENT) {
3153
+ returnNode = createDocumentFragment.call(body.ownerDocument);
3154
+ while (body.firstChild) {
3155
+ returnNode.appendChild(body.firstChild);
3156
+ }
3157
+ } else {
3158
+ returnNode = body;
3159
+ }
3160
+ if (ALLOWED_ATTR2.shadowroot || ALLOWED_ATTR2.shadowrootmode) {
3161
+ returnNode = importNode.call(originalDocument, returnNode, true);
3162
+ }
3163
+ return returnNode;
3164
+ }
3165
+ let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
3166
+ if (WHOLE_DOCUMENT && ALLOWED_TAGS2["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
3167
+ serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
3168
+ }
3169
+ if (SAFE_FOR_TEMPLATES) {
3170
+ serializedHTML = _stripTemplateExpressions(serializedHTML);
3171
+ }
3172
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
3173
+ };
3174
+ DOMPurify.setConfig = function() {
3175
+ let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
3176
+ _parseConfig(cfg);
3177
+ SET_CONFIG = true;
3178
+ SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS2;
3179
+ SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR2;
3180
+ };
3181
+ DOMPurify.clearConfig = function() {
3182
+ CONFIG = null;
3183
+ SET_CONFIG = false;
3184
+ SET_CONFIG_ALLOWED_TAGS = null;
3185
+ SET_CONFIG_ALLOWED_ATTR = null;
3186
+ trustedTypesPolicy = defaultTrustedTypesPolicy;
3187
+ emptyHTML = "";
3188
+ };
3189
+ DOMPurify.isValidAttribute = function(tag, attr, value) {
3190
+ if (!CONFIG) {
3191
+ _parseConfig({});
3192
+ }
3193
+ const lcTag = transformCaseFunc(tag);
3194
+ const lcName = transformCaseFunc(attr);
3195
+ return _isValidAttribute(lcTag, lcName, value);
3196
+ };
3197
+ DOMPurify.addHook = function(entryPoint, hookFunction) {
3198
+ if (typeof hookFunction !== "function") {
3199
+ return;
3200
+ }
3201
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
3202
+ return;
3203
+ }
3204
+ arrayPush(hooks[entryPoint], hookFunction);
3205
+ };
3206
+ DOMPurify.removeHook = function(entryPoint, hookFunction) {
3207
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
3208
+ return void 0;
3209
+ }
3210
+ if (hookFunction !== void 0) {
3211
+ const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
3212
+ return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
3213
+ }
3214
+ return arrayPop(hooks[entryPoint]);
3215
+ };
3216
+ DOMPurify.removeHooks = function(entryPoint) {
3217
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
3218
+ return;
344
3219
  }
3220
+ hooks[entryPoint] = [];
345
3221
  };
3222
+ DOMPurify.removeAllHooks = function() {
3223
+ hooks = _createHooksMap();
3224
+ };
3225
+ return DOMPurify;
3226
+ }
3227
+ var purify = createDOMPurify();
3228
+
3229
+ // src/markdown.ts
3230
+ f.setOptions({ gfm: true, breaks: true });
3231
+ var hookInstalled = false;
3232
+ function installLinkHook() {
3233
+ if (hookInstalled) return;
3234
+ purify.addHook("afterSanitizeAttributes", (node) => {
3235
+ if (node.nodeName === "A") {
3236
+ node.setAttribute("target", "_blank");
3237
+ node.setAttribute("rel", "noopener noreferrer nofollow");
3238
+ }
3239
+ });
3240
+ hookInstalled = true;
3241
+ }
3242
+ var ALLOWED_TAGS = [
3243
+ "p",
3244
+ "br",
3245
+ "strong",
3246
+ "em",
3247
+ "b",
3248
+ "i",
3249
+ "del",
3250
+ "s",
3251
+ "code",
3252
+ "pre",
3253
+ "blockquote",
3254
+ "ul",
3255
+ "ol",
3256
+ "li",
3257
+ "a",
3258
+ "h1",
3259
+ "h2",
3260
+ "h3",
3261
+ "h4",
3262
+ "h5",
3263
+ "h6",
3264
+ "hr",
3265
+ "table",
3266
+ "thead",
3267
+ "tbody",
3268
+ "tr",
3269
+ "th",
3270
+ "td",
3271
+ "span"
3272
+ ];
3273
+ var ALLOWED_ATTR = ["href", "target", "rel", "class"];
3274
+ function renderMarkdown(text2) {
3275
+ installLinkHook();
3276
+ const raw = f.parse(text2, { async: false });
3277
+ return purify.sanitize(raw, {
3278
+ ALLOWED_TAGS,
3279
+ ALLOWED_ATTR,
3280
+ ALLOW_DATA_ATTR: false,
3281
+ ALLOWED_URI_REGEXP: /^(?:https?:|mailto:)/i
3282
+ });
3283
+ }
3284
+
3285
+ // src/styles.ts
3286
+ var STYLES = `
3287
+ :host {
3288
+ /* accent (consumer-overridable via --oc-accent) + its derivations */
3289
+ --oc-ac: var(--oc-accent, #096DD9);
3290
+ --oc-btn-rim: color-mix(in oklab, var(--oc-ac) 70%, black);
3291
+ --oc-btn-edge: 0 6px 16px -10px color-mix(in oklab, var(--oc-ac) 55%, transparent);
3292
+ --oc-danger: #D92D20;
3293
+ --oc-ease: cubic-bezier(0.16,1,0.3,1);
3294
+ --oc-bounce: cubic-bezier(0.18,0.89,0.32,1.13);
3295
+ --oc-mono: 'Geist Mono', ui-monospace, monospace;
3296
+ --oc-r-full: 999px;
3297
+
3298
+ /* light palette (base) */
3299
+ --oc-bg: #FFFFFF; --oc-bg-sunk: #F6F8FB;
3300
+ --oc-fg: #0A0D12; --oc-fg-muted: rgba(10,13,18,0.66); --oc-fg-dim: rgba(10,13,18,0.44);
3301
+ --oc-border: rgba(9,13,20,0.10);
3302
+ --oc-accent-text: color-mix(in oklab, var(--oc-ac) 88%, black);
3303
+ --oc-tint-1: rgba(9,13,20,0.025); --oc-tint-2: rgba(9,13,20,0.04); --oc-tint-3: rgba(9,13,20,0.055);
3304
+ --oc-field-bg: #FFFFFF; --oc-field-border: rgba(9,13,20,0.22);
3305
+ --oc-glass-border: rgba(9,13,20,0.12);
3306
+
3307
+ position: fixed; right: 24px; bottom: 24px; z-index: 2147483000;
3308
+ font-family: 'Geist', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
3309
+ -webkit-font-smoothing: antialiased;
3310
+ }
3311
+ @media (prefers-color-scheme: dark) {
3312
+ :host(:not([theme="light"])) {
3313
+ --oc-bg: #000000; --oc-bg-sunk: #000000;
3314
+ --oc-fg: #FFFFFF; --oc-fg-muted: rgba(255,255,255,0.68); --oc-fg-dim: rgba(255,255,255,0.42);
3315
+ --oc-border: rgba(255,255,255,0.09);
3316
+ --oc-accent-text: color-mix(in oklab, var(--oc-ac) 62%, white);
3317
+ --oc-tint-1: rgba(255,255,255,0.03); --oc-tint-2: rgba(255,255,255,0.05); --oc-tint-3: rgba(255,255,255,0.07);
3318
+ --oc-field-bg: rgba(255,255,255,0.045); --oc-field-border: rgba(255,255,255,0.20);
3319
+ --oc-glass-border: rgba(255,255,255,0.12);
3320
+ }
3321
+ }
3322
+ :host([theme="dark"]) {
3323
+ --oc-bg: #000000; --oc-bg-sunk: #000000;
3324
+ --oc-fg: #FFFFFF; --oc-fg-muted: rgba(255,255,255,0.68); --oc-fg-dim: rgba(255,255,255,0.42);
3325
+ --oc-border: rgba(255,255,255,0.09);
3326
+ --oc-accent-text: color-mix(in oklab, var(--oc-ac) 62%, white);
3327
+ --oc-tint-1: rgba(255,255,255,0.03); --oc-tint-2: rgba(255,255,255,0.05); --oc-tint-3: rgba(255,255,255,0.07);
3328
+ --oc-field-bg: rgba(255,255,255,0.045); --oc-field-border: rgba(255,255,255,0.20);
3329
+ --oc-glass-border: rgba(255,255,255,0.12);
3330
+ }
3331
+ * { box-sizing: border-box; }
3332
+ button { font-family: inherit; }
3333
+
3334
+ .oc { display: flex; flex-direction: column; align-items: flex-end; gap: 14px; }
3335
+
3336
+ /* \u2500\u2500 Launcher \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3337
+ .launcher {
3338
+ position: relative; flex: none; width: 46px; height: 46px; border-radius: var(--oc-r-full);
3339
+ border: 1px solid var(--oc-btn-rim); background: var(--oc-ac);
3340
+ box-shadow: 0 8px 22px -8px color-mix(in oklab, var(--oc-ac) 70%, transparent), 0 18px 48px -18px rgba(0,0,0,0.6);
3341
+ color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer;
3342
+ transition: transform .26s var(--oc-bounce), filter .2s var(--oc-ease); align-self: flex-end;
3343
+ }
3344
+ .launcher:hover { transform: scale(1.06); }
3345
+ .launcher:active { transform: scale(0.93); }
3346
+ .ring { pointer-events: none; position: absolute; inset: -1px; border-radius: var(--oc-r-full); border: 2px solid var(--oc-ac); opacity: 0; }
3347
+ .oc.ring:not(.open) .ring { animation: w-ring 2.4s ease-out 1.1s 3; }
3348
+ .ic-chat, .ic-close { position: absolute; display: flex; align-items: center; justify-content: center; transition: all .3s var(--oc-bounce); }
3349
+ .ic-chat { width: 28px; height: 28px; opacity: 1; transform: rotate(0) scale(1); }
3350
+ .ic-close { opacity: 0; transform: rotate(90deg) scale(0.6); }
3351
+ .oc.open .ic-chat { opacity: 0; transform: rotate(-90deg) scale(0.6); }
3352
+ .oc.open .ic-close { opacity: 1; transform: rotate(0) scale(1); }
3353
+ .badge {
3354
+ position: absolute; top: -2px; right: -2px; min-width: 17px; height: 17px; padding: 0 5px;
3355
+ border-radius: var(--oc-r-full); border: 2px solid var(--oc-bg-sunk); background: var(--oc-danger);
3356
+ color: #fff; font-family: var(--oc-mono); font-size: 10px; font-weight: 700;
3357
+ display: flex; align-items: center; justify-content: center; opacity: 0; transform: scale(0.4);
3358
+ transition: all .26s var(--oc-bounce);
3359
+ }
3360
+ .oc.unread:not(.open) .badge { opacity: 1; transform: scale(1); }
3361
+
3362
+ /* \u2500\u2500 Teaser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3363
+ .teaser {
3364
+ position: absolute; right: 0; bottom: 60px; display: none; align-items: center; gap: 11px;
3365
+ opacity: 0; transform: translateY(8px) scale(0.94); pointer-events: none;
3366
+ transition: opacity .3s var(--oc-ease), transform .38s var(--oc-bounce);
3367
+ }
3368
+ .oc.has-teaser .teaser { display: flex; }
3369
+ .oc.teaser:not(.open) .teaser { opacity: 1; transform: none; pointer-events: auto; }
3370
+ .teaser-btn {
3371
+ max-width: 250px; display: flex; align-items: center; gap: 10px; padding: 11px 15px;
3372
+ border-radius: 16px 16px 5px 16px; border: 1px solid var(--oc-glass-border); background: var(--oc-bg);
3373
+ box-shadow: 0 10px 30px -14px rgba(0,0,0,0.5); color: var(--oc-fg); font-size: 13.5px; line-height: 1.45;
3374
+ text-align: left; cursor: pointer; transition: transform .2s var(--oc-ease);
3375
+ }
3376
+ .teaser-btn:hover { transform: translateY(-1px); }
3377
+ .teaser-btn .logo { flex: none; width: 24px; height: 24px; border-radius: 6px; overflow: hidden; color: var(--oc-ac); }
3378
+ .teaser-x {
3379
+ flex: none; width: 22px; height: 22px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border);
3380
+ background: var(--oc-bg); color: var(--oc-fg-dim); display: flex; align-items: center; justify-content: center; cursor: pointer;
3381
+ }
3382
+ .teaser-x:hover { color: var(--oc-fg); }
3383
+
3384
+ /* \u2500\u2500 Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3385
+ .panel {
3386
+ position: relative; width: min(384px, calc(100vw - 40px)); height: min(560px, calc(100vh - 108px));
3387
+ display: flex; flex-direction: column; border-radius: 20px; border: 1px solid var(--oc-glass-border);
3388
+ background: var(--oc-bg); box-shadow: 0 12px 28px -12px rgba(0,0,0,0.28), 0 40px 90px -30px rgba(0,0,0,0.55);
3389
+ overflow: hidden; transform-origin: bottom right;
3390
+ opacity: 0; transform: translateY(16px) scale(0.94); pointer-events: none; visibility: hidden;
3391
+ transition: opacity .24s var(--oc-ease), transform .34s var(--oc-bounce), visibility .34s, width .3s var(--oc-ease), height .3s var(--oc-ease);
3392
+ }
3393
+ .oc.open .panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }
3394
+ .oc.max .panel { width: min(720px, calc(100vw - 40px)); height: calc(100vh - 108px); }
3395
+
3396
+ .hd { position: relative; flex: none; display: flex; align-items: center; gap: 12px; padding: 13px 14px 12px; background: var(--oc-ac); color: #fff; overflow: hidden; }
3397
+ .hd-grid { pointer-events: none; position: absolute; inset: 0; background-image: linear-gradient(90deg, rgba(255,255,255,0.11) 1px, transparent 1px), linear-gradient(180deg, rgba(255,255,255,0.11) 1px, transparent 1px); background-size: 26px 26px; }
3398
+ .hd .logo { position: relative; flex: none; width: 32px; height: 32px; border-radius: 7px; overflow: hidden; color: rgba(255,255,255,0.22); }
3399
+ .hd-txt { position: relative; flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
3400
+ .hd-title { font-size: 14.5px; font-weight: 600; letter-spacing: -0.015em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
3401
+ .hd-status { display: flex; align-items: center; gap: 6px; font-size: 11.5px; opacity: 0.9; }
3402
+ .hd-status .dot { width: 6px; height: 6px; border-radius: var(--oc-r-full); background: #7BE3A6; flex: none; }
3403
+ .hd-status .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
3404
+ .hd-btn { position: relative; flex: none; width: 28px; height: 28px; border-radius: 8px; border: none; background: rgba(255,255,255,0.16); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background .18s var(--oc-ease); }
3405
+ .hd-btn:hover { background: rgba(255,255,255,0.28); }
3406
+ .hd-btn .i { position: absolute; display: flex; transition: opacity .2s var(--oc-ease); }
3407
+ .i-expand { opacity: 1; } .i-shrink { opacity: 0; }
3408
+ .oc.max .i-expand { opacity: 0; } .oc.max .i-shrink { opacity: 1; }
3409
+
3410
+ .err { flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 16px; font-size: 12px; color: #fff; background: var(--oc-danger); }
3411
+ .err .retry { padding: 3px 10px; font-size: 11px; background: rgba(255,255,255,0.2); color: #fff; border: none; border-radius: 6px; cursor: pointer; }
3412
+
3413
+ /* \u2500\u2500 Message list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3414
+ .body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; padding: 16px 16px 26px; background: var(--oc-bg); scroll-behavior: smooth; }
3415
+ .turn { display: flex; flex-direction: column; gap: 6px; animation: w-in .42s var(--oc-ease) both; }
3416
+ .turn.bot { align-items: flex-start; } .turn.user { align-items: flex-end; }
3417
+ .b { font-size: 13.5px; line-height: 1.55; text-wrap: pretty; word-break: break-word; }
3418
+ .turn.bot .b { max-width: 86%; padding: 13px 15px; border-radius: 20px; background: var(--oc-tint-2); color: var(--oc-fg); }
3419
+ .turn.user .b { max-width: 82%; padding: 11px 15px; border-radius: var(--oc-r-full); background: var(--oc-ac); color: #fff; }
3420
+ .turn.human .b { max-width: 86%; padding: 13px 15px; border-radius: 20px; background: color-mix(in oklab, var(--oc-ac) 16%, transparent); color: var(--oc-fg); }
3421
+ .src { display: inline-flex; align-items: center; gap: 7px; padding: 5px 10px 5px 8px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border); background: var(--oc-tint-1); max-width: 100%; }
3422
+ .src .t { min-width: 0; font-size: 11.5px; color: var(--oc-fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
3423
+ .byline { display: flex; align-items: center; gap: 6px; padding: 0 4px; font-size: 11.5px; color: var(--oc-fg-dim); }
3424
+ .human-label { font-size: 11px; font-weight: 600; opacity: .7; margin-bottom: 2px; }
3425
+
3426
+ /* markdown inside a bot bubble */
3427
+ .md > :first-child { margin-top: 0; } .md > :last-child { margin-bottom: 0; }
3428
+ .md p { margin: 0 0 8px; } .md ul, .md ol { margin: 0 0 8px; padding-left: 20px; } .md li { margin: 2px 0; }
3429
+ .md a { color: var(--oc-accent-text); text-decoration: underline; text-underline-offset: 2px; }
3430
+ .md code { font-family: var(--oc-mono); font-size: 12.5px; background: var(--oc-tint-3); padding: 1px 5px; border-radius: 5px; }
3431
+ .md pre { background: color-mix(in oklab, var(--oc-fg) 10%, transparent); padding: 10px 12px; border-radius: 8px; overflow-x: auto; margin: 0 0 8px; }
3432
+ .md pre code { background: none; padding: 0; }
3433
+ .md blockquote { margin: 0 0 8px; padding-left: 10px; border-left: 3px solid var(--oc-border); color: var(--oc-fg-muted); }
3434
+ .md h1, .md h2, .md h3, .md h4 { margin: 8px 0 6px; font-size: 15px; }
3435
+ .md table { border-collapse: collapse; font-size: 13px; margin: 0 0 8px; display: block; overflow-x: auto; }
3436
+ .md th, .md td { border: 1px solid var(--oc-border); padding: 4px 8px; }
3437
+ .att-thumb { display: block; max-width: 180px; max-height: 180px; border-radius: 8px; margin-bottom: 6px; }
3438
+ .att-chip { display: inline-block; font-size: 12px; background: var(--oc-tint-3); border-radius: 6px; padding: 2px 8px; margin: 0 0 6px; }
3439
+ .turn.user .att-chip { background: rgba(255,255,255,0.25); }
3440
+
3441
+ .typing { align-self: flex-start; display: flex; align-items: center; gap: 5px; padding: 13px 16px; border-radius: 20px; background: var(--oc-tint-2); animation: w-in .3s var(--oc-ease) both; }
3442
+ .typing span { width: 6px; height: 6px; border-radius: var(--oc-r-full); background: var(--oc-fg-muted); animation: w-dot 1.2s ease-in-out infinite; }
3443
+ .typing span:nth-child(2) { animation-delay: .15s; } .typing span:nth-child(3) { animation-delay: .3s; }
3444
+
3445
+ .chips { display: flex; flex-wrap: wrap; gap: 7px; padding-top: 2px; animation: w-in .42s var(--oc-ease) both; animation-delay: .3s; }
3446
+ .chip { padding: 8px 13px; border-radius: var(--oc-r-full); border: 1px solid color-mix(in oklab, var(--oc-ac) 34%, transparent); background: color-mix(in oklab, var(--oc-ac) 10%, transparent); color: var(--oc-accent-text); font-size: 12px; font-weight: 500; cursor: pointer; white-space: nowrap; transition: all .18s var(--oc-ease); }
3447
+ .chip:hover { background: color-mix(in oklab, var(--oc-ac) 18%, transparent); }
3448
+
3449
+ /* \u2500\u2500 Jump to latest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3450
+ .jump-wrap { position: relative; flex: none; height: 0; z-index: 2; display: flex; justify-content: center; }
3451
+ .jump { position: absolute; bottom: 8px; width: 34px; height: 34px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border); background: var(--oc-bg); box-shadow: 0 8px 20px -10px rgba(0,0,0,0.5); color: var(--oc-fg-muted); display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transform: translateY(6px) scale(0.8); pointer-events: none; transition: all .22s var(--oc-ease); }
3452
+ .oc.away .jump { opacity: 1; transform: none; pointer-events: auto; }
3453
+ .jump:hover { color: var(--oc-fg); border-color: var(--oc-fg-dim); }
3454
+
3455
+ /* \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3456
+ .composer { flex: none; display: flex; flex-direction: column; gap: 9px; padding: 12px 14px 13px; background: var(--oc-bg); }
3457
+ .field { display: flex; flex-direction: column; gap: 11px; padding: 13px 14px 11px; border-radius: 18px; border: 1px solid var(--oc-field-border); background: var(--oc-field-bg); transition: border-color .18s var(--oc-ease); }
3458
+ .oc.focus .field { border-color: var(--oc-ac); }
3459
+ .input { width: 100%; border: none; background: transparent; color: var(--oc-fg); font-size: 13.5px; line-height: 1.4; outline: none; padding: 0; resize: none; max-height: 108px; font-family: inherit; }
3460
+ .input::placeholder { color: var(--oc-fg-dim); }
3461
+ .acts { display: flex; align-items: center; gap: 16px; }
3462
+ .act { flex: none; display: flex; border: none; background: transparent; padding: 4px; margin: -4px; color: var(--oc-fg-dim); cursor: pointer; transition: color .18s var(--oc-ease); }
3463
+ .act:hover { color: var(--oc-fg-muted); }
3464
+ .oc.emoji .act.emoji-btn { color: var(--oc-accent-text); }
3465
+ .send { flex: none; margin-left: auto; width: 34px; height: 34px; border-radius: var(--oc-r-full); border: 1px solid var(--oc-border); background: var(--oc-tint-3); color: var(--oc-fg-dim); box-shadow: none; display: flex; align-items: center; justify-content: center; cursor: default; transition: all .22s var(--oc-ease); }
3466
+ .oc.ready .send { border-color: var(--oc-btn-rim); background: var(--oc-ac); color: #fff; box-shadow: var(--oc-btn-edge); cursor: pointer; }
3467
+ .oc.ready .send:hover { filter: brightness(1.1); }
3468
+ .send:active { transform: scale(0.92); }
3469
+
3470
+ .foot { position: relative; display: none; text-align: center; font-size: 11.5px; line-height: 1.5; color: var(--oc-fg-dim); }
3471
+ .oc.has-privacy .foot { display: block; }
3472
+ .foot .priv { color: var(--oc-fg-muted); text-decoration: underline; text-underline-offset: 2px; cursor: default; }
3473
+ .foot .tip { position: absolute; left: 0; right: 0; bottom: 16px; padding-bottom: 8px; z-index: 7; display: flex; justify-content: flex-end; pointer-events: none; opacity: 0; transition: opacity .18s var(--oc-ease); }
3474
+ .oc.max .foot .tip { right: 188px; }
3475
+ .foot:hover .tip { opacity: 1; }
3476
+ .foot .tip-card { max-width: 100%; width: 262px; padding: 13px 15px; border-radius: 14px; border: 1px solid var(--oc-border); background: var(--oc-bg); box-shadow: 0 8px 22px -12px rgba(0,0,0,0.32); text-align: left; font-size: 11.5px; line-height: 1.55; color: var(--oc-fg-muted); text-wrap: pretty; transform: translateY(6px); transition: transform .24s var(--oc-bounce); }
3477
+ .foot:hover .tip-card { transform: none; }
3478
+ .foot .tip-card a { color: var(--oc-fg); text-decoration: underline; text-underline-offset: 2px; }
3479
+
3480
+ /* \u2500\u2500 Emoji picker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
3481
+ .emoji-scrim { position: absolute; inset: 0; z-index: 3; display: none; }
3482
+ .oc.emoji .emoji-scrim { display: block; }
3483
+ .emoji-panel { position: absolute; left: 10px; right: 10px; bottom: 96px; z-index: 4; max-height: min(340px, 58%); display: flex; flex-direction: column; border-radius: 18px; border: 1px solid var(--oc-border); background: var(--oc-bg); box-shadow: 0 18px 46px -18px rgba(0,0,0,0.6); overflow: hidden; opacity: 0; transform: translateY(10px) scale(0.96); transform-origin: bottom center; pointer-events: none; visibility: hidden; transition: opacity .18s var(--oc-ease), transform .26s var(--oc-bounce), visibility .26s; }
3484
+ .oc.emoji .emoji-panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }
3485
+ .emoji-search { flex: none; display: flex; align-items: center; gap: 11px; padding: 13px 16px; border-bottom: 1px solid var(--oc-border); color: var(--oc-fg-dim); }
3486
+ .emoji-search input { flex: 1 1 auto; min-width: 0; border: none; background: transparent; color: var(--oc-fg); font-size: 14.5px; outline: none; font-family: inherit; }
3487
+ .emoji-search input::placeholder { color: var(--oc-fg-dim); }
3488
+ .emoji-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; padding: 12px 14px 16px; }
3489
+ .emoji-grp { display: flex; flex-direction: column; gap: 6px; }
3490
+ .emoji-grp + .emoji-grp { padding-top: 8px; }
3491
+ .emoji-grp-name { font-family: var(--oc-mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase; color: var(--oc-fg-dim); }
3492
+ .emoji-grid { display: grid; grid-template-columns: repeat(7, minmax(0,1fr)); gap: 2px; }
3493
+ .emoji-grid button { display: flex; align-items: center; justify-content: center; height: 34px; border-radius: 8px; border: none; background: transparent; font-size: 20px; line-height: 1; cursor: pointer; transition: background .14s var(--oc-ease); }
3494
+ .emoji-grid button:hover { background: var(--oc-tint-3); }
3495
+ .emoji-empty { display: none; flex-direction: column; align-items: center; gap: 5px; padding: 26px 10px; text-align: center; }
3496
+ .emoji-empty .h { font-size: 14px; color: var(--oc-fg); } .emoji-empty .s { font-size: 12.5px; color: var(--oc-fg-dim); }
3497
+
3498
+ @media (max-width: 480px) {
3499
+ :host { right: 0; bottom: 0; }
3500
+ .oc { padding: 0 16px 16px; }
3501
+ .panel { position: fixed; inset: 0; width: 100vw; height: 100dvh; border-radius: 0; }
3502
+ .oc.max .panel { width: 100vw; height: 100dvh; }
3503
+ }
3504
+ @media (prefers-reduced-motion: reduce) {
3505
+ .launcher, .panel, .teaser, .turn, .jump, .emoji-panel { transition: none; animation: none; }
3506
+ .ring { animation: none; } .body { scroll-behavior: auto; }
3507
+ }
3508
+
3509
+ @keyframes w-in { from { opacity: 0; transform: translateY(10px) scale(0.97); } to { opacity: 1; transform: none; } }
3510
+ @keyframes w-dot { 0%,60%,100% { transform: translateY(0); opacity: .45; } 30% { transform: translateY(-4px); opacity: 1; } }
3511
+ @keyframes w-ring { 0% { transform: scale(1); opacity: .5; } 70%,100% { transform: scale(1.7); opacity: 0; } }
3512
+ `;
3513
+
3514
+ // src/icons.ts
3515
+ var logoMark = (rectFill) => `<svg viewBox="0 0 1032 1024" fill="none" style="display:block;width:100%;height:100%"><rect x="4" width="1024" height="1024" rx="150" fill="${rectFill}"></rect><path d="M430.924 831.644C270.203 859.983 138.14 760.606 111.329 608.551C84.5174 456.497 174.627 317.945 335.348 289.605C496.068 261.266 628.131 360.643 654.943 512.698C681.754 664.752 591.644 803.304 430.924 831.644ZM406.613 693.77C488.549 679.323 518.727 615.513 505.252 539.092C491.777 462.671 441.594 413.031 359.658 427.478C277.722 441.926 247.544 505.736 261.02 582.157C274.495 658.578 324.677 708.218 406.613 693.77ZM870.337 558.389L744.281 580.616C727.055 482.923 674.565 369.515 652.06 241.884L841.143 208.543C863.509 335.387 853.111 460.696 870.337 558.389ZM910.583 740.568L768.771 765.573L745.016 630.852L886.828 605.846L910.583 740.568Z" fill="#fff"></path></svg>`;
3516
+ var stroke = (w, path, size = 24) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="${w}" stroke-linecap="round" stroke-linejoin="round" style="display:block;flex:none">${path}</svg>`;
3517
+ var ICON = {
3518
+ close: (size = 19) => stroke(2.4, '<path d="M18 6 6 18M6 6l12 12"/>', size),
3519
+ minus: stroke(2, '<path d="M6 12h12"/>', 15),
3520
+ expand: stroke(2, '<path d="M15 4h5v5M20 4l-6.5 6.5M9 20H4v-5M4 20l6.5-6.5"/>', 15),
3521
+ shrink: stroke(2, '<path d="M20 9h-5V4M15 9l5.5-5.5M4 15h5v5M9 15l-5.5 5.5"/>', 15),
3522
+ chevronDown: stroke(2.1, '<path d="m6 9 6 6 6-6"/>', 16),
3523
+ send: stroke(2.2, '<path d="M12 19V5M6 11l6-6 6 6"/>', 16),
3524
+ paperclip: stroke(1.7, '<path d="M21 11.5 12.5 20a5.5 5.5 0 0 1-7.8-7.8l8.5-8.5a3.7 3.7 0 0 1 5.2 5.2l-8.5 8.5a1.8 1.8 0 0 1-2.6-2.6l7.9-7.8"/>', 17),
3525
+ emoji: stroke(1.7, '<circle cx="12" cy="12" r="9"/><path d="M8.5 14.5a4.5 4.5 0 0 0 7 0M9 9.5h.01M15 9.5h.01"/>', 17),
3526
+ mic: stroke(1.7, '<rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3"/>', 17),
3527
+ search: stroke(1.9, '<circle cx="11" cy="11" r="7.5"/><path d="m21 21-4.3-4.3"/>', 17),
3528
+ clear: stroke(2.2, '<path d="M18 6 6 18M6 6l12 12"/>', 15),
3529
+ // Two-page "source" glyph for citation chips.
3530
+ book: `<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" style="display:block;flex:none;color:var(--oc-accent-text)"><path d="M3 5.5A2.5 2.5 0 0 1 5.5 3H11v18H5.5A2.5 2.5 0 0 1 3 18.5Z"/><path d="M21 5.5A2.5 2.5 0 0 0 18.5 3H13v18h5.5a2.5 2.5 0 0 0 2.5-2.5Z"/></svg>`,
3531
+ teaserDismiss: stroke(2.4, '<path d="M18 6 6 18M6 6l12 12"/>', 12)
3532
+ };
3533
+
3534
+ // src/emoji.ts
3535
+ var CATS = [
3536
+ { name: "Frequently used", items: [
3537
+ ["\u{1F44D}", "thumbs up"],
3538
+ ["\u{1F64F}", "thanks"],
3539
+ ["\u{1F44B}", "wave"],
3540
+ ["\u2705", "done"],
3541
+ ["\u{1F4DE}", "call"],
3542
+ ["\u{1F60A}", "smile"],
3543
+ ["\u2764\uFE0F", "heart"]
3544
+ ] },
3545
+ { name: "Smileys and emotion", items: [
3546
+ ["\u{1F600}", "grinning"],
3547
+ ["\u{1F603}", "smiley"],
3548
+ ["\u{1F604}", "grin"],
3549
+ ["\u{1F601}", "beaming"],
3550
+ ["\u{1F606}", "squinting"],
3551
+ ["\u{1F605}", "relief"],
3552
+ ["\u{1F923}", "rolling"],
3553
+ ["\u{1F602}", "tears of joy"],
3554
+ ["\u{1F642}", "slightly smiling"],
3555
+ ["\u{1F643}", "upside down"],
3556
+ ["\u{1F609}", "wink"],
3557
+ ["\u{1F607}", "halo"],
3558
+ ["\u{1F970}", "smiling hearts"],
3559
+ ["\u{1F60D}", "heart eyes"],
3560
+ ["\u{1F618}", "kiss"],
3561
+ ["\u{1F60B}", "yum"],
3562
+ ["\u{1F914}", "thinking"],
3563
+ ["\u{1F928}", "raised brow"],
3564
+ ["\u{1F610}", "neutral"],
3565
+ ["\u{1F644}", "eye roll"],
3566
+ ["\u{1F62C}", "grimace"],
3567
+ ["\u{1F625}", "sad"],
3568
+ ["\u{1F622}", "crying"],
3569
+ ["\u{1F62D}", "sobbing"],
3570
+ ["\u{1F620}", "angry"],
3571
+ ["\u{1F633}", "flushed"],
3572
+ ["\u{1F929}", "star struck"],
3573
+ ["\u{1F634}", "sleeping"]
3574
+ ] },
3575
+ { name: "Gestures", items: [
3576
+ ["\u{1F44E}", "thumbs down"],
3577
+ ["\u{1F44F}", "clap"],
3578
+ ["\u{1F64C}", "raised hands"],
3579
+ ["\u{1F91D}", "handshake"],
3580
+ ["\u{1F44C}", "ok hand"],
3581
+ ["\u270C\uFE0F", "victory"],
3582
+ ["\u{1F4AA}", "strong"],
3583
+ ["\u{1F440}", "eyes"],
3584
+ ["\u{1F9E0}", "brain"],
3585
+ ["\u{1F91F}", "love you"],
3586
+ ["\u261D\uFE0F", "point up"],
3587
+ ["\u{1F447}", "point down"],
3588
+ ["\u{1F91A}", "raised back"],
3589
+ ["\u{1F91E}", "fingers crossed"]
3590
+ ] },
3591
+ { name: "Work and travel", items: [
3592
+ ["\u{1F4C5}", "calendar"],
3593
+ ["\u{1F4C4}", "document"],
3594
+ ["\u{1F4B0}", "money"],
3595
+ ["\u{1F4CA}", "chart"],
3596
+ ["\u{1F4E6}", "package"],
3597
+ ["\u{1F3E5}", "hospital"],
3598
+ ["\u{1F3E6}", "bank"],
3599
+ ["\u{1F69A}", "truck"],
3600
+ ["\u2708\uFE0F", "plane"],
3601
+ ["\u{1F4F1}", "phone"],
3602
+ ["\u{1F4BB}", "laptop"],
3603
+ ["\u{1F50D}", "search"],
3604
+ ["\u{1F4CC}", "pin"],
3605
+ ["\u{1F514}", "bell"]
3606
+ ] },
3607
+ { name: "Symbols", items: [
3608
+ ["\u{1F525}", "fire"],
3609
+ ["\u2728", "sparkles"],
3610
+ ["\u{1F389}", "celebrate"],
3611
+ ["\u{1F4AF}", "hundred"],
3612
+ ["\u26A0\uFE0F", "warning"],
3613
+ ["\u274C", "cross"],
3614
+ ["\u2B50", "star"],
3615
+ ["\u{1F680}", "launch"],
3616
+ ["\u{1F49A}", "green heart"],
3617
+ ["\u{1F499}", "blue heart"],
3618
+ ["\u{1F552}", "clock"],
3619
+ ["\u{1F4A1}", "idea"],
3620
+ ["\u{1F512}", "lock"],
3621
+ ["\u{1F3AF}", "target"]
3622
+ ] }
3623
+ ];
3624
+ var toGroup = (name, items) => ({
3625
+ name,
3626
+ items: items.map(([ch, kw]) => ({ ch, name: kw }))
3627
+ });
3628
+ function emojiGroups(query) {
3629
+ const q2 = query.trim().toLowerCase();
3630
+ if (!q2) return CATS.map((c) => toGroup(c.name, c.items));
3631
+ const hits = [];
3632
+ for (const c of CATS) for (const e of c.items) {
3633
+ if (e[1].indexOf(q2) >= 0 && !hits.some((h) => h[0] === e[0])) hits.push(e);
3634
+ }
3635
+ if (!hits.length) return [];
3636
+ return [toGroup(`${hits.length} result${hits.length === 1 ? "" : "s"}`, hits)];
346
3637
  }
347
3638
 
348
3639
  // src/element.ts
349
- var HANDOFF_STATUS_TEXT = {
3640
+ var DEFAULT_STATUS = "Replies in a few seconds";
3641
+ var ATTACHMENT_ACCEPT = "image/*,application/pdf,text/plain,text/csv";
3642
+ var AWAY_THRESHOLD = 60;
3643
+ var HANDOFF_STATUS = {
350
3644
  ai: null,
351
3645
  awaiting_human: "Connecting you to a person\u2026",
352
3646
  human: "You're chatting with a person"
353
3647
  };
354
- var ATTACHMENT_ACCEPT = "image/*,application/pdf,text/plain,text/csv";
355
- var AGENT_TYPING_TEXT = "The agent is typing\u2026";
356
3648
  var OyehelloChatElement = class extends HTMLElement {
357
- static observedAttributes = ["api-key", "agent-id", "base-url", "title"];
3649
+ static observedAttributes = ["api-key", "agent-id", "base-url", "title", "theme"];
3650
+ // ── live client state ──
358
3651
  client = null;
359
3652
  off = null;
360
3653
  messages = [];
361
3654
  state = "idle";
362
3655
  agentName = null;
363
3656
  handoffState = "ai";
364
- // Transient "agent is typing…" affordance (Phase 7 followups) - never a message, only rendered
365
- // while a handoff is active (human/awaiting_human).
366
3657
  agentTyping = false;
367
- // Last connection/runtime error message (client emits an 'error' event on a failed start() or
368
- // send). Surfaced as a visible banner so a disabled composer always shows WHY, instead of sitting
369
- // dead. Cleared when the client reaches a healthy state again.
370
3658
  lastError = null;
371
- // registerTools() may be called before connectedCallback creates the client (e.g. right after
372
- // document.createElement, before the element is attached). Buffer until the client exists.
373
3659
  pendingTools = {};
374
- // Files picked in the file input, staged until the form submits alongside the text.
375
3660
  pendingFiles = [];
376
- // Best-effort local thumbnail cache for images THIS widget instance just sent, keyed by filename -
377
- // an instant blob src, no round-trip needed.
378
3661
  imagePreviewCache = /* @__PURE__ */ new Map();
379
- // Read-back URLs resolved lazily (via client.getAttachmentUrl) for images with no local blob (a
380
- // reconnect, or an `attachment` SSE echo), keyed by storageRef. Cached across re-renders so the
381
- // same image isn't re-fetched on every render() call.
382
3662
  resolvedUrlCache = /* @__PURE__ */ new Map();
3663
+ mdCache = /* @__PURE__ */ new Map();
3664
+ receivedAt = /* @__PURE__ */ new Map();
3665
+ // ── widget UI state ──
3666
+ uiOpen = false;
3667
+ started = false;
3668
+ uiMax = false;
3669
+ emojiOpen = false;
3670
+ emojiQuery = "";
3671
+ away = false;
3672
+ // reader scrolled up
3673
+ unseen = 0;
3674
+ focused = false;
3675
+ teaserActive = false;
3676
+ renderedCount = 0;
3677
+ renderedBotFinal = 0;
3678
+ timers = [];
3679
+ // ── shadow refs ──
3680
+ oc;
3681
+ bodyEl;
3682
+ textareaEl;
3683
+ fileEl;
3684
+ titleEl;
3685
+ statusEl;
3686
+ errEl;
3687
+ emojiListEl;
3688
+ emojiSearchEl;
383
3689
  connectedCallback() {
384
3690
  if (!this.shadowRoot) this.attachShadow({ mode: "open" });
385
3691
  const apiKey = this.getAttribute("api-key");
@@ -394,23 +3700,44 @@ var OyehelloChat = (function (exports) {
394
3700
  this.client.registerTools(this.pendingTools);
395
3701
  this.pendingTools = {};
396
3702
  }
397
- this.off = this.client.on((e) => {
398
- if (e.type === "messages") this.messages = e.messages;
399
- else if (e.type === "state") {
400
- this.state = e.state;
401
- if (e.state === "ready" || e.state === "opening") this.lastError = null;
402
- } else if (e.type === "agent") this.agentName = e.agent.name;
403
- else if (e.type === "handoff") this.handoffState = e.state;
404
- else if (e.type === "agentTyping") this.agentTyping = e.active;
405
- else if (e.type === "error") this.lastError = e.error.message;
406
- this.render();
407
- });
408
- this.render();
409
- void this.client.start();
3703
+ this.off = this.client.on((e) => this.onClientEvent(e));
3704
+ this.renderShell();
3705
+ this.renderMessages();
3706
+ this.updateHeader();
3707
+ this.updateStatus();
3708
+ this.updateClasses();
3709
+ let wasOpen = false;
3710
+ try {
3711
+ wasOpen = sessionStorage.getItem(this.key("open")) === "1";
3712
+ } catch {
3713
+ }
3714
+ if (wasOpen) {
3715
+ this.openPanel();
3716
+ return;
3717
+ }
3718
+ this.updateClasses(true);
3719
+ this.timers.push(setTimeout(() => {
3720
+ this.oc?.classList.remove("ring");
3721
+ }, 6e3));
3722
+ const teaserText = this.getAttribute("teaser");
3723
+ let dismissed = false;
3724
+ try {
3725
+ dismissed = sessionStorage.getItem(this.key("teaser")) === "0";
3726
+ } catch {
3727
+ }
3728
+ if (teaserText && !dismissed) {
3729
+ this.timers.push(setTimeout(() => {
3730
+ if (!this.uiOpen) {
3731
+ this.teaserActive = true;
3732
+ this.updateClasses();
3733
+ }
3734
+ }, 1400));
3735
+ }
410
3736
  }
411
3737
  disconnectedCallback() {
412
3738
  this.off?.();
413
3739
  void this.client?.end();
3740
+ for (const t of this.timers) clearTimeout(t);
414
3741
  for (const url of this.imagePreviewCache.values()) {
415
3742
  if (typeof URL.revokeObjectURL === "function") URL.revokeObjectURL(url);
416
3743
  }
@@ -420,37 +3747,394 @@ var OyehelloChat = (function (exports) {
420
3747
  if (this.client) this.client.registerTools(handlers);
421
3748
  else Object.assign(this.pendingTools, handlers);
422
3749
  }
423
- send(text, files) {
424
- if (!text.trim()) return;
425
- for (const f of files) {
426
- if (f.type.startsWith("image/") && typeof URL.createObjectURL === "function" && !this.imagePreviewCache.has(f.name)) {
427
- this.imagePreviewCache.set(f.name, URL.createObjectURL(f));
3750
+ key(k2) {
3751
+ return `oyehello-chat:${k2}:${this.getAttribute("agent-id") ?? ""}`;
3752
+ }
3753
+ get suggestions() {
3754
+ return (this.getAttribute("suggestions") ?? "").split(",").map((s) => s.trim()).filter(Boolean);
3755
+ }
3756
+ // ── Shell (built once) ─────────────────────────────────────────────────────────────────────────
3757
+ renderShell() {
3758
+ const root = this.shadowRoot;
3759
+ const hasTeaser = !!this.getAttribute("teaser");
3760
+ const hasPrivacy = !!this.getAttribute("privacy-url");
3761
+ const teaserText = this.getAttribute("teaser") ?? "";
3762
+ root.innerHTML = `
3763
+ <style>${STYLES}</style>
3764
+ <div class="oc${hasTeaser ? " has-teaser" : ""}${hasPrivacy ? " has-privacy" : ""}">
3765
+ <div class="panel" role="dialog" aria-label="Chat">
3766
+ <div class="hd">
3767
+ <span class="hd-grid"></span>
3768
+ <span class="logo">${logoMark("currentColor")}</span>
3769
+ <span class="hd-txt"><span class="hd-title">Chat</span><span class="hd-status"><span class="dot"></span><span class="t"></span></span></span>
3770
+ <button type="button" class="hd-btn max" aria-label="Expand"><span class="i i-expand">${ICON.expand}</span><span class="i i-shrink">${ICON.shrink}</span></button>
3771
+ <button type="button" class="hd-btn min" aria-label="Minimise">${ICON.minus}</button>
3772
+ </div>
3773
+ <div class="err" hidden></div>
3774
+ <div class="body"></div>
3775
+ <span class="emoji-scrim"></span>
3776
+ <div class="emoji-panel">
3777
+ <div class="emoji-search">${ICON.search}<input type="text" placeholder="Search emoji\u2026" aria-label="Search emoji" /></div>
3778
+ <div class="emoji-list"></div>
3779
+ </div>
3780
+ <div class="jump-wrap"><button type="button" class="jump" aria-label="Jump to latest">${ICON.chevronDown}</button></div>
3781
+ <div class="composer">
3782
+ <form class="field">
3783
+ <textarea class="input" rows="1" aria-label="message" placeholder="Ask a question\u2026"></textarea>
3784
+ <div class="acts">
3785
+ <button type="button" class="act attach" aria-label="Attach a file">${ICON.paperclip}</button>
3786
+ <input type="file" accept="${ATTACHMENT_ACCEPT}" multiple hidden />
3787
+ <button type="button" class="act emoji-btn" aria-label="Insert emoji">${ICON.emoji}</button>
3788
+ <button type="button" class="act mic" aria-label="Send a voice note">${ICON.mic}</button>
3789
+ <button type="submit" class="send" aria-label="Send">${ICON.send}</button>
3790
+ </div>
3791
+ </form>
3792
+ <div class="foot">
3793
+ <span>By chatting with us, you agree to our </span><span class="priv">Privacy Policy</span>
3794
+ <span class="tip"><span class="tip-card">By chatting with us, you agree to the monitoring and recording of this chat to deliver our services and processing of your personal data in accordance with our Privacy Policy. <a href="${this.escapeAttr(this.getAttribute("privacy-url") ?? "#")}" target="_blank" rel="noopener noreferrer">See our Privacy Policy</a>.</span></span>
3795
+ </div>
3796
+ </div>
3797
+ </div>
3798
+
3799
+ <div class="teaser">
3800
+ <button type="button" class="teaser-btn"><span class="logo">${logoMark("currentColor")}</span><span>${escapeHtml(teaserText)}</span></button>
3801
+ <button type="button" class="teaser-x" aria-label="Dismiss">${ICON.teaserDismiss}</button>
3802
+ </div>
3803
+
3804
+ <button type="button" class="launcher" aria-label="Open chat">
3805
+ <span class="ring"></span>
3806
+ <span class="ic-chat">${logoMark("var(--oc-ac)")}</span>
3807
+ <span class="ic-close">${ICON.close(19)}</span>
3808
+ <span class="badge"></span>
3809
+ </button>
3810
+ </div>`;
3811
+ this.oc = root.querySelector(".oc");
3812
+ this.bodyEl = root.querySelector(".body");
3813
+ this.textareaEl = root.querySelector("textarea.input");
3814
+ this.fileEl = root.querySelector('input[type="file"]');
3815
+ this.titleEl = root.querySelector(".hd-title");
3816
+ this.statusEl = root.querySelector(".hd-status .t");
3817
+ this.errEl = root.querySelector(".err");
3818
+ this.emojiListEl = root.querySelector(".emoji-list");
3819
+ this.emojiSearchEl = root.querySelector(".emoji-search input");
3820
+ root.querySelector(".launcher").addEventListener("click", () => this.toggle());
3821
+ root.querySelector(".hd-btn.min").addEventListener("click", () => this.closePanel());
3822
+ root.querySelector(".hd-btn.max").addEventListener("click", () => {
3823
+ this.uiMax = !this.uiMax;
3824
+ this.updateClasses();
3825
+ });
3826
+ root.querySelector(".teaser-btn").addEventListener("click", () => this.openPanel());
3827
+ root.querySelector(".teaser-x").addEventListener("click", () => this.dismissTeaser());
3828
+ root.querySelector(".jump").addEventListener("click", () => this.scrollToBottom());
3829
+ root.querySelector(".attach").addEventListener("click", () => this.fileEl.click());
3830
+ this.fileEl.addEventListener("change", () => {
3831
+ this.pendingFiles = this.fileEl.files ? Array.from(this.fileEl.files) : [];
3832
+ });
3833
+ root.querySelector(".emoji-btn").addEventListener("click", () => this.toggleEmoji());
3834
+ root.querySelector(".emoji-scrim").addEventListener("click", () => this.closeEmoji());
3835
+ this.emojiSearchEl.addEventListener("input", () => {
3836
+ this.emojiQuery = this.emojiSearchEl.value;
3837
+ this.renderEmoji();
3838
+ });
3839
+ this.bodyEl.addEventListener("scroll", () => this.onScroll());
3840
+ root.querySelector("form.field").addEventListener("submit", (e) => {
3841
+ e.preventDefault();
3842
+ this.doSend();
3843
+ });
3844
+ this.textareaEl.addEventListener("input", () => {
3845
+ this.autoGrow();
3846
+ this.updateClasses();
3847
+ });
3848
+ this.textareaEl.addEventListener("focus", () => {
3849
+ this.focused = true;
3850
+ this.updateClasses();
3851
+ });
3852
+ this.textareaEl.addEventListener("blur", () => {
3853
+ this.focused = false;
3854
+ this.updateClasses();
3855
+ });
3856
+ this.textareaEl.addEventListener("keydown", (e) => {
3857
+ if (e.key === "Enter" && !e.shiftKey && !e.isComposing) {
3858
+ e.preventDefault();
3859
+ this.doSend();
428
3860
  }
429
- }
430
- void this.client?.sendMessage(text, files.length > 0 ? files : void 0);
3861
+ if (e.key === "Escape") {
3862
+ if (this.emojiOpen) this.closeEmoji();
3863
+ else this.closePanel();
3864
+ }
3865
+ });
431
3866
  }
432
3867
  renderError(msg) {
433
3868
  if (!this.shadowRoot) this.attachShadow({ mode: "open" });
434
- this.shadowRoot.innerHTML = `<div style="color:#b91c1c;font:13px system-ui;padding:12px">${escapeHtml(msg)}</div>`;
3869
+ console.error(msg);
3870
+ this.shadowRoot.innerHTML = `<div style="position:fixed;right:16px;bottom:16px;color:#b91c1c;font:12px system-ui;background:#fef2f2;border:1px solid #fecaca;padding:8px 12px;border-radius:8px">${escapeHtml(msg)}</div>`;
3871
+ }
3872
+ // ── State-class sync ──────────────────────────────────────────────────────────────────────────
3873
+ updateClasses(initialRing = false) {
3874
+ if (!this.oc) return;
3875
+ const c = this.oc.classList;
3876
+ c.toggle("open", this.uiOpen);
3877
+ c.toggle("max", this.uiMax);
3878
+ c.toggle("emoji", this.emojiOpen);
3879
+ c.toggle("teaser", this.teaserActive);
3880
+ c.toggle("away", this.away);
3881
+ c.toggle("focus", this.focused);
3882
+ c.toggle("ready", (this.textareaEl?.value.trim().length ?? 0) > 0);
3883
+ c.toggle("unread", this.unseen > 0);
3884
+ if (initialRing) c.add("ring");
3885
+ const badge = this.oc.querySelector(".badge");
3886
+ if (badge) badge.textContent = this.unseen > 9 ? "9+" : String(this.unseen);
3887
+ const launcher = this.oc.querySelector(".launcher");
3888
+ if (launcher) launcher.setAttribute("aria-label", this.uiOpen ? "Close chat" : "Open chat");
3889
+ }
3890
+ // ── Open / close ───────────────────────────────────────────────────────────────────────────────
3891
+ toggle() {
3892
+ this.uiOpen ? this.closePanel() : this.openPanel();
3893
+ }
3894
+ openPanel() {
3895
+ this.uiOpen = true;
3896
+ this.teaserActive = false;
3897
+ this.unseen = 0;
3898
+ try {
3899
+ sessionStorage.setItem(this.key("open"), "1");
3900
+ } catch {
3901
+ }
3902
+ if (!this.started && this.client) {
3903
+ this.started = true;
3904
+ void this.client.start();
3905
+ }
3906
+ this.updateClasses();
3907
+ this.renderMessages();
3908
+ this.scrollToBottom();
3909
+ if (!this.textareaEl.disabled) setTimeout(() => this.textareaEl.focus(), 60);
3910
+ }
3911
+ closePanel() {
3912
+ this.uiOpen = false;
3913
+ this.uiMax = false;
3914
+ this.emojiOpen = false;
3915
+ try {
3916
+ sessionStorage.setItem(this.key("open"), "0");
3917
+ } catch {
3918
+ }
3919
+ this.updateClasses();
3920
+ }
3921
+ dismissTeaser() {
3922
+ this.teaserActive = false;
3923
+ try {
3924
+ sessionStorage.setItem(this.key("teaser"), "0");
3925
+ } catch {
3926
+ }
3927
+ this.updateClasses();
3928
+ }
3929
+ // ── Client events ─────────────────────────────────────────────────────────────────────────────
3930
+ onClientEvent(e) {
3931
+ if (e.type === "messages") this.messages = e.messages;
3932
+ else if (e.type === "state") {
3933
+ this.state = e.state;
3934
+ if (e.state === "ready" || e.state === "opening") this.lastError = null;
3935
+ } else if (e.type === "agent") {
3936
+ this.agentName = e.agent.name;
3937
+ this.updateHeader();
3938
+ } else if (e.type === "handoff") this.handoffState = e.state;
3939
+ else if (e.type === "agentTyping") this.agentTyping = e.active;
3940
+ else if (e.type === "error") this.lastError = e.error.message;
3941
+ this.updateStatus();
3942
+ this.renderMessages();
3943
+ }
3944
+ updateHeader() {
3945
+ if (this.titleEl) this.titleEl.textContent = this.getAttribute("title") ?? this.agentName ?? "Chat";
3946
+ }
3947
+ updateStatus() {
3948
+ if (!this.textareaEl) return;
3949
+ const disabled = this.state !== "ready";
3950
+ this.textareaEl.disabled = disabled;
3951
+ const handoff = HANDOFF_STATUS[this.handoffState];
3952
+ const text2 = this.state === "opening" ? "Connecting\u2026" : handoff ?? (this.getAttribute("status") ?? DEFAULT_STATUS);
3953
+ if (this.statusEl) this.statusEl.textContent = text2;
3954
+ if (this.state === "error" && this.lastError) {
3955
+ this.errEl.hidden = false;
3956
+ this.errEl.innerHTML = `<span>Couldn't start chat: ${escapeHtml(this.lastError)}</span><button class="retry" type="button">Retry</button>`;
3957
+ this.errEl.querySelector(".retry").addEventListener("click", () => {
3958
+ void this.client?.start();
3959
+ });
3960
+ } else {
3961
+ this.errEl.hidden = true;
3962
+ this.errEl.innerHTML = "";
3963
+ }
3964
+ }
3965
+ // ── Message list + scroll ─────────────────────────────────────────────────────────────────────
3966
+ renderMessages() {
3967
+ if (!this.bodyEl) return;
3968
+ const body = this.bodyEl;
3969
+ const prevTop = body.scrollTop;
3970
+ const added = this.messages.length - this.renderedCount;
3971
+ const botFinal = this.messages.filter((m2) => m2.role === "assistant" && !m2.streaming).length;
3972
+ const newBotFinal = botFinal > this.renderedBotFinal;
3973
+ const now = Date.now();
3974
+ for (const m2 of this.messages) if (!this.receivedAt.has(m2.id)) this.receivedAt.set(m2.id, now);
3975
+ const lastBot = (() => {
3976
+ for (let i = this.messages.length - 1; i >= 0; i--) if (this.messages[i]?.role === "assistant") return i;
3977
+ return -1;
3978
+ })();
3979
+ let html2 = this.messages.map((m2, i) => this.turnHtml(m2, i === lastBot && !this.agentTyping)).join("");
3980
+ if (this.agentTyping) html2 += '<span class="typing"><span></span><span></span><span></span></span>';
3981
+ const sugg = this.suggestions;
3982
+ if (sugg.length > 0 && !this.agentTyping && this.state === "ready") {
3983
+ html2 += `<span class="chips">${sugg.map((s, i) => `<button type="button" class="chip" data-chip="${i}">${escapeHtml(s)}</button>`).join("")}</span>`;
3984
+ }
3985
+ body.innerHTML = html2;
3986
+ this.hydrateAttachmentImages();
3987
+ this.bindChips();
3988
+ this.renderedCount = this.messages.length;
3989
+ this.renderedBotFinal = botFinal;
3990
+ if (!this.uiOpen) {
3991
+ if (added > 0) this.unseen += added;
3992
+ this.updateClasses();
3993
+ return;
3994
+ }
3995
+ if (newBotFinal && !this.away) this.parkLastQuestion();
3996
+ else if (!this.away) this.scrollToBottom();
3997
+ else {
3998
+ body.scrollTop = prevTop;
3999
+ if (added > 0) this.unseen += added;
4000
+ }
4001
+ this.updateClasses();
4002
+ }
4003
+ // After a reply lands, float the question that prompted it to the top so the answer reads from its
4004
+ // first line rather than its last (the design's behaviour).
4005
+ parkLastQuestion() {
4006
+ const users = this.bodyEl.querySelectorAll(".turn.user");
4007
+ const last = users[users.length - 1];
4008
+ if (!last) {
4009
+ this.scrollToBottom();
4010
+ return;
4011
+ }
4012
+ const top = Math.max(0, Math.min(last.offsetTop - 22, this.bodyEl.scrollHeight - this.bodyEl.clientHeight));
4013
+ this.bodyEl.scrollTo({ top, behavior: "smooth" });
4014
+ }
4015
+ onScroll() {
4016
+ const b2 = this.bodyEl;
4017
+ const away = b2.scrollHeight - b2.scrollTop - b2.clientHeight > AWAY_THRESHOLD;
4018
+ if (away !== this.away) {
4019
+ this.away = away;
4020
+ if (!away) this.unseen = 0;
4021
+ this.updateClasses();
4022
+ }
4023
+ }
4024
+ scrollToBottom() {
4025
+ if (!this.bodyEl) return;
4026
+ this.bodyEl.scrollTop = this.bodyEl.scrollHeight;
4027
+ this.away = false;
4028
+ this.unseen = 0;
4029
+ this.updateClasses();
4030
+ }
4031
+ // ── Composer ──────────────────────────────────────────────────────────────────────────────────
4032
+ autoGrow() {
4033
+ const ta = this.textareaEl;
4034
+ ta.style.height = "auto";
4035
+ ta.style.height = `${Math.min(ta.scrollHeight, 108)}px`;
4036
+ }
4037
+ doSend() {
4038
+ const text2 = this.textareaEl.value;
4039
+ if (!text2.trim()) return;
4040
+ const files = this.pendingFiles;
4041
+ this.pendingFiles = [];
4042
+ this.fileEl.value = "";
4043
+ for (const f2 of files) {
4044
+ if (f2.type.startsWith("image/") && typeof URL.createObjectURL === "function" && !this.imagePreviewCache.has(f2.name)) {
4045
+ this.imagePreviewCache.set(f2.name, URL.createObjectURL(f2));
4046
+ }
4047
+ }
4048
+ this.away = false;
4049
+ this.emojiOpen = false;
4050
+ void this.client?.sendMessage(text2, files.length > 0 ? files : void 0);
4051
+ this.textareaEl.value = "";
4052
+ this.textareaEl.style.height = "auto";
4053
+ this.updateClasses();
4054
+ }
4055
+ sendChip(text2) {
4056
+ this.away = false;
4057
+ this.emojiOpen = false;
4058
+ void this.client?.sendMessage(text2);
4059
+ this.updateClasses();
4060
+ }
4061
+ bindChips() {
4062
+ const sugg = this.suggestions;
4063
+ this.bodyEl.querySelectorAll(".chip[data-chip]").forEach((btn) => {
4064
+ const i = Number(btn.getAttribute("data-chip"));
4065
+ const text2 = sugg[i];
4066
+ if (text2) btn.addEventListener("click", () => this.sendChip(text2));
4067
+ });
4068
+ }
4069
+ // ── Emoji ─────────────────────────────────────────────────────────────────────────────────────
4070
+ toggleEmoji() {
4071
+ this.emojiOpen = !this.emojiOpen;
4072
+ this.emojiQuery = "";
4073
+ this.emojiSearchEl.value = "";
4074
+ this.renderEmoji();
4075
+ this.updateClasses();
4076
+ if (this.emojiOpen) setTimeout(() => this.emojiSearchEl.focus(), 60);
4077
+ }
4078
+ closeEmoji() {
4079
+ this.emojiOpen = false;
4080
+ this.emojiQuery = "";
4081
+ this.updateClasses();
4082
+ }
4083
+ renderEmoji() {
4084
+ const groups = emojiGroups(this.emojiQuery);
4085
+ let html2 = groups.map((g) => `
4086
+ <div class="emoji-grp"><span class="emoji-grp-name">${escapeHtml(g.name)}</span>
4087
+ <div class="emoji-grid">${g.items.map((e) => `<button type="button" title="${this.escapeAttr(e.name)}" aria-label="${this.escapeAttr(e.name)}" data-ch="${this.escapeAttr(e.ch)}">${e.ch}</button>`).join("")}</div>
4088
+ </div>`).join("");
4089
+ if (groups.length === 0) html2 = '<span class="emoji-empty" style="display:flex"><span class="h">No emoji match that</span><span class="s">Try a shorter word, like smile or call.</span></span>';
4090
+ this.emojiListEl.innerHTML = html2;
4091
+ this.emojiListEl.querySelectorAll("button[data-ch]").forEach((btn) => {
4092
+ btn.addEventListener("click", () => {
4093
+ this.textareaEl.value += btn.getAttribute("data-ch") ?? "";
4094
+ this.emojiOpen = false;
4095
+ this.autoGrow();
4096
+ this.updateClasses();
4097
+ this.textareaEl.focus();
4098
+ });
4099
+ });
4100
+ }
4101
+ // ── Bubble rendering ──────────────────────────────────────────────────────────────────────────
4102
+ turnHtml(m2, isLastBot) {
4103
+ const role = m2.role === "user" ? "user" : m2.role === "human" ? "human" : "bot";
4104
+ const atts = (m2.attachments ?? []).map((a) => this.renderAttachment(a)).join("");
4105
+ let content;
4106
+ if (m2.role === "assistant") {
4107
+ let rendered = m2.streaming ? void 0 : this.mdCache.get(m2.id);
4108
+ if (rendered === void 0) {
4109
+ rendered = renderMarkdown(m2.text || "");
4110
+ if (!m2.streaming) this.mdCache.set(m2.id, rendered);
4111
+ }
4112
+ content = `<span class="b">${atts}<span class="md">${rendered}</span></span>`;
4113
+ } else {
4114
+ const label = m2.role === "human" ? '<div class="human-label">Support</div>' : "";
4115
+ content = `<span class="b">${label}${atts}${escapeHtml(m2.text)}</span>`;
4116
+ }
4117
+ const src = m2.sources && m2.sources.length > 0 ? `<span class="src">${ICON.book}<span class="t">${escapeHtml("From " + (m2.sources[0]?.title ?? ""))}</span></span>` : "";
4118
+ const byline = role === "bot" && isLastBot ? `<span class="byline">${escapeHtml((this.agentName ?? "OyeHello") + " \xB7 AI agent \xB7 " + this.relTime(m2.id))}</span>` : "";
4119
+ return `<span class="turn ${role}">${content}${src}${byline}</span>`;
4120
+ }
4121
+ relTime(id) {
4122
+ const t = this.receivedAt.get(id);
4123
+ if (!t) return "just now";
4124
+ const mins = Math.floor((Date.now() - t) / 6e4);
4125
+ return mins <= 0 ? "just now" : `${mins} min ago`;
435
4126
  }
436
4127
  renderAttachment(a) {
437
4128
  if (a.contentType.startsWith("image/")) {
438
4129
  const cached = (a.name ? this.imagePreviewCache.get(a.name) : void 0) ?? this.resolvedUrlCache.get(a.storageRef);
439
4130
  const srcAttr = cached ? ` src="${cached}"` : "";
440
- return `<img class="att-thumb" data-oc-ref="${escapeHtml(a.storageRef)}"${srcAttr} alt="${escapeHtml(a.name ?? "image")}"/>`;
4131
+ return `<img class="att-thumb" data-oc-ref="${this.escapeAttr(a.storageRef)}"${srcAttr} alt="${this.escapeAttr(a.name ?? "image")}"/>`;
441
4132
  }
442
4133
  return `<div class="att-chip">\u{1F4CE} ${escapeHtml(a.name ?? a.contentType)}</div>`;
443
4134
  }
444
- renderSource(s) {
445
- return `<div class="src-chip" title="${escapeHtml(s.snippet)}">${escapeHtml(s.title)}</div>`;
446
- }
447
- // After render() attaches the markup, resolve a read-back URL (via the client) for every image
448
- // placeholder that has no src yet - a local blob or a previously-resolved URL already set one, so
449
- // those are left untouched (no redundant network call).
450
4135
  hydrateAttachmentImages() {
451
4136
  if (!this.client) return;
452
- const imgs = this.shadowRoot.querySelectorAll("img.att-thumb[data-oc-ref]");
453
- imgs.forEach((img) => {
4137
+ this.shadowRoot.querySelectorAll("img.att-thumb[data-oc-ref]").forEach((img) => {
454
4138
  if (img.hasAttribute("src")) return;
455
4139
  const ref = img.getAttribute("data-oc-ref");
456
4140
  if (!ref) return;
@@ -461,82 +4145,8 @@ var OyehelloChat = (function (exports) {
461
4145
  });
462
4146
  });
463
4147
  }
464
- render() {
465
- const title = this.getAttribute("title") ?? this.agentName ?? "Chat";
466
- const bubbles = this.messages.map((m) => {
467
- const atts = (m.attachments ?? []).map((a) => this.renderAttachment(a)).join("");
468
- const label = m.role === "human" ? '<div class="human-label">Support</div>' : "";
469
- const bubble = `<div class="b ${m.role}">${label}${atts}${m.text ? escapeHtml(m.text) : ""}${m.streaming ? "\u2026" : ""}</div>`;
470
- const sources = m.sources && m.sources.length > 0 ? `<div class="src-row">${m.sources.map((s) => this.renderSource(s)).join("")}</div>` : "";
471
- return bubble + sources;
472
- }).join("");
473
- const statusText = HANDOFF_STATUS_TEXT[this.handoffState];
474
- const status = statusText ? `<div class="status">${escapeHtml(statusText)}</div>` : "";
475
- const errBanner = this.state === "error" && this.lastError ? `<div class="err">Couldn't start chat: ${escapeHtml(this.lastError)}</div>` : "";
476
- const showTyping = this.agentTyping && (this.handoffState === "human" || this.handoffState === "awaiting_human");
477
- const typingIndicator = showTyping ? `<div class="b assistant typing">${escapeHtml(AGENT_TYPING_TEXT)}</div>` : "";
478
- const disabled = this.state !== "ready" ? "disabled" : "";
479
- const prevInput = this.shadowRoot.querySelector('input[aria-label="message"]');
480
- const prevValue = prevInput?.value ?? "";
481
- const prevSelectionStart = prevInput?.selectionStart ?? null;
482
- const prevSelectionEnd = prevInput?.selectionEnd ?? null;
483
- const hadFocus = !!prevInput && this.shadowRoot.activeElement === prevInput;
484
- this.shadowRoot.innerHTML = `
485
- <style>
486
- :host{display:block;height:100%;min-height:320px;font-family:system-ui,sans-serif;--oc-accent:#2563eb}
487
- .wrap{display:flex;flex-direction:column;height:100%;border:1px solid #e5e7eb;border-radius:12px;overflow:hidden}
488
- .hd{padding:10px 14px;border-bottom:1px solid #e5e7eb;font-weight:600}
489
- .body{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px}
490
- .b{max-width:80%;padding:8px 12px;border-radius:12px;white-space:pre-wrap;word-break:break-word}
491
- .b.user{align-self:flex-end;background:var(--oc-accent);color:#fff}
492
- .b.assistant{align-self:flex-start;background:#f3f4f6;color:#111}
493
- .b.human{align-self:flex-start;background:#dbeafe;color:#111}
494
- .b.typing{font-style:italic;color:#6b7280;opacity:.85}
495
- .human-label{font-size:11px;font-weight:600;opacity:.7;margin-bottom:2px}
496
- .status{padding:6px 14px;font-size:12px;color:#6b7280;background:#f9fafb;border-bottom:1px solid #e5e7eb}
497
- .err{padding:8px 14px;font-size:12px;color:#b91c1c;background:#fef2f2;border-bottom:1px solid #fecaca}
498
- .att-thumb{display:block;max-width:160px;max-height:160px;border-radius:8px;margin-bottom:6px}
499
- .att-chip{display:inline-block;font-size:12px;background:rgba(0,0,0,.08);border-radius:6px;padding:2px 8px;margin:0 0 6px}
500
- .b.user .att-chip{background:rgba(255,255,255,.25)}
501
- .src-row{align-self:flex-start;display:flex;flex-wrap:wrap;gap:6px;max-width:80%}
502
- .src-chip{display:inline-block;font-size:11px;background:rgba(0,0,0,.06);color:#374151;border-radius:6px;padding:2px 8px;cursor:default}
503
- form{display:flex;gap:8px;padding:10px;border-top:1px solid #e5e7eb;align-items:center}
504
- input[aria-label="message"]{flex:1;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;font:inherit}
505
- input[type="file"]{max-width:120px;font-size:12px}
506
- button{padding:8px 14px;border-radius:8px;border:none;background:var(--oc-accent);color:#fff;font-weight:600;cursor:pointer}
507
- button:disabled,input:disabled{opacity:.6;cursor:not-allowed}
508
- </style>
509
- <div class="wrap">
510
- <div class="hd">${escapeHtml(title)}</div>
511
- ${status}${errBanner}
512
- <div class="body">${bubbles}${typingIndicator}</div>
513
- <form>
514
- <input aria-label="message" placeholder="Type a message\u2026" ${disabled}/>
515
- <input type="file" accept="${ATTACHMENT_ACCEPT}" multiple ${disabled}/>
516
- <button type="submit" ${disabled}>Send</button>
517
- </form>
518
- </div>`;
519
- const form = this.shadowRoot.querySelector("form");
520
- const input = this.shadowRoot.querySelector('input[aria-label="message"]');
521
- const fileInput = this.shadowRoot.querySelector('input[type="file"]');
522
- fileInput.addEventListener("change", () => {
523
- this.pendingFiles = fileInput.files ? Array.from(fileInput.files) : [];
524
- });
525
- form.addEventListener("submit", (e) => {
526
- e.preventDefault();
527
- const files = this.pendingFiles;
528
- this.pendingFiles = [];
529
- this.send(input.value, files);
530
- input.value = "";
531
- });
532
- if (prevValue) {
533
- input.value = prevValue;
534
- if (prevSelectionStart !== null && prevSelectionEnd !== null) input.setSelectionRange(prevSelectionStart, prevSelectionEnd);
535
- }
536
- if (hadFocus) input.focus();
537
- const body = this.shadowRoot.querySelector(".body");
538
- body.scrollTop = body.scrollHeight;
539
- this.hydrateAttachmentImages();
4148
+ escapeAttr(s) {
4149
+ return s.replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
540
4150
  }
541
4151
  };
542
4152
  function escapeHtml(s) {
@@ -547,6 +4157,11 @@ var OyehelloChat = (function (exports) {
547
4157
  if (typeof customElements !== "undefined" && !customElements.get("oyehello-chat")) {
548
4158
  customElements.define("oyehello-chat", OyehelloChatElement);
549
4159
  }
4160
+ /*! Bundled license information:
4161
+
4162
+ dompurify/dist/purify.es.mjs:
4163
+ (*! @license DOMPurify 3.4.15 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.15/LICENSE *)
4164
+ */
550
4165
 
551
4166
  exports.ChatApiError = ChatApiError;
552
4167
  exports.OyehelloChatElement = OyehelloChatElement;