@noodleseed/assistant 1.2.0 → 1.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.
package/dist/index.cjs CHANGED
@@ -33,10 +33,10 @@ var common = {
33
33
  baseFontSize: 15,
34
34
  messageFontSize: 15,
35
35
  lineHeight: 1.5,
36
- panelRadius: 20,
37
- cardRadius: 14,
38
- inputRadius: 14,
39
- buttonRadius: 12,
36
+ panelRadius: 24,
37
+ cardRadius: 16,
38
+ inputRadius: 999,
39
+ buttonRadius: 999,
40
40
  launcherRadius: 999,
41
41
  spacing: 12,
42
42
  backdropBlur: 18,
@@ -48,57 +48,58 @@ var DEFAULT_APPEARANCE = {
48
48
  defaultMode: "auto",
49
49
  light: {
50
50
  ...common,
51
- page: "#F7F7F8",
52
- panel: "#FFFFFF",
53
- elevated: "#FFFFFF",
54
- input: "#F1F1F3",
55
- hover: "#ECECEF",
56
- selected: "#E4E2FF",
57
- text: "#18181B",
51
+ page: "#F8F8F8",
52
+ panel: "#F8F8F8",
53
+ elevated: "#F4F4F5",
54
+ input: "#FFFFFF",
55
+ hover: "#F4F4F5",
56
+ selected: "#FFF1E7",
57
+ text: "#09090B",
58
58
  mutedText: "#71717A",
59
- accent: "#5B4CF0",
59
+ accent: "#C2410C",
60
60
  accentText: "#FFFFFF",
61
- link: "#4A3BD5",
61
+ link: "#9A3412",
62
62
  divider: "#E4E4E7",
63
- focus: "#5B4CF0",
63
+ focus: "#C2410C",
64
64
  success: "#16835D",
65
65
  warning: "#A45B00",
66
66
  danger: "#C92A45",
67
67
  overlay: "#18181B66",
68
68
  code: "#F1F1F3",
69
69
  widgetFrame: "#E4E4E7",
70
- shadow: "0 24px 80px rgba(24, 24, 27, 0.18)"
70
+ shadow: "0 4px 16px rgba(0, 0, 0, 0.06), 0 24px 70px rgba(0, 0, 0, 0.10)"
71
71
  },
72
72
  dark: {
73
73
  ...common,
74
- page: "#111113",
75
- panel: "#19191D",
76
- elevated: "#222228",
77
- input: "#26262C",
78
- hover: "#303038",
79
- selected: "#37315F",
74
+ page: "#0C0A09",
75
+ panel: "#0C0A09",
76
+ elevated: "#27272A",
77
+ input: "#1C1917",
78
+ hover: "#27272A",
79
+ selected: "#431B0B",
80
80
  text: "#FAFAFA",
81
81
  mutedText: "#A1A1AA",
82
- accent: "#A99FFF",
83
- accentText: "#17131F",
84
- link: "#B9B1FF",
85
- divider: "#34343B",
86
- focus: "#B9B1FF",
82
+ accent: "#FB923C",
83
+ accentText: "#1C0A02",
84
+ link: "#FDBA74",
85
+ divider: "#292524",
86
+ focus: "#FB923C",
87
87
  success: "#58C69A",
88
88
  warning: "#F2B45F",
89
89
  danger: "#FF8094",
90
90
  overlay: "#00000099",
91
91
  code: "#26262C",
92
92
  widgetFrame: "#34343B",
93
- shadow: "0 24px 90px rgba(0, 0, 0, 0.55)"
93
+ shadow: "0 8px 32px rgba(0, 0, 0, 0.48)"
94
94
  }
95
95
  },
96
96
  layout: {
97
97
  mode: "floating",
98
98
  position: "bottom-right",
99
- panelWidth: 400,
100
- panelMinHeight: 420,
101
- panelMaxHeight: 720,
99
+ panelWidth: 560,
100
+ panelMinHeight: 540,
101
+ panelMaxHeight: 820,
102
+ edgeOffset: 20,
102
103
  zIndex: 2147483e3,
103
104
  density: "comfortable",
104
105
  mobileFullscreen: true
@@ -116,6 +117,7 @@ var DEFAULT_APPEARANCE = {
116
117
  welcomeHeading: "How can I help?",
117
118
  welcomeMessage: "",
118
119
  composerPlaceholder: "Ask a question\u2026",
120
+ thinking: "Thinking",
119
121
  send: "Send",
120
122
  stop: "Stop",
121
123
  close: "Close assistant",
@@ -124,7 +126,27 @@ var DEFAULT_APPEARANCE = {
124
126
  cancel: "Cancel",
125
127
  retry: "Try again",
126
128
  unavailable: "The assistant is temporarily unavailable.",
127
- sessionExpired: "Your assistant session expired. Reopen it to continue."
129
+ sessionExpired: "Your assistant session expired. Reopen it to continue.",
130
+ sessionIdle: "Assistant session idle",
131
+ sessionLoading: "Assistant session loading",
132
+ sessionReady: "Assistant session ready",
133
+ sessionError: "Assistant session unavailable"
134
+ },
135
+ presentation: {
136
+ panel: {
137
+ surface: "glass",
138
+ elevation: "soft",
139
+ border: "subtle"
140
+ },
141
+ launcher: {
142
+ icon: "brand-mark",
143
+ size: "md",
144
+ status: "none",
145
+ effect: "none"
146
+ },
147
+ header: { mark: "none" },
148
+ composer: { leadingIcon: "none", sendIcon: "arrow-up", shape: "pill" },
149
+ messages: { userStyle: "bubble", assistantStyle: "plain" }
128
150
  },
129
151
  suggestedPrompts: [],
130
152
  locale: "en",
@@ -149,10 +171,12 @@ function resolveAppearance(input = {}) {
149
171
  layout: {
150
172
  ...DEFAULT_APPEARANCE.layout,
151
173
  ...branding?.density ? { density: branding.density } : {},
152
- ...assistant?.layout
174
+ ...assistant?.layout,
175
+ ...assistant?.layout?.edgeOffset === void 0 ? {} : { edgeOffset: boundedNumber(assistant.layout.edgeOffset, 0, 96) }
153
176
  },
154
177
  behavior: { ...DEFAULT_APPEARANCE.behavior, ...assistant?.behavior },
155
178
  labels: { ...DEFAULT_APPEARANCE.labels, ...assistant?.labels },
179
+ presentation: resolvePresentation(assistant?.presentation),
156
180
  suggestedPrompts: assistant?.suggestedPrompts ?? DEFAULT_APPEARANCE.suggestedPrompts,
157
181
  ...assistant?.privacyUrl ? { privacyUrl: assistant.privacyUrl } : {},
158
182
  ...assistant?.termsUrl ? { termsUrl: assistant.termsUrl } : {},
@@ -160,6 +184,33 @@ function resolveAppearance(input = {}) {
160
184
  direction: assistant?.direction ?? DEFAULT_APPEARANCE.direction
161
185
  };
162
186
  }
187
+ function resolvePresentation(input) {
188
+ const defaults = DEFAULT_APPEARANCE.presentation;
189
+ const panelRadius = input?.panel?.radius === void 0 ? defaults.panel.radius : boundedNumber(input.panel.radius, 0, 64);
190
+ return {
191
+ panel: {
192
+ ...defaults.panel,
193
+ ...input?.panel,
194
+ ...panelRadius === void 0 ? {} : { radius: panelRadius }
195
+ },
196
+ launcher: { ...defaults.launcher, ...input?.launcher },
197
+ header: {
198
+ mark: input?.header?.mark ?? defaults.header.mark,
199
+ ...input?.header?.badge ? {
200
+ badge: {
201
+ text: input.header.badge.text,
202
+ tone: input.header.badge.tone ?? "neutral",
203
+ indicator: input.header.badge.indicator ?? false
204
+ }
205
+ } : {}
206
+ },
207
+ composer: { ...defaults.composer, ...input?.composer },
208
+ messages: { ...defaults.messages, ...input?.messages }
209
+ };
210
+ }
211
+ function boundedNumber(value, min, max) {
212
+ return Math.min(max, Math.max(min, Number.isFinite(value) ? Math.round(value) : min));
213
+ }
163
214
  function themedAsset(asset) {
164
215
  return asset ? { light: asset.uri, dark: asset.darkUri ?? asset.uri } : {};
165
216
  }
@@ -167,12 +218,15 @@ function resolveTheme(mode, branding) {
167
218
  const defaults = DEFAULT_APPEARANCE.theme[mode];
168
219
  const surface = mode === "light" ? branding?.surface : branding?.surfaceDark;
169
220
  const portable = branding?.theme?.[mode];
221
+ const configuredAccent = portable?.accent ?? branding?.accent;
222
+ const derivedAccentText = configuredAccent && !portable?.accentText ? contrastingText(configuredAccent) : void 0;
170
223
  const radius = branding?.radius ? radiusValue(branding.radius) : void 0;
171
224
  return {
172
225
  ...defaults,
173
226
  ...branding?.accent ? { accent: branding.accent } : {},
174
227
  ...surface ? { page: surface, panel: surface } : {},
175
228
  ...mapPortableTheme(portable),
229
+ ...derivedAccentText ? { accentText: derivedAccentText } : {},
176
230
  ...radius === void 0 ? {} : {
177
231
  panelRadius: radius,
178
232
  cardRadius: radius,
@@ -182,6 +236,25 @@ function resolveTheme(mode, branding) {
182
236
  ...branding?.typography === "serif" ? { fontFamily: "ui-serif, Georgia, serif" } : branding?.typography === "mono" ? { fontFamily: defaults.monoFontFamily } : {}
183
237
  };
184
238
  }
239
+ function contrastingText(background) {
240
+ const dark = "#09090B";
241
+ const light = "#FFFFFF";
242
+ return contrastRatio(background, dark) >= contrastRatio(background, light) ? dark : light;
243
+ }
244
+ function contrastRatio(first, second) {
245
+ const lighter = Math.max(relativeLuminance(first), relativeLuminance(second));
246
+ const darker = Math.min(relativeLuminance(first), relativeLuminance(second));
247
+ return (lighter + 0.05) / (darker + 0.05);
248
+ }
249
+ function relativeLuminance(color) {
250
+ const match = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
251
+ if (!match) return 0;
252
+ const channels = match.slice(1).map((channel) => {
253
+ const value = Number.parseInt(channel, 16) / 255;
254
+ return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
255
+ });
256
+ return 0.2126 * (channels[0] ?? 0) + 0.7152 * (channels[1] ?? 0) + 0.0722 * (channels[2] ?? 0);
257
+ }
185
258
  function mapPortableTheme(input) {
186
259
  if (!input) return {};
187
260
  return {
@@ -297,8 +370,8 @@ function isJsonValue(value, depth) {
297
370
  return value.length <= 256 && value.every((entry) => isJsonValue(entry, depth + 1));
298
371
  }
299
372
  if (!isRecord(value)) return false;
300
- const entries = Object.entries(value);
301
- return entries.length <= 256 && entries.every(([, entry]) => isJsonValue(entry, depth + 1));
373
+ const entries2 = Object.entries(value);
374
+ return entries2.length <= 256 && entries2.every(([, entry]) => isJsonValue(entry, depth + 1));
302
375
  }
303
376
  function isRecord(value) {
304
377
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -375,13 +448,13 @@ function copyJsonValue(value, path, depth, ancestors) {
375
448
  ancestors.delete(value);
376
449
  return copy2;
377
450
  }
378
- const entries = Object.entries(value);
379
- if (entries.length > MAX_ENTRIES) {
451
+ const entries2 = Object.entries(value);
452
+ if (entries2.length > MAX_ENTRIES) {
380
453
  throw new Error(`Model context has more than 128 entries at ${path}`);
381
454
  }
382
455
  const copy = /* @__PURE__ */ Object.create(null);
383
456
  ancestors.add(value);
384
- for (const [key, entry] of entries) {
457
+ for (const [key, entry] of entries2) {
385
458
  if (SENSITIVE_KEY.test(key)) {
386
459
  throw new Error(`Model context contains sensitive key ${path}.${key}`);
387
460
  }
@@ -417,14 +490,14 @@ var AssistantTransportError = class extends Error {
417
490
  async function consumeAssistantEvents(response, onEvent) {
418
491
  const stream = new AssistantEventStream(onEvent);
419
492
  if (!response.body) {
420
- let text;
493
+ let text2;
421
494
  try {
422
- text = await response.text();
495
+ text2 = await response.text();
423
496
  } catch (error) {
424
497
  if (isAbortError(error)) throw error;
425
498
  throw invalidStream("assistant event stream could not be read", error);
426
499
  }
427
- stream.push(text);
500
+ stream.push(text2);
428
501
  stream.finish(response.headers.get("content-type") ?? "");
429
502
  return;
430
503
  }
@@ -562,8 +635,14 @@ var DefaultAssistantClient = class {
562
635
  this.#listeners.add(listener);
563
636
  return () => this.#listeners.delete(listener);
564
637
  }
565
- async sendMessage(text) {
566
- const message = text.trim();
638
+ async connect() {
639
+ if (this.#session) return;
640
+ await this.#singleFlight(async (signal) => {
641
+ if (!this.#session) await this.#createSession(signal);
642
+ });
643
+ }
644
+ async sendMessage(text2) {
645
+ const message = text2.trim();
567
646
  if (!message) return;
568
647
  await this.#singleFlight(async (signal) => {
569
648
  await this.#sendTurn(message, true, signal, this.#modelContext);
@@ -1191,262 +1270,3378 @@ function formatArgumentValue(value) {
1191
1270
  return JSON.stringify(value) ?? "";
1192
1271
  }
1193
1272
 
1194
- // src/element-event-controller.ts
1195
- var AssistantElementEventController = class {
1196
- #host;
1197
- #assistantBody;
1198
- #completedTool;
1199
- #proposalCards = /* @__PURE__ */ new Map();
1200
- constructor(host) {
1201
- this.#host = host;
1273
+ // ../../node_modules/.pnpm/dompurify@3.4.11/node_modules/dompurify/dist/purify.es.mjs
1274
+ function _arrayLikeToArray(r, a) {
1275
+ (null == a || a > r.length) && (a = r.length);
1276
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
1277
+ return n;
1278
+ }
1279
+ function _arrayWithHoles(r) {
1280
+ if (Array.isArray(r)) return r;
1281
+ }
1282
+ function _iterableToArrayLimit(r, l3) {
1283
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
1284
+ if (null != t) {
1285
+ var e, n, i, u, a = [], f = true, o = false;
1286
+ try {
1287
+ if (i = (t = t.call(r)).next, 0 === l3) ;
1288
+ else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l3); f = true) ;
1289
+ } catch (r2) {
1290
+ o = true, n = r2;
1291
+ } finally {
1292
+ try {
1293
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
1294
+ } finally {
1295
+ if (o) throw n;
1296
+ }
1297
+ }
1298
+ return a;
1202
1299
  }
1203
- handle(event) {
1204
- if (event.event === "view_available") {
1205
- this.#host.element.dispatchEvent(
1206
- new CustomEvent("assistant-view-available", {
1207
- detail: event.data
1208
- })
1209
- );
1210
- return;
1300
+ }
1301
+ function _nonIterableRest() {
1302
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1303
+ }
1304
+ function _slicedToArray(r, e) {
1305
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
1306
+ }
1307
+ function _unsupportedIterableToArray(r, a) {
1308
+ if (r) {
1309
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
1310
+ var t = {}.toString.call(r).slice(8, -1);
1311
+ 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;
1312
+ }
1313
+ }
1314
+ var entries = Object.entries;
1315
+ var setPrototypeOf = Object.setPrototypeOf;
1316
+ var isFrozen = Object.isFrozen;
1317
+ var getPrototypeOf = Object.getPrototypeOf;
1318
+ var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1319
+ var freeze = Object.freeze;
1320
+ var seal = Object.seal;
1321
+ var create = Object.create;
1322
+ var _ref = typeof Reflect !== "undefined" && Reflect;
1323
+ var apply = _ref.apply;
1324
+ var construct = _ref.construct;
1325
+ if (!freeze) {
1326
+ freeze = function freeze2(x2) {
1327
+ return x2;
1328
+ };
1329
+ }
1330
+ if (!seal) {
1331
+ seal = function seal2(x2) {
1332
+ return x2;
1333
+ };
1334
+ }
1335
+ if (!apply) {
1336
+ apply = function apply2(func, thisArg) {
1337
+ for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
1338
+ args[_key - 2] = arguments[_key];
1211
1339
  }
1212
- if (event.event === "unrecognized") return;
1213
- const { event: name, data } = event;
1214
- if (name === "session_started") {
1215
- if (isRecord4(data.configuration)) {
1216
- this.#host.applyConfiguration(data.configuration);
1217
- }
1218
- this.#host.element.dispatchEvent(
1219
- new CustomEvent("assistant-session-started", {
1220
- detail: { expiresAt: String(data.expiresAt ?? "") }
1221
- })
1222
- );
1223
- return;
1340
+ return func.apply(thisArg, args);
1341
+ };
1342
+ }
1343
+ if (!construct) {
1344
+ construct = function construct2(Func) {
1345
+ for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
1346
+ args[_key2 - 1] = arguments[_key2];
1224
1347
  }
1225
- if (name === "session_expired") {
1226
- this.#host.element.dispatchEvent(new CustomEvent("assistant-session-expired"));
1227
- return;
1348
+ return new Func(...args);
1349
+ };
1350
+ }
1351
+ var arrayForEach = unapply(Array.prototype.forEach);
1352
+ var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
1353
+ var arrayPop = unapply(Array.prototype.pop);
1354
+ var arrayPush = unapply(Array.prototype.push);
1355
+ var arraySplice = unapply(Array.prototype.splice);
1356
+ var arrayIsArray = Array.isArray;
1357
+ var stringToLowerCase = unapply(String.prototype.toLowerCase);
1358
+ var stringToString = unapply(String.prototype.toString);
1359
+ var stringMatch = unapply(String.prototype.match);
1360
+ var stringReplace = unapply(String.prototype.replace);
1361
+ var stringIndexOf = unapply(String.prototype.indexOf);
1362
+ var stringTrim = unapply(String.prototype.trim);
1363
+ var numberToString = unapply(Number.prototype.toString);
1364
+ var booleanToString = unapply(Boolean.prototype.toString);
1365
+ var bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
1366
+ var symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
1367
+ var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
1368
+ var objectToString = unapply(Object.prototype.toString);
1369
+ var regExpTest = unapply(RegExp.prototype.test);
1370
+ var typeErrorCreate = unconstruct(TypeError);
1371
+ function unapply(func) {
1372
+ return function(thisArg) {
1373
+ if (thisArg instanceof RegExp) {
1374
+ thisArg.lastIndex = 0;
1228
1375
  }
1229
- if (name === "session_reset") {
1230
- this.resetConversation();
1231
- return;
1376
+ for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1377
+ args[_key3 - 1] = arguments[_key3];
1232
1378
  }
1233
- if (name === "context_changed") {
1234
- this.#host.element.dispatchEvent(
1235
- new CustomEvent("assistant-context-changed", { detail: { context: data.context } })
1236
- );
1237
- return;
1379
+ return apply(func, thisArg, args);
1380
+ };
1381
+ }
1382
+ function unconstruct(Func) {
1383
+ return function() {
1384
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1385
+ args[_key4] = arguments[_key4];
1238
1386
  }
1239
- if (name === "model_context_changed") {
1240
- this.#host.element.dispatchEvent(
1241
- new CustomEvent("assistant-model-context-changed", {
1242
- detail: { modelContext: data.modelContext }
1243
- })
1244
- );
1245
- return;
1387
+ return construct(Func, args);
1388
+ };
1389
+ }
1390
+ function addToSet(set, array) {
1391
+ let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
1392
+ if (setPrototypeOf) {
1393
+ setPrototypeOf(set, null);
1394
+ }
1395
+ if (!arrayIsArray(array)) {
1396
+ return set;
1397
+ }
1398
+ let l3 = array.length;
1399
+ while (l3--) {
1400
+ let element = array[l3];
1401
+ if (typeof element === "string") {
1402
+ const lcElement = transformCaseFunc(element);
1403
+ if (lcElement !== element) {
1404
+ if (!isFrozen(array)) {
1405
+ array[l3] = lcElement;
1406
+ }
1407
+ element = lcElement;
1408
+ }
1246
1409
  }
1247
- if (name === "message_started") {
1248
- this.#assistantBody = void 0;
1249
- this.#host.appendMessage("user", String(data.message ?? ""));
1250
- this.#host.element.dispatchEvent(new CustomEvent("assistant-message-started"));
1251
- return;
1410
+ set[element] = true;
1411
+ }
1412
+ return set;
1413
+ }
1414
+ function cleanArray(array) {
1415
+ for (let index = 0; index < array.length; index++) {
1416
+ const isPropertyExist = objectHasOwnProperty(array, index);
1417
+ if (!isPropertyExist) {
1418
+ array[index] = null;
1252
1419
  }
1253
- if (name === "message_completed") {
1254
- this.#assistantBody = void 0;
1255
- this.#host.element.dispatchEvent(new CustomEvent("assistant-message-completed"));
1256
- return;
1420
+ }
1421
+ return array;
1422
+ }
1423
+ function clone(object) {
1424
+ const newObject = create(null);
1425
+ for (const _ref2 of entries(object)) {
1426
+ var _ref3 = _slicedToArray(_ref2, 2);
1427
+ const property = _ref3[0];
1428
+ const value = _ref3[1];
1429
+ const isPropertyExist = objectHasOwnProperty(object, property);
1430
+ if (isPropertyExist) {
1431
+ if (arrayIsArray(value)) {
1432
+ newObject[property] = cleanArray(value);
1433
+ } else if (value && typeof value === "object" && value.constructor === Object) {
1434
+ newObject[property] = clone(value);
1435
+ } else {
1436
+ newObject[property] = value;
1437
+ }
1257
1438
  }
1258
- if (name === "interaction_started") {
1259
- this.#assistantBody = void 0;
1260
- this.#completedTool = void 0;
1261
- return;
1439
+ }
1440
+ return newObject;
1441
+ }
1442
+ function stringifyValue(value) {
1443
+ switch (typeof value) {
1444
+ case "string": {
1445
+ return value;
1262
1446
  }
1263
- if (name === "interaction_completed") {
1264
- this.#finishInteraction(String(data.id ?? ""), String(data.action ?? "accept"));
1265
- return;
1447
+ case "number": {
1448
+ return numberToString(value);
1266
1449
  }
1267
- if (name === "content") {
1268
- const body = this.#assistantBody ?? this.#host.appendMessage("assistant", "");
1269
- this.#assistantBody = body;
1270
- if (body) body.textContent += String(data.delta ?? "");
1271
- return;
1450
+ case "boolean": {
1451
+ return booleanToString(value);
1272
1452
  }
1273
- if (name === "tool_proposed" || name === "interaction_proposed") {
1274
- this.#appendToolProposal(
1275
- String(data.id ?? ""),
1276
- String(data.tool ?? ("title" in data ? data.title : void 0) ?? "Action"),
1277
- isRecord4(data.arguments) ? data.arguments : void 0
1278
- );
1279
- return;
1453
+ case "bigint": {
1454
+ return bigintToString ? bigintToString(value) : "0";
1280
1455
  }
1281
- if (name === "input_requested" && isRecord4(data.requestedSchema)) {
1282
- this.#appendInputRequest(
1283
- String(data.id ?? ""),
1284
- String(data.message ?? "More information is required"),
1285
- data.requestedSchema
1286
- );
1287
- return;
1456
+ case "symbol": {
1457
+ return symbolToString ? symbolToString(value) : "Symbol()";
1288
1458
  }
1289
- if (name === "tool_completed") {
1290
- this.#completedTool = data;
1291
- return;
1459
+ case "undefined": {
1460
+ return objectToString(value);
1292
1461
  }
1293
- if (name === "error") {
1294
- this.#host.dispatchError({
1295
- code: String(data.code ?? "stream_failed"),
1296
- ...typeof data.status === "number" ? { status: data.status } : {},
1297
- retryable: data.retryable === true
1298
- });
1462
+ case "function":
1463
+ case "object": {
1464
+ if (value === null) {
1465
+ return objectToString(value);
1466
+ }
1467
+ const valueAsRecord = value;
1468
+ const valueToString = lookupGetter(valueAsRecord, "toString");
1469
+ if (typeof valueToString === "function") {
1470
+ const stringified = valueToString(valueAsRecord);
1471
+ return typeof stringified === "string" ? stringified : objectToString(stringified);
1472
+ }
1473
+ return objectToString(value);
1299
1474
  }
1300
- }
1301
- resetConversation() {
1302
- this.#host.messages()?.replaceChildren();
1303
- this.#proposalCards.clear();
1304
- this.#assistantBody = void 0;
1305
- this.#completedTool = void 0;
1306
- this.#host.element.dispatchEvent(new CustomEvent("assistant-session-reset"));
1307
- }
1308
- #finishInteraction(id, action) {
1309
- if (this.#completedTool && !this.#assistantBody) {
1310
- this.#host.appendMessage("assistant", JSON.stringify(this.#completedTool.result ?? {}) ?? "");
1475
+ default: {
1476
+ return objectToString(value);
1311
1477
  }
1312
- this.#proposalCards.get(id)?.remove();
1313
- this.#proposalCards.delete(id);
1314
- if (action === "accept") {
1315
- this.#host.element.dispatchEvent(
1316
- new CustomEvent("assistant-tool-completed", { detail: { id } })
1317
- );
1478
+ }
1479
+ }
1480
+ function lookupGetter(object, prop) {
1481
+ while (object !== null) {
1482
+ const desc = getOwnPropertyDescriptor(object, prop);
1483
+ if (desc) {
1484
+ if (desc.get) {
1485
+ return unapply(desc.get);
1486
+ }
1487
+ if (typeof desc.value === "function") {
1488
+ return unapply(desc.value);
1489
+ }
1318
1490
  }
1319
- this.#host.element.dispatchEvent(
1320
- new CustomEvent("assistant-interaction-resolved", { detail: { id, action } })
1321
- );
1322
- this.#assistantBody = void 0;
1323
- this.#completedTool = void 0;
1491
+ object = getPrototypeOf(object);
1324
1492
  }
1325
- #appendToolProposal(id, tool, arguments_) {
1326
- const messages = this.#host.messages();
1327
- if (!messages || !id) return;
1328
- this.#proposalCards.get(id)?.remove();
1329
- const labels = this.#host.labels();
1330
- const card = createInteractionCard({
1331
- tool,
1332
- ...arguments_ ? { arguments: arguments_ } : {},
1333
- labels: {
1334
- accept: labels.confirm,
1335
- decline: "Decline",
1336
- cancel: labels.cancel
1337
- },
1338
- respond: (action) => this.#host.respond(id, { action })
1339
- });
1340
- messages.append(card);
1341
- this.#proposalCards.set(id, card);
1342
- this.#host.element.dispatchEvent(
1343
- new CustomEvent("assistant-tool-proposed", { detail: { id, tool, arguments: arguments_ } })
1344
- );
1493
+ function fallbackValue() {
1494
+ return null;
1345
1495
  }
1346
- #appendInputRequest(id, message, requestedSchema) {
1347
- const messages = this.#host.messages();
1348
- if (!messages || !id) return;
1349
- this.#proposalCards.get(id)?.remove();
1350
- const labels = this.#host.labels();
1351
- const card = createInputRequestCard({
1352
- message,
1353
- requestedSchema,
1354
- labels: {
1355
- submit: labels.confirm,
1356
- decline: "Decline",
1357
- cancel: labels.cancel
1496
+ return fallbackValue;
1497
+ }
1498
+ function isRegex(value) {
1499
+ try {
1500
+ regExpTest(value, "");
1501
+ return true;
1502
+ } catch (_unused) {
1503
+ return false;
1504
+ }
1505
+ }
1506
+ 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"]);
1507
+ 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"]);
1508
+ 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"]);
1509
+ 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"]);
1510
+ 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"]);
1511
+ var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
1512
+ var text = freeze(["#text"]);
1513
+ 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"]);
1514
+ 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", "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", "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-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "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"]);
1515
+ 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"]);
1516
+ var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
1517
+ var MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
1518
+ var ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
1519
+ var TMPLIT_EXPR = seal(/\${[\w\W]*/g);
1520
+ var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
1521
+ var ARIA_ATTR = seal(/^aria-[\-\w]+$/);
1522
+ var IS_ALLOWED_URI = seal(
1523
+ /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
1524
+ // eslint-disable-line no-useless-escape
1525
+ );
1526
+ var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
1527
+ var ATTR_WHITESPACE = seal(
1528
+ /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
1529
+ // eslint-disable-line no-control-regex
1530
+ );
1531
+ var DOCTYPE_NAME = seal(/^html$/i);
1532
+ var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
1533
+ var ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
1534
+ var COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
1535
+ var FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
1536
+ var SELF_CLOSING_TAG = seal(/\/>/i);
1537
+ var NODE_TYPE = {
1538
+ element: 1,
1539
+ attribute: 2,
1540
+ text: 3,
1541
+ cdataSection: 4,
1542
+ entityReference: 5,
1543
+ // Deprecated
1544
+ entityNode: 6,
1545
+ // Deprecated
1546
+ processingInstruction: 7,
1547
+ comment: 8,
1548
+ document: 9,
1549
+ documentType: 10,
1550
+ documentFragment: 11,
1551
+ notation: 12
1552
+ // Deprecated
1553
+ };
1554
+ var getGlobal = function getGlobal2() {
1555
+ return typeof window === "undefined" ? null : window;
1556
+ };
1557
+ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, purifyHostElement) {
1558
+ if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") {
1559
+ return null;
1560
+ }
1561
+ let suffix = null;
1562
+ const ATTR_NAME = "data-tt-policy-suffix";
1563
+ if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
1564
+ suffix = purifyHostElement.getAttribute(ATTR_NAME);
1565
+ }
1566
+ const policyName = "dompurify" + (suffix ? "#" + suffix : "");
1567
+ try {
1568
+ return trustedTypes.createPolicy(policyName, {
1569
+ createHTML(html2) {
1570
+ return html2;
1358
1571
  },
1359
- respond: (response) => this.#host.respond(id, response)
1572
+ createScriptURL(scriptUrl) {
1573
+ return scriptUrl;
1574
+ }
1360
1575
  });
1361
- messages.append(card);
1362
- this.#proposalCards.set(id, card);
1363
- this.#host.element.dispatchEvent(
1364
- new CustomEvent("assistant-input-requested", {
1365
- detail: { id, message, requestedSchema }
1366
- })
1367
- );
1576
+ } catch (_2) {
1577
+ console.warn("TrustedTypes policy " + policyName + " could not be created.");
1578
+ return null;
1368
1579
  }
1369
1580
  };
1370
- function isRecord4(value) {
1371
- return typeof value === "object" && value !== null && !Array.isArray(value);
1372
- }
1373
-
1374
- // src/element-styles.ts
1375
- var ASSISTANT_ELEMENT_STYLES = `<style>
1376
- :host { color-scheme: light dark; font-family: var(--ns-assistant-font-family, var(--ns-assistant-default-font-family)); font-size: var(--ns-assistant-base-font-size, var(--ns-assistant-default-base-font-size)); line-height: var(--ns-assistant-line-height, var(--ns-assistant-default-line-height)); z-index: var(--ns-assistant-z-index, var(--ns-assistant-default-z-index)); }
1377
- :host([data-mode="floating"]) { position: fixed; bottom: 24px; right: 24px; }
1378
- :host([data-mode="floating"][data-position="bottom-left"]) { right: auto; left: 24px; }
1379
- .launcher { width: 54px; height: 54px; border: 0; border-radius: var(--ns-assistant-launcher-radius, var(--ns-assistant-default-launcher-radius)); color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); cursor: pointer; }
1380
- .launcher img { width: 24px; height: 24px; object-fit: contain; }
1381
- .panel { display: none; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 32px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 32px)); overflow: hidden; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); }
1382
- :host([open]) .panel { display: grid; grid-template-rows: auto auto 1fr auto; }
1383
- :host([open]) .launcher { display: none; }
1384
- header { display: flex; gap: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); align-items: center; padding: calc(var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)) * 1.2); border-bottom: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }
1385
- header strong { flex: 1; }
1386
- .brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }
1387
- button { font: inherit; }
1388
- .close, .send { border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); cursor: pointer; }
1389
- .close { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; font-size: 24px; }
1390
- .welcome { padding: calc(var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)) * 1.5); }
1391
- .welcome h2 { margin: 0; font-size: 1.25em; }
1392
- .welcome p { margin: 6px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
1393
- .suggested-prompts { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); }
1394
- .suggested-prompts:empty { display: none; }
1395
- .suggested-prompts button { padding: 7px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: transparent; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; cursor: pointer; }
1396
- .messages { min-height: 120px; padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); overflow: auto; }
1397
- .message { width: fit-content; max-width: 84%; margin: 8px 0; padding: 10px 12px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); white-space: pre-wrap; }
1398
- .message .avatar { float: left; width: 24px; height: 24px; margin-right: 8px; border-radius: 50%; object-fit: cover; }
1399
- .message time { display: block; margin-top: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; }
1400
- .message.user { margin-left: auto; color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
1401
- .tool-proposal { display: grid; gap: 10px; margin: 10px 0; padding: 12px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); }
1402
- .proposal-arguments { display: grid; grid-template-columns: minmax(90px, auto) 1fr; gap: 4px 10px; margin: 0; font-size: .9em; }
1403
- .proposal-arguments dt { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
1404
- .proposal-arguments dd { margin: 0; overflow-wrap: anywhere; }
1405
- .proposal-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: end; }
1406
- .tool-proposal button { padding: 8px 10px; border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); cursor: pointer; }
1407
- .tool-proposal button:first-of-type { color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
1408
- .input-request form { display: grid; gap: 10px; padding: 0; border: 0; }
1409
- .input-request label { display: grid; gap: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .9em; }
1410
- .input-request input, .input-request select { width: 100%; box-sizing: border-box; padding: 8px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); font: inherit; }
1411
- .input-request input[type="checkbox"] { width: auto; justify-self: start; }
1412
- form { display: flex; gap: 8px; align-items: end; padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); border-top: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }
1413
- textarea { flex: 1; resize: none; padding: 10px 12px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 0; border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); font: inherit; }
1414
- textarea:focus-visible, button:focus-visible { outline: 3px solid var(--ns-assistant-focus, var(--ns-assistant-default-focus)); outline-offset: 2px; }
1415
- .send { padding: 10px 14px; color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
1416
- .legal { display: flex; gap: 12px; justify-content: center; padding: 0 12px 10px; font-size: .8em; }
1417
- .legal:empty { display: none; }
1418
- .legal a { color: var(--ns-assistant-link, var(--ns-assistant-default-link)); }
1419
- :host([data-density="compact"]) .welcome { padding: var(--ns-assistant-spacing, var(--ns-assistant-default-spacing)); }
1420
- @media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border-radius: 0; } }
1421
- @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } }
1422
- @media (max-width: 560px) { :host([data-mode="floating"]) { inset: auto 12px 12px; } :host([open]) .panel { width: calc(100vw - 24px); max-height: calc(100vh - 24px); } }
1423
- </style>`;
1424
-
1425
- // src/element.ts
1426
- var ASSISTANT_TAG_NAME = "noodle-assistant";
1427
- var HTMLElementBase = globalThis.HTMLElement ?? class {
1581
+ var _createHooksMap = function _createHooksMap2() {
1582
+ return {
1583
+ afterSanitizeAttributes: [],
1584
+ afterSanitizeElements: [],
1585
+ afterSanitizeShadowDOM: [],
1586
+ beforeSanitizeAttributes: [],
1587
+ beforeSanitizeElements: [],
1588
+ beforeSanitizeShadowDOM: [],
1589
+ uponSanitizeAttribute: [],
1590
+ uponSanitizeElement: [],
1591
+ uponSanitizeShadowNode: []
1592
+ };
1428
1593
  };
1429
- var NoodleAssistantElement = class extends HTMLElementBase {
1430
- static observedAttributes = ["open", "theme"];
1431
- #appearance = resolveAppearance();
1432
- #client;
1433
- #clientEndpoint = "";
1434
- #unsubscribeClient;
1435
- #messages;
1436
- #media;
1437
- #context;
1438
- #modelContext;
1439
- sessionEndpoint = "";
1440
- #events = new AssistantElementEventController({
1441
- element: this,
1442
- messages: () => this.#messages,
1443
- appendMessage: (role, text) => this.#appendMessage(role, text),
1444
- applyConfiguration: (configuration) => {
1445
- this.#appearance = resolveAppearance(configuration);
1446
- this.#render();
1447
- },
1448
- labels: () => ({
1449
- confirm: this.#appearance.labels.confirm,
1594
+ var _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
1595
+ return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
1596
+ };
1597
+ function createDOMPurify() {
1598
+ let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
1599
+ const DOMPurify = (root) => createDOMPurify(root);
1600
+ DOMPurify.version = "3.4.11";
1601
+ DOMPurify.removed = [];
1602
+ if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
1603
+ DOMPurify.isSupported = false;
1604
+ return DOMPurify;
1605
+ }
1606
+ let document2 = window2.document;
1607
+ const originalDocument = document2;
1608
+ const currentScript = originalDocument.currentScript;
1609
+ window2.DocumentFragment;
1610
+ const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap;
1611
+ _window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap;
1612
+ window2.HTMLFormElement;
1613
+ const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
1614
+ const ElementPrototype = Element.prototype;
1615
+ const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
1616
+ const remove = lookupGetter(ElementPrototype, "remove");
1617
+ const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
1618
+ const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
1619
+ const getParentNode = lookupGetter(ElementPrototype, "parentNode");
1620
+ const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
1621
+ const getAttributes = lookupGetter(ElementPrototype, "attributes");
1622
+ const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
1623
+ const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
1624
+ if (typeof HTMLTemplateElement === "function") {
1625
+ const template = document2.createElement("template");
1626
+ if (template.content && template.content.ownerDocument) {
1627
+ document2 = template.content.ownerDocument;
1628
+ }
1629
+ }
1630
+ let trustedTypesPolicy;
1631
+ let emptyHTML = "";
1632
+ let defaultTrustedTypesPolicy;
1633
+ let defaultTrustedTypesPolicyResolved = false;
1634
+ let IN_TRUSTED_TYPES_POLICY = 0;
1635
+ const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy2() {
1636
+ if (IN_TRUSTED_TYPES_POLICY > 0) {
1637
+ 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.');
1638
+ }
1639
+ };
1640
+ const _createTrustedHTML = function _createTrustedHTML2(html2) {
1641
+ _assertNotInTrustedTypesPolicy();
1642
+ IN_TRUSTED_TYPES_POLICY++;
1643
+ try {
1644
+ return trustedTypesPolicy.createHTML(html2);
1645
+ } finally {
1646
+ IN_TRUSTED_TYPES_POLICY--;
1647
+ }
1648
+ };
1649
+ const _createTrustedScriptURL = function _createTrustedScriptURL2(scriptUrl) {
1650
+ _assertNotInTrustedTypesPolicy();
1651
+ IN_TRUSTED_TYPES_POLICY++;
1652
+ try {
1653
+ return trustedTypesPolicy.createScriptURL(scriptUrl);
1654
+ } finally {
1655
+ IN_TRUSTED_TYPES_POLICY--;
1656
+ }
1657
+ };
1658
+ const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy2() {
1659
+ if (!defaultTrustedTypesPolicyResolved) {
1660
+ defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
1661
+ defaultTrustedTypesPolicyResolved = true;
1662
+ }
1663
+ return defaultTrustedTypesPolicy;
1664
+ };
1665
+ const _document = document2, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
1666
+ const importNode = originalDocument.importNode;
1667
+ let hooks = _createHooksMap();
1668
+ DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
1669
+ 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;
1670
+ let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
1671
+ let ALLOWED_TAGS = null;
1672
+ const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
1673
+ let ALLOWED_ATTR = null;
1674
+ const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
1675
+ let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
1676
+ tagNameCheck: {
1677
+ writable: true,
1678
+ configurable: false,
1679
+ enumerable: true,
1680
+ value: null
1681
+ },
1682
+ attributeNameCheck: {
1683
+ writable: true,
1684
+ configurable: false,
1685
+ enumerable: true,
1686
+ value: null
1687
+ },
1688
+ allowCustomizedBuiltInElements: {
1689
+ writable: true,
1690
+ configurable: false,
1691
+ enumerable: true,
1692
+ value: false
1693
+ }
1694
+ }));
1695
+ let FORBID_TAGS = null;
1696
+ let FORBID_ATTR = null;
1697
+ const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
1698
+ tagCheck: {
1699
+ writable: true,
1700
+ configurable: false,
1701
+ enumerable: true,
1702
+ value: null
1703
+ },
1704
+ attributeCheck: {
1705
+ writable: true,
1706
+ configurable: false,
1707
+ enumerable: true,
1708
+ value: null
1709
+ }
1710
+ }));
1711
+ let ALLOW_ARIA_ATTR = true;
1712
+ let ALLOW_DATA_ATTR = true;
1713
+ let ALLOW_UNKNOWN_PROTOCOLS = false;
1714
+ let ALLOW_SELF_CLOSE_IN_ATTR = true;
1715
+ let SAFE_FOR_TEMPLATES = false;
1716
+ let SAFE_FOR_XML = true;
1717
+ let WHOLE_DOCUMENT = false;
1718
+ let SET_CONFIG = false;
1719
+ let SET_CONFIG_ALLOWED_TAGS = null;
1720
+ let SET_CONFIG_ALLOWED_ATTR = null;
1721
+ let FORCE_BODY = false;
1722
+ let RETURN_DOM = false;
1723
+ let RETURN_DOM_FRAGMENT = false;
1724
+ let RETURN_TRUSTED_TYPE = false;
1725
+ let SANITIZE_DOM = true;
1726
+ let SANITIZE_NAMED_PROPS = false;
1727
+ const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
1728
+ let KEEP_CONTENT = true;
1729
+ let IN_PLACE = false;
1730
+ let USE_PROFILES = {};
1731
+ let FORBID_CONTENTS = null;
1732
+ const DEFAULT_FORBID_CONTENTS = addToSet({}, [
1733
+ "annotation-xml",
1734
+ "audio",
1735
+ "colgroup",
1736
+ "desc",
1737
+ "foreignobject",
1738
+ "head",
1739
+ "iframe",
1740
+ "math",
1741
+ "mi",
1742
+ "mn",
1743
+ "mo",
1744
+ "ms",
1745
+ "mtext",
1746
+ "noembed",
1747
+ "noframes",
1748
+ "noscript",
1749
+ "plaintext",
1750
+ "script",
1751
+ // <selectedcontent> mirrors the selected <option>'s subtree, cloned by
1752
+ // the UA (customizable <select>) — including any on* handlers — and the
1753
+ // engine re-mirrors synchronously whenever a removal changes which
1754
+ // option/selectedcontent is current, even inside DOMPurify's inert
1755
+ // DOMParser document. Hoisting its children on removal re-inserts a fresh
1756
+ // mirror target ahead of the walk, which the engine refills, looping
1757
+ // forever (DoS) and amplifying output. Dropping its content on removal
1758
+ // (rather than hoisting) breaks that cascade; the content is a duplicate
1759
+ // of the option, which is sanitized on its own. See campaign-3 F1/F6.
1760
+ "selectedcontent",
1761
+ "style",
1762
+ "svg",
1763
+ "template",
1764
+ "thead",
1765
+ "title",
1766
+ "video",
1767
+ "xmp"
1768
+ ]);
1769
+ let DATA_URI_TAGS = null;
1770
+ const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
1771
+ let URI_SAFE_ATTRIBUTES = null;
1772
+ const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ["alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns"]);
1773
+ const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
1774
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
1775
+ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
1776
+ let NAMESPACE = HTML_NAMESPACE;
1777
+ let IS_EMPTY_INPUT = false;
1778
+ let ALLOWED_NAMESPACES = null;
1779
+ const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
1780
+ const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(["mi", "mo", "mn", "ms", "mtext"]);
1781
+ let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
1782
+ const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
1783
+ let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
1784
+ const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
1785
+ let PARSER_MEDIA_TYPE = null;
1786
+ const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
1787
+ const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
1788
+ let transformCaseFunc = null;
1789
+ let CONFIG = null;
1790
+ const formElement = document2.createElement("form");
1791
+ const isRegexOrFunction = function isRegexOrFunction2(testValue) {
1792
+ return testValue instanceof RegExp || testValue instanceof Function;
1793
+ };
1794
+ const _parseConfig = function _parseConfig2() {
1795
+ let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
1796
+ if (CONFIG && CONFIG === cfg) {
1797
+ return;
1798
+ }
1799
+ if (!cfg || typeof cfg !== "object") {
1800
+ cfg = {};
1801
+ }
1802
+ cfg = clone(cfg);
1803
+ PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
1804
+ SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
1805
+ transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
1806
+ ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, {
1807
+ transform: transformCaseFunc
1808
+ });
1809
+ ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, {
1810
+ transform: transformCaseFunc
1811
+ });
1812
+ ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, {
1813
+ transform: stringToString
1814
+ });
1815
+ URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
1816
+ transform: transformCaseFunc,
1817
+ base: DEFAULT_URI_SAFE_ATTRIBUTES
1818
+ });
1819
+ DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
1820
+ transform: transformCaseFunc,
1821
+ base: DEFAULT_DATA_URI_TAGS
1822
+ });
1823
+ FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, {
1824
+ transform: transformCaseFunc
1825
+ });
1826
+ FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), {
1827
+ transform: transformCaseFunc
1828
+ });
1829
+ FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), {
1830
+ transform: transformCaseFunc
1831
+ });
1832
+ USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
1833
+ ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
1834
+ ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
1835
+ ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
1836
+ ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
1837
+ SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
1838
+ SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
1839
+ WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
1840
+ RETURN_DOM = cfg.RETURN_DOM || false;
1841
+ RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
1842
+ RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
1843
+ FORCE_BODY = cfg.FORCE_BODY || false;
1844
+ SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
1845
+ SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
1846
+ KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
1847
+ IN_PLACE = cfg.IN_PLACE || false;
1848
+ IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
1849
+ NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
1850
+ MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
1851
+ HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
1852
+ const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
1853
+ CUSTOM_ELEMENT_HANDLING = create(null);
1854
+ if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
1855
+ CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
1856
+ }
1857
+ if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
1858
+ CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
1859
+ }
1860
+ if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
1861
+ CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
1862
+ }
1863
+ seal(CUSTOM_ELEMENT_HANDLING);
1864
+ if (SAFE_FOR_TEMPLATES) {
1865
+ ALLOW_DATA_ATTR = false;
1866
+ }
1867
+ if (RETURN_DOM_FRAGMENT) {
1868
+ RETURN_DOM = true;
1869
+ }
1870
+ if (USE_PROFILES) {
1871
+ ALLOWED_TAGS = addToSet({}, text);
1872
+ ALLOWED_ATTR = create(null);
1873
+ if (USE_PROFILES.html === true) {
1874
+ addToSet(ALLOWED_TAGS, html$1);
1875
+ addToSet(ALLOWED_ATTR, html);
1876
+ }
1877
+ if (USE_PROFILES.svg === true) {
1878
+ addToSet(ALLOWED_TAGS, svg$1);
1879
+ addToSet(ALLOWED_ATTR, svg);
1880
+ addToSet(ALLOWED_ATTR, xml);
1881
+ }
1882
+ if (USE_PROFILES.svgFilters === true) {
1883
+ addToSet(ALLOWED_TAGS, svgFilters);
1884
+ addToSet(ALLOWED_ATTR, svg);
1885
+ addToSet(ALLOWED_ATTR, xml);
1886
+ }
1887
+ if (USE_PROFILES.mathMl === true) {
1888
+ addToSet(ALLOWED_TAGS, mathMl$1);
1889
+ addToSet(ALLOWED_ATTR, mathMl);
1890
+ addToSet(ALLOWED_ATTR, xml);
1891
+ }
1892
+ }
1893
+ EXTRA_ELEMENT_HANDLING.tagCheck = null;
1894
+ EXTRA_ELEMENT_HANDLING.attributeCheck = null;
1895
+ if (objectHasOwnProperty(cfg, "ADD_TAGS")) {
1896
+ if (typeof cfg.ADD_TAGS === "function") {
1897
+ EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
1898
+ } else if (arrayIsArray(cfg.ADD_TAGS)) {
1899
+ if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
1900
+ ALLOWED_TAGS = clone(ALLOWED_TAGS);
1901
+ }
1902
+ addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
1903
+ }
1904
+ }
1905
+ if (objectHasOwnProperty(cfg, "ADD_ATTR")) {
1906
+ if (typeof cfg.ADD_ATTR === "function") {
1907
+ EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
1908
+ } else if (arrayIsArray(cfg.ADD_ATTR)) {
1909
+ if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
1910
+ ALLOWED_ATTR = clone(ALLOWED_ATTR);
1911
+ }
1912
+ addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
1913
+ }
1914
+ }
1915
+ if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
1916
+ addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
1917
+ }
1918
+ if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
1919
+ if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
1920
+ FORBID_CONTENTS = clone(FORBID_CONTENTS);
1921
+ }
1922
+ addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
1923
+ }
1924
+ if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
1925
+ if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
1926
+ FORBID_CONTENTS = clone(FORBID_CONTENTS);
1927
+ }
1928
+ addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
1929
+ }
1930
+ if (KEEP_CONTENT) {
1931
+ ALLOWED_TAGS["#text"] = true;
1932
+ }
1933
+ if (WHOLE_DOCUMENT) {
1934
+ addToSet(ALLOWED_TAGS, ["html", "head", "body"]);
1935
+ }
1936
+ if (ALLOWED_TAGS.table) {
1937
+ addToSet(ALLOWED_TAGS, ["tbody"]);
1938
+ delete FORBID_TAGS.tbody;
1939
+ }
1940
+ if (cfg.TRUSTED_TYPES_POLICY) {
1941
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") {
1942
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
1943
+ }
1944
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
1945
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
1946
+ }
1947
+ const previousTrustedTypesPolicy = trustedTypesPolicy;
1948
+ trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
1949
+ try {
1950
+ emptyHTML = _createTrustedHTML("");
1951
+ } catch (error) {
1952
+ trustedTypesPolicy = previousTrustedTypesPolicy;
1953
+ throw error;
1954
+ }
1955
+ } else if (cfg.TRUSTED_TYPES_POLICY === null) {
1956
+ trustedTypesPolicy = void 0;
1957
+ emptyHTML = "";
1958
+ } else {
1959
+ if (trustedTypesPolicy === void 0) {
1960
+ trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
1961
+ }
1962
+ if (trustedTypesPolicy && typeof emptyHTML === "string") {
1963
+ emptyHTML = _createTrustedHTML("");
1964
+ }
1965
+ }
1966
+ if (freeze) {
1967
+ freeze(cfg);
1968
+ }
1969
+ CONFIG = cfg;
1970
+ };
1971
+ const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
1972
+ const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
1973
+ const _checkSvgNamespace = function _checkSvgNamespace2(tagName, parent, parentTagName) {
1974
+ if (parent.namespaceURI === HTML_NAMESPACE) {
1975
+ return tagName === "svg";
1976
+ }
1977
+ if (parent.namespaceURI === MATHML_NAMESPACE) {
1978
+ return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
1979
+ }
1980
+ return Boolean(ALL_SVG_TAGS[tagName]);
1981
+ };
1982
+ const _checkMathMlNamespace = function _checkMathMlNamespace2(tagName, parent, parentTagName) {
1983
+ if (parent.namespaceURI === HTML_NAMESPACE) {
1984
+ return tagName === "math";
1985
+ }
1986
+ if (parent.namespaceURI === SVG_NAMESPACE) {
1987
+ return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
1988
+ }
1989
+ return Boolean(ALL_MATHML_TAGS[tagName]);
1990
+ };
1991
+ const _checkHtmlNamespace = function _checkHtmlNamespace2(tagName, parent, parentTagName) {
1992
+ if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
1993
+ return false;
1994
+ }
1995
+ if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
1996
+ return false;
1997
+ }
1998
+ return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
1999
+ };
2000
+ const _checkValidNamespace = function _checkValidNamespace2(element) {
2001
+ let parent = getParentNode(element);
2002
+ if (!parent || !parent.tagName) {
2003
+ parent = {
2004
+ namespaceURI: NAMESPACE,
2005
+ tagName: "template"
2006
+ };
2007
+ }
2008
+ const tagName = stringToLowerCase(element.tagName);
2009
+ const parentTagName = stringToLowerCase(parent.tagName);
2010
+ if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
2011
+ return false;
2012
+ }
2013
+ if (element.namespaceURI === SVG_NAMESPACE) {
2014
+ return _checkSvgNamespace(tagName, parent, parentTagName);
2015
+ }
2016
+ if (element.namespaceURI === MATHML_NAMESPACE) {
2017
+ return _checkMathMlNamespace(tagName, parent, parentTagName);
2018
+ }
2019
+ if (element.namespaceURI === HTML_NAMESPACE) {
2020
+ return _checkHtmlNamespace(tagName, parent, parentTagName);
2021
+ }
2022
+ if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
2023
+ return true;
2024
+ }
2025
+ return false;
2026
+ };
2027
+ const _forceRemove = function _forceRemove2(node) {
2028
+ arrayPush(DOMPurify.removed, {
2029
+ element: node
2030
+ });
2031
+ try {
2032
+ getParentNode(node).removeChild(node);
2033
+ } catch (_2) {
2034
+ remove(node);
2035
+ if (!getParentNode(node)) {
2036
+ throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
2037
+ }
2038
+ }
2039
+ };
2040
+ const _neutralizeRoot = function _neutralizeRoot2(root) {
2041
+ const childNodes = getChildNodes(root);
2042
+ if (childNodes) {
2043
+ const snapshot = [];
2044
+ arrayForEach(childNodes, (child) => {
2045
+ arrayPush(snapshot, child);
2046
+ });
2047
+ arrayForEach(snapshot, (child) => {
2048
+ try {
2049
+ remove(child);
2050
+ } catch (_2) {
2051
+ }
2052
+ });
2053
+ }
2054
+ const attributes = getAttributes(root);
2055
+ if (attributes) {
2056
+ for (let i = attributes.length - 1; i >= 0; --i) {
2057
+ const attribute = attributes[i];
2058
+ const name = attribute && attribute.name;
2059
+ if (typeof name === "string") {
2060
+ try {
2061
+ root.removeAttribute(name);
2062
+ } catch (_2) {
2063
+ }
2064
+ }
2065
+ }
2066
+ }
2067
+ };
2068
+ const _removeAttribute = function _removeAttribute2(name, element) {
2069
+ try {
2070
+ arrayPush(DOMPurify.removed, {
2071
+ attribute: element.getAttributeNode(name),
2072
+ from: element
2073
+ });
2074
+ } catch (_2) {
2075
+ arrayPush(DOMPurify.removed, {
2076
+ attribute: null,
2077
+ from: element
2078
+ });
2079
+ }
2080
+ element.removeAttribute(name);
2081
+ if (name === "is") {
2082
+ if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
2083
+ try {
2084
+ _forceRemove(element);
2085
+ } catch (_2) {
2086
+ }
2087
+ } else {
2088
+ try {
2089
+ element.setAttribute(name, "");
2090
+ } catch (_2) {
2091
+ }
2092
+ }
2093
+ }
2094
+ };
2095
+ const _stripDisallowedAttributes = function _stripDisallowedAttributes2(element) {
2096
+ const attributes = getAttributes(element);
2097
+ if (!attributes) {
2098
+ return;
2099
+ }
2100
+ for (let i = attributes.length - 1; i >= 0; --i) {
2101
+ const attribute = attributes[i];
2102
+ const name = attribute && attribute.name;
2103
+ if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) {
2104
+ continue;
2105
+ }
2106
+ try {
2107
+ element.removeAttribute(name);
2108
+ } catch (_2) {
2109
+ }
2110
+ }
2111
+ };
2112
+ const _neutralizeSubtree = function _neutralizeSubtree2(root) {
2113
+ const stack = [root];
2114
+ while (stack.length > 0) {
2115
+ const node = stack.pop();
2116
+ const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
2117
+ if (nodeType === NODE_TYPE.element) {
2118
+ _stripDisallowedAttributes(node);
2119
+ }
2120
+ const childNodes = getChildNodes(node);
2121
+ if (childNodes) {
2122
+ for (let i = childNodes.length - 1; i >= 0; --i) {
2123
+ stack.push(childNodes[i]);
2124
+ }
2125
+ }
2126
+ }
2127
+ };
2128
+ const _initDocument = function _initDocument2(dirty) {
2129
+ let doc = null;
2130
+ let leadingWhitespace = null;
2131
+ if (FORCE_BODY) {
2132
+ dirty = "<remove></remove>" + dirty;
2133
+ } else {
2134
+ const matches = stringMatch(dirty, /^[\r\n\t ]+/);
2135
+ leadingWhitespace = matches && matches[0];
2136
+ }
2137
+ if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
2138
+ dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
2139
+ }
2140
+ const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
2141
+ if (NAMESPACE === HTML_NAMESPACE) {
2142
+ try {
2143
+ doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
2144
+ } catch (_2) {
2145
+ }
2146
+ }
2147
+ if (!doc || !doc.documentElement) {
2148
+ doc = implementation.createDocument(NAMESPACE, "template", null);
2149
+ try {
2150
+ doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
2151
+ } catch (_2) {
2152
+ }
2153
+ }
2154
+ const body = doc.body || doc.documentElement;
2155
+ if (dirty && leadingWhitespace) {
2156
+ body.insertBefore(document2.createTextNode(leadingWhitespace), body.childNodes[0] || null);
2157
+ }
2158
+ if (NAMESPACE === HTML_NAMESPACE) {
2159
+ return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
2160
+ }
2161
+ return WHOLE_DOCUMENT ? doc.documentElement : body;
2162
+ };
2163
+ const _createNodeIterator = function _createNodeIterator2(root) {
2164
+ return createNodeIterator.call(
2165
+ root.ownerDocument || root,
2166
+ root,
2167
+ // eslint-disable-next-line no-bitwise
2168
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION,
2169
+ null
2170
+ );
2171
+ };
2172
+ const _stripTemplateExpressions = function _stripTemplateExpressions2(value) {
2173
+ value = stringReplace(value, MUSTACHE_EXPR$1, " ");
2174
+ value = stringReplace(value, ERB_EXPR$1, " ");
2175
+ value = stringReplace(value, TMPLIT_EXPR$1, " ");
2176
+ return value;
2177
+ };
2178
+ const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
2179
+ var _node$querySelectorAl;
2180
+ node.normalize();
2181
+ const walker = createNodeIterator.call(
2182
+ node.ownerDocument || node,
2183
+ node,
2184
+ // eslint-disable-next-line no-bitwise
2185
+ NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION,
2186
+ null
2187
+ );
2188
+ let currentNode = walker.nextNode();
2189
+ while (currentNode) {
2190
+ currentNode.data = _stripTemplateExpressions(currentNode.data);
2191
+ currentNode = walker.nextNode();
2192
+ }
2193
+ const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
2194
+ if (templates) {
2195
+ arrayForEach(templates, (tmpl) => {
2196
+ if (_isDocumentFragment(tmpl.content)) {
2197
+ _scrubTemplateExpressions2(tmpl.content);
2198
+ }
2199
+ });
2200
+ }
2201
+ };
2202
+ const _isClobbered = function _isClobbered2(element) {
2203
+ const realTagName = getNodeName ? getNodeName(element) : null;
2204
+ if (typeof realTagName !== "string") {
2205
+ return false;
2206
+ }
2207
+ if (transformCaseFunc(realTagName) !== "form") {
2208
+ return false;
2209
+ }
2210
+ return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || // Realm-safe NamedNodeMap detection: equality against the cached
2211
+ // prototype getter. Clobbered .attributes (e.g. <input name="attributes">)
2212
+ // makes the direct read diverge from the cached read; a clean form
2213
+ // (same-realm OR foreign-realm) has both reads pointing at the same
2214
+ // canonical NamedNodeMap.
2215
+ element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "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
2216
+ // returns the integer 1 for any Element regardless of realm; direct
2217
+ // read on a clobbered form (e.g. <input name="nodeType">) returns
2218
+ // the named child element. Cheap addition — nodeType is read from
2219
+ // an internal slot, no serialization cost — and removes a residual
2220
+ // clobbering surface used by several mXSS / PI / comment branches
2221
+ // in _sanitizeElements that compare currentNode.nodeType directly.
2222
+ element.nodeType !== getNodeType(element) || // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
2223
+ // "childNodes" shadows the prototype getter. Direct reads of
2224
+ // form.childNodes from a clobbered form return the named child
2225
+ // instead of the real NodeList, so any walk that reads it directly
2226
+ // skips the form's real children. Compare the direct read to the
2227
+ // cached Node.prototype getter — when the form's named-property
2228
+ // getter intercepts the read, the two values differ and we flag
2229
+ // the form. This catches every clobbering child type (input,
2230
+ // select, etc.) regardless of whether the named child happens to
2231
+ // carry a numeric .length, which a typeof-based probe would miss
2232
+ // (e.g. HTMLSelectElement.length is a defined unsigned-long).
2233
+ element.childNodes !== getChildNodes(element);
2234
+ };
2235
+ const _isDocumentFragment = function _isDocumentFragment2(value) {
2236
+ if (!getNodeType || typeof value !== "object" || value === null) {
2237
+ return false;
2238
+ }
2239
+ try {
2240
+ return getNodeType(value) === NODE_TYPE.documentFragment;
2241
+ } catch (_2) {
2242
+ return false;
2243
+ }
2244
+ };
2245
+ const _isNode = function _isNode2(value) {
2246
+ if (!getNodeType || typeof value !== "object" || value === null) {
2247
+ return false;
2248
+ }
2249
+ try {
2250
+ return typeof getNodeType(value) === "number";
2251
+ } catch (_2) {
2252
+ return false;
2253
+ }
2254
+ };
2255
+ function _executeHooks(hooks2, currentNode, data) {
2256
+ if (hooks2.length === 0) {
2257
+ return;
2258
+ }
2259
+ arrayForEach(hooks2, (hook) => {
2260
+ hook.call(DOMPurify, currentNode, data, CONFIG);
2261
+ });
2262
+ }
2263
+ const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
2264
+ if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
2265
+ return true;
2266
+ }
2267
+ if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
2268
+ return true;
2269
+ }
2270
+ if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
2271
+ return true;
2272
+ }
2273
+ if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
2274
+ return true;
2275
+ }
2276
+ return false;
2277
+ };
2278
+ const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName) {
2279
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
2280
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
2281
+ return false;
2282
+ }
2283
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
2284
+ return false;
2285
+ }
2286
+ }
2287
+ if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
2288
+ const parentNode = getParentNode(currentNode);
2289
+ const childNodes = getChildNodes(currentNode);
2290
+ if (childNodes && parentNode) {
2291
+ const childCount = childNodes.length;
2292
+ for (let i = childCount - 1; i >= 0; --i) {
2293
+ const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
2294
+ parentNode.insertBefore(hoisted, getNextSibling(currentNode));
2295
+ }
2296
+ }
2297
+ }
2298
+ _forceRemove(currentNode);
2299
+ return true;
2300
+ };
2301
+ const _sanitizeElements = function _sanitizeElements2(currentNode) {
2302
+ _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
2303
+ if (_isClobbered(currentNode)) {
2304
+ _forceRemove(currentNode);
2305
+ return true;
2306
+ }
2307
+ const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
2308
+ _executeHooks(hooks.uponSanitizeElement, currentNode, {
2309
+ tagName,
2310
+ allowedTags: ALLOWED_TAGS
2311
+ });
2312
+ if (_isUnsafeNode(currentNode, tagName)) {
2313
+ _forceRemove(currentNode);
2314
+ return true;
2315
+ }
2316
+ if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
2317
+ return _sanitizeDisallowedNode(currentNode, tagName);
2318
+ }
2319
+ const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
2320
+ if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
2321
+ _forceRemove(currentNode);
2322
+ return true;
2323
+ }
2324
+ if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
2325
+ _forceRemove(currentNode);
2326
+ return true;
2327
+ }
2328
+ if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
2329
+ const content = _stripTemplateExpressions(currentNode.textContent);
2330
+ if (currentNode.textContent !== content) {
2331
+ arrayPush(DOMPurify.removed, {
2332
+ element: currentNode.cloneNode()
2333
+ });
2334
+ currentNode.textContent = content;
2335
+ }
2336
+ }
2337
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2338
+ return false;
2339
+ };
2340
+ const _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value) {
2341
+ if (FORBID_ATTR[lcName]) {
2342
+ return false;
2343
+ }
2344
+ if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) {
2345
+ return false;
2346
+ }
2347
+ const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
2348
+ if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) ;
2349
+ else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;
2350
+ else if (!nameIsPermitted) {
2351
+ if (
2352
+ // First condition does a very basic check if a) it's basically a valid custom element tagname AND
2353
+ // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
2354
+ // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
2355
+ _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || // Alternative, second condition checks if it's an `is`-attribute, AND
2356
+ // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
2357
+ lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))
2358
+ ) ;
2359
+ else {
2360
+ return false;
2361
+ }
2362
+ } else if (URI_SAFE_ATTRIBUTES[lcName]) ;
2363
+ else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ;
2364
+ else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) ;
2365
+ else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ;
2366
+ else if (value) {
2367
+ return false;
2368
+ } else ;
2369
+ return true;
2370
+ };
2371
+ 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"]);
2372
+ const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
2373
+ return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
2374
+ };
2375
+ const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute2(lcTag, lcName, namespaceURI, value) {
2376
+ if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) {
2377
+ switch (trustedTypes.getAttributeType(lcTag, lcName)) {
2378
+ case "TrustedHTML": {
2379
+ return _createTrustedHTML(value);
2380
+ }
2381
+ case "TrustedScriptURL": {
2382
+ return _createTrustedScriptURL(value);
2383
+ }
2384
+ }
2385
+ }
2386
+ return value;
2387
+ };
2388
+ const _setAttributeValue = function _setAttributeValue2(currentNode, name, namespaceURI, value) {
2389
+ try {
2390
+ if (namespaceURI) {
2391
+ currentNode.setAttributeNS(namespaceURI, name, value);
2392
+ } else {
2393
+ currentNode.setAttribute(name, value);
2394
+ }
2395
+ if (_isClobbered(currentNode)) {
2396
+ _forceRemove(currentNode);
2397
+ } else {
2398
+ arrayPop(DOMPurify.removed);
2399
+ }
2400
+ } catch (_2) {
2401
+ _removeAttribute(name, currentNode);
2402
+ }
2403
+ };
2404
+ const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
2405
+ _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
2406
+ const attributes = currentNode.attributes;
2407
+ if (!attributes || _isClobbered(currentNode)) {
2408
+ return;
2409
+ }
2410
+ const hookEvent = {
2411
+ attrName: "",
2412
+ attrValue: "",
2413
+ keepAttr: true,
2414
+ allowedAttributes: ALLOWED_ATTR,
2415
+ forceKeepAttr: void 0
2416
+ };
2417
+ let l3 = attributes.length;
2418
+ const lcTag = transformCaseFunc(currentNode.nodeName);
2419
+ while (l3--) {
2420
+ const attr = attributes[l3];
2421
+ const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
2422
+ const lcName = transformCaseFunc(name);
2423
+ const initValue = attrValue;
2424
+ let value = name === "value" ? initValue : stringTrim(initValue);
2425
+ hookEvent.attrName = lcName;
2426
+ hookEvent.attrValue = value;
2427
+ hookEvent.keepAttr = true;
2428
+ hookEvent.forceKeepAttr = void 0;
2429
+ _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
2430
+ value = hookEvent.attrValue;
2431
+ if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
2432
+ _removeAttribute(name, currentNode);
2433
+ value = SANITIZE_NAMED_PROPS_PREFIX + value;
2434
+ }
2435
+ if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
2436
+ _removeAttribute(name, currentNode);
2437
+ continue;
2438
+ }
2439
+ if (lcName === "attributename" && stringMatch(value, "href")) {
2440
+ _removeAttribute(name, currentNode);
2441
+ continue;
2442
+ }
2443
+ if (hookEvent.forceKeepAttr) {
2444
+ continue;
2445
+ }
2446
+ if (!hookEvent.keepAttr) {
2447
+ _removeAttribute(name, currentNode);
2448
+ continue;
2449
+ }
2450
+ if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
2451
+ _removeAttribute(name, currentNode);
2452
+ continue;
2453
+ }
2454
+ if (SAFE_FOR_TEMPLATES) {
2455
+ value = _stripTemplateExpressions(value);
2456
+ }
2457
+ if (!_isValidAttribute(lcTag, lcName, value)) {
2458
+ _removeAttribute(name, currentNode);
2459
+ continue;
2460
+ }
2461
+ value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
2462
+ if (value !== initValue) {
2463
+ _setAttributeValue(currentNode, name, namespaceURI, value);
2464
+ }
2465
+ }
2466
+ _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
2467
+ };
2468
+ const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
2469
+ let shadowNode = null;
2470
+ const shadowIterator = _createNodeIterator(fragment);
2471
+ _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
2472
+ while (shadowNode = shadowIterator.nextNode()) {
2473
+ _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
2474
+ _sanitizeElements(shadowNode);
2475
+ _sanitizeAttributes(shadowNode);
2476
+ if (_isDocumentFragment(shadowNode.content)) {
2477
+ _sanitizeShadowDOM2(shadowNode.content);
2478
+ }
2479
+ const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
2480
+ if (shadowNodeType === NODE_TYPE.element) {
2481
+ const innerSr = getShadowRoot(shadowNode);
2482
+ if (_isDocumentFragment(innerSr)) {
2483
+ _sanitizeAttachedShadowRoots(innerSr);
2484
+ _sanitizeShadowDOM2(innerSr);
2485
+ }
2486
+ }
2487
+ }
2488
+ _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
2489
+ };
2490
+ const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots2(root) {
2491
+ const stack = [{
2492
+ node: root,
2493
+ shadow: null
2494
+ }];
2495
+ while (stack.length > 0) {
2496
+ const item = stack.pop();
2497
+ if (item.shadow) {
2498
+ _sanitizeShadowDOM2(item.shadow);
2499
+ continue;
2500
+ }
2501
+ const node = item.node;
2502
+ const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
2503
+ const isElement = nodeType === NODE_TYPE.element;
2504
+ const childNodes = getChildNodes(node);
2505
+ if (childNodes) {
2506
+ for (let i = childNodes.length - 1; i >= 0; --i) {
2507
+ stack.push({
2508
+ node: childNodes[i],
2509
+ shadow: null
2510
+ });
2511
+ }
2512
+ }
2513
+ if (isElement) {
2514
+ const rootName = getNodeName ? getNodeName(node) : null;
2515
+ if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
2516
+ const content = node.content;
2517
+ if (_isDocumentFragment(content)) {
2518
+ stack.push({
2519
+ node: content,
2520
+ shadow: null
2521
+ });
2522
+ }
2523
+ }
2524
+ }
2525
+ if (isElement) {
2526
+ const sr = getShadowRoot(node);
2527
+ if (_isDocumentFragment(sr)) {
2528
+ stack.push({
2529
+ node: null,
2530
+ shadow: sr
2531
+ }, {
2532
+ node: sr,
2533
+ shadow: null
2534
+ });
2535
+ }
2536
+ }
2537
+ }
2538
+ };
2539
+ DOMPurify.sanitize = function(dirty) {
2540
+ let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
2541
+ let body = null;
2542
+ let importedNode = null;
2543
+ let currentNode = null;
2544
+ let returnNode = null;
2545
+ IS_EMPTY_INPUT = !dirty;
2546
+ if (IS_EMPTY_INPUT) {
2547
+ dirty = "<!-->";
2548
+ }
2549
+ if (typeof dirty !== "string" && !_isNode(dirty)) {
2550
+ dirty = stringifyValue(dirty);
2551
+ if (typeof dirty !== "string") {
2552
+ throw typeErrorCreate("dirty is not a string, aborting");
2553
+ }
2554
+ }
2555
+ if (!DOMPurify.isSupported) {
2556
+ return dirty;
2557
+ }
2558
+ if (SET_CONFIG) {
2559
+ ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
2560
+ ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
2561
+ } else {
2562
+ _parseConfig(cfg);
2563
+ }
2564
+ if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) {
2565
+ ALLOWED_TAGS = clone(ALLOWED_TAGS);
2566
+ }
2567
+ if (hooks.uponSanitizeAttribute.length > 0) {
2568
+ ALLOWED_ATTR = clone(ALLOWED_ATTR);
2569
+ }
2570
+ DOMPurify.removed = [];
2571
+ const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
2572
+ if (inPlace) {
2573
+ const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
2574
+ if (typeof nn === "string") {
2575
+ const tagName = transformCaseFunc(nn);
2576
+ if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
2577
+ throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
2578
+ }
2579
+ }
2580
+ if (_isClobbered(dirty)) {
2581
+ throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
2582
+ }
2583
+ try {
2584
+ _sanitizeAttachedShadowRoots(dirty);
2585
+ } catch (error) {
2586
+ _neutralizeRoot(dirty);
2587
+ throw error;
2588
+ }
2589
+ } else if (_isNode(dirty)) {
2590
+ body = _initDocument("<!---->");
2591
+ importedNode = body.ownerDocument.importNode(dirty, true);
2592
+ if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") {
2593
+ body = importedNode;
2594
+ } else if (importedNode.nodeName === "HTML") {
2595
+ body = importedNode;
2596
+ } else {
2597
+ body.appendChild(importedNode);
2598
+ }
2599
+ _sanitizeAttachedShadowRoots(importedNode);
2600
+ } else {
2601
+ if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
2602
+ dirty.indexOf("<") === -1) {
2603
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
2604
+ }
2605
+ body = _initDocument(dirty);
2606
+ if (!body) {
2607
+ return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
2608
+ }
2609
+ }
2610
+ if (body && FORCE_BODY) {
2611
+ _forceRemove(body.firstChild);
2612
+ }
2613
+ const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
2614
+ try {
2615
+ while (currentNode = nodeIterator.nextNode()) {
2616
+ _sanitizeElements(currentNode);
2617
+ _sanitizeAttributes(currentNode);
2618
+ if (_isDocumentFragment(currentNode.content)) {
2619
+ _sanitizeShadowDOM2(currentNode.content);
2620
+ }
2621
+ }
2622
+ } catch (error) {
2623
+ if (inPlace) {
2624
+ _neutralizeRoot(dirty);
2625
+ }
2626
+ throw error;
2627
+ }
2628
+ if (inPlace) {
2629
+ arrayForEach(DOMPurify.removed, (entry) => {
2630
+ if (entry.element) {
2631
+ _neutralizeSubtree(entry.element);
2632
+ }
2633
+ });
2634
+ if (SAFE_FOR_TEMPLATES) {
2635
+ _scrubTemplateExpressions2(dirty);
2636
+ }
2637
+ return dirty;
2638
+ }
2639
+ if (RETURN_DOM) {
2640
+ if (SAFE_FOR_TEMPLATES) {
2641
+ _scrubTemplateExpressions2(body);
2642
+ }
2643
+ if (RETURN_DOM_FRAGMENT) {
2644
+ returnNode = createDocumentFragment.call(body.ownerDocument);
2645
+ while (body.firstChild) {
2646
+ returnNode.appendChild(body.firstChild);
2647
+ }
2648
+ } else {
2649
+ returnNode = body;
2650
+ }
2651
+ if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
2652
+ returnNode = importNode.call(originalDocument, returnNode, true);
2653
+ }
2654
+ return returnNode;
2655
+ }
2656
+ let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
2657
+ if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
2658
+ serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
2659
+ }
2660
+ if (SAFE_FOR_TEMPLATES) {
2661
+ serializedHTML = _stripTemplateExpressions(serializedHTML);
2662
+ }
2663
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
2664
+ };
2665
+ DOMPurify.setConfig = function() {
2666
+ let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
2667
+ _parseConfig(cfg);
2668
+ SET_CONFIG = true;
2669
+ SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
2670
+ SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
2671
+ };
2672
+ DOMPurify.clearConfig = function() {
2673
+ CONFIG = null;
2674
+ SET_CONFIG = false;
2675
+ SET_CONFIG_ALLOWED_TAGS = null;
2676
+ SET_CONFIG_ALLOWED_ATTR = null;
2677
+ trustedTypesPolicy = defaultTrustedTypesPolicy;
2678
+ emptyHTML = "";
2679
+ };
2680
+ DOMPurify.isValidAttribute = function(tag, attr, value) {
2681
+ if (!CONFIG) {
2682
+ _parseConfig({});
2683
+ }
2684
+ const lcTag = transformCaseFunc(tag);
2685
+ const lcName = transformCaseFunc(attr);
2686
+ return _isValidAttribute(lcTag, lcName, value);
2687
+ };
2688
+ DOMPurify.addHook = function(entryPoint, hookFunction) {
2689
+ if (typeof hookFunction !== "function") {
2690
+ return;
2691
+ }
2692
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
2693
+ return;
2694
+ }
2695
+ arrayPush(hooks[entryPoint], hookFunction);
2696
+ };
2697
+ DOMPurify.removeHook = function(entryPoint, hookFunction) {
2698
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
2699
+ return void 0;
2700
+ }
2701
+ if (hookFunction !== void 0) {
2702
+ const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
2703
+ return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
2704
+ }
2705
+ return arrayPop(hooks[entryPoint]);
2706
+ };
2707
+ DOMPurify.removeHooks = function(entryPoint) {
2708
+ if (!objectHasOwnProperty(hooks, entryPoint)) {
2709
+ return;
2710
+ }
2711
+ hooks[entryPoint] = [];
2712
+ };
2713
+ DOMPurify.removeAllHooks = function() {
2714
+ hooks = _createHooksMap();
2715
+ };
2716
+ return DOMPurify;
2717
+ }
2718
+ var purify = createDOMPurify();
2719
+
2720
+ // ../../node_modules/.pnpm/marked@16.4.2/node_modules/marked/lib/marked.esm.js
2721
+ function L() {
2722
+ return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
2723
+ }
2724
+ var T = L();
2725
+ function G(l3) {
2726
+ T = l3;
2727
+ }
2728
+ var E = { exec: () => null };
2729
+ function d(l3, e = "") {
2730
+ let t = typeof l3 == "string" ? l3 : l3.source, n = { replace: (r, i) => {
2731
+ let s = typeof i == "string" ? i : i.source;
2732
+ return s = s.replace(m.caret, "$1"), t = t.replace(r, s), n;
2733
+ }, getRegex: () => new RegExp(t, e) };
2734
+ return n;
2735
+ }
2736
+ var be = (() => {
2737
+ try {
2738
+ return !!new RegExp("(?<=1)(?<!1)");
2739
+ } catch {
2740
+ return false;
2741
+ }
2742
+ })();
2743
+ var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, 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, listReplaceTabs: /^\t+/, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] /, listReplaceTask: /^\[[ 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, unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (l3) => new RegExp(`^( {0,3}${l3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}#`), htmlBeginRegex: (l3) => new RegExp(`^ {0,${Math.min(3, l3 - 1)}}<(?:[a-z].*>|!--)`, "i") };
2744
+ var Re = /^(?:[ \t]*(?:\n|$))+/;
2745
+ var Te = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
2746
+ var Oe = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
2747
+ var I = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
2748
+ var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
2749
+ var F = /(?:[*+-]|\d{1,9}[.)])/;
2750
+ var ie = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
2751
+ var oe = d(ie).replace(/bull/g, F).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}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
2752
+ var ye = d(ie).replace(/bull/g, F).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}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
2753
+ var j = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
2754
+ var Pe = /^[^\n]+/;
2755
+ var Q = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
2756
+ var Se = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", Q).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
2757
+ var $e = d(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, F).getRegex();
2758
+ var v = "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";
2759
+ var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
2760
+ var _e = d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", U).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
2761
+ var ae = d(j).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
2762
+ var Le = d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", ae).getRegex();
2763
+ var K = { blockquote: Le, code: Te, def: Se, fences: Oe, heading: we, hr: I, html: _e, lheading: oe, list: $e, newline: Re, paragraph: ae, table: E, text: Pe };
2764
+ var re = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
2765
+ var Me = { ...K, lheading: ye, table: re, paragraph: d(j).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", re).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
2766
+ var ze = { ...K, html: d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", U).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: d(j).replace("hr", I).replace("heading", ` *#{1,6} *[^
2767
+ ]`).replace("lheading", oe).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
2768
+ var Ae = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
2769
+ var Ee = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
2770
+ var le = /^( {2,}|\\)\n(?!\s*$)/;
2771
+ var Ie = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
2772
+ var D = /[\p{P}\p{S}]/u;
2773
+ var W = /[\s\p{P}\p{S}]/u;
2774
+ var ue = /[^\s\p{P}\p{S}]/u;
2775
+ var Ce = d(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, W).getRegex();
2776
+ var pe = /(?!~)[\p{P}\p{S}]/u;
2777
+ var Be = /(?!~)[\s\p{P}\p{S}]/u;
2778
+ var qe = /(?:[^\s\p{P}\p{S}]|~)/u;
2779
+ var ve = d(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", be ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
2780
+ var ce = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
2781
+ var De = d(ce, "u").replace(/punct/g, D).getRegex();
2782
+ var He = d(ce, "u").replace(/punct/g, pe).getRegex();
2783
+ var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
2784
+ var Ze = d(he, "gu").replace(/notPunctSpace/g, ue).replace(/punctSpace/g, W).replace(/punct/g, D).getRegex();
2785
+ var Ge = d(he, "gu").replace(/notPunctSpace/g, qe).replace(/punctSpace/g, Be).replace(/punct/g, pe).getRegex();
2786
+ var Ne = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, ue).replace(/punctSpace/g, W).replace(/punct/g, D).getRegex();
2787
+ var Fe = d(/\\(punct)/, "gu").replace(/punct/g, D).getRegex();
2788
+ var je = d(/^<(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();
2789
+ var Qe = d(U).replace("(?:-->|$)", "-->").getRegex();
2790
+ var Ue = d("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Qe).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
2791
+ var q = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/;
2792
+ var Ke = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
2793
+ var de = d(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", Q).getRegex();
2794
+ var ke = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", Q).getRegex();
2795
+ var We = d("reflink|nolink(?!\\()", "g").replace("reflink", de).replace("nolink", ke).getRegex();
2796
+ var se = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
2797
+ var X = { _backpedal: E, anyPunctuation: Fe, autolink: je, blockSkip: ve, br: le, code: Ee, del: E, emStrongLDelim: De, emStrongRDelimAst: Ze, emStrongRDelimUnd: Ne, escape: Ae, link: Ke, nolink: ke, punctuation: Ce, reflink: de, reflinkSearch: We, tag: Ue, text: Ie, url: E };
2798
+ var Xe = { ...X, link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
2799
+ var N = { ...X, emStrongRDelimAst: Ge, emStrongLDelim: He, url: d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", se).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: d(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", se).getRegex() };
2800
+ var Je = { ...N, br: d(le).replace("{2,}", "*").getRegex(), text: d(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
2801
+ var C = { normal: K, gfm: Me, pedantic: ze };
2802
+ var M = { normal: X, gfm: N, breaks: Je, pedantic: Xe };
2803
+ var Ve = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
2804
+ var ge = (l3) => Ve[l3];
2805
+ function w(l3, e) {
2806
+ if (e) {
2807
+ if (m.escapeTest.test(l3)) return l3.replace(m.escapeReplace, ge);
2808
+ } else if (m.escapeTestNoEncode.test(l3)) return l3.replace(m.escapeReplaceNoEncode, ge);
2809
+ return l3;
2810
+ }
2811
+ function J(l3) {
2812
+ try {
2813
+ l3 = encodeURI(l3).replace(m.percentDecode, "%");
2814
+ } catch {
2815
+ return null;
2816
+ }
2817
+ return l3;
2818
+ }
2819
+ function V(l3, e) {
2820
+ let t = l3.replace(m.findPipe, (i, s, a) => {
2821
+ let o = false, p = s;
2822
+ for (; --p >= 0 && a[p] === "\\"; ) o = !o;
2823
+ return o ? "|" : " |";
2824
+ }), n = t.split(m.splitPipe), r = 0;
2825
+ if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
2826
+ else for (; n.length < e; ) n.push("");
2827
+ for (; r < n.length; r++) n[r] = n[r].trim().replace(m.slashPipe, "|");
2828
+ return n;
2829
+ }
2830
+ function z(l3, e, t) {
2831
+ let n = l3.length;
2832
+ if (n === 0) return "";
2833
+ let r = 0;
2834
+ for (; r < n; ) {
2835
+ let i = l3.charAt(n - r - 1);
2836
+ if (i === e && !t) r++;
2837
+ else if (i !== e && t) r++;
2838
+ else break;
2839
+ }
2840
+ return l3.slice(0, n - r);
2841
+ }
2842
+ function fe(l3, e) {
2843
+ if (l3.indexOf(e[1]) === -1) return -1;
2844
+ let t = 0;
2845
+ for (let n = 0; n < l3.length; n++) if (l3[n] === "\\") n++;
2846
+ else if (l3[n] === e[0]) t++;
2847
+ else if (l3[n] === e[1] && (t--, t < 0)) return n;
2848
+ return t > 0 ? -2 : -1;
2849
+ }
2850
+ function me(l3, e, t, n, r) {
2851
+ let i = e.href, s = e.title || null, a = l3[1].replace(r.other.outputLinkReplace, "$1");
2852
+ n.state.inLink = true;
2853
+ let o = { type: l3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: s, text: a, tokens: n.inlineTokens(a) };
2854
+ return n.state.inLink = false, o;
2855
+ }
2856
+ function Ye(l3, e, t) {
2857
+ let n = l3.match(t.other.indentCodeCompensation);
2858
+ if (n === null) return e;
2859
+ let r = n[1];
2860
+ return e.split(`
2861
+ `).map((i) => {
2862
+ let s = i.match(t.other.beginningSpace);
2863
+ if (s === null) return i;
2864
+ let [a] = s;
2865
+ return a.length >= r.length ? i.slice(r.length) : i;
2866
+ }).join(`
2867
+ `);
2868
+ }
2869
+ var y = class {
2870
+ options;
2871
+ rules;
2872
+ lexer;
2873
+ constructor(e) {
2874
+ this.options = e || T;
2875
+ }
2876
+ space(e) {
2877
+ let t = this.rules.block.newline.exec(e);
2878
+ if (t && t[0].length > 0) return { type: "space", raw: t[0] };
2879
+ }
2880
+ code(e) {
2881
+ let t = this.rules.block.code.exec(e);
2882
+ if (t) {
2883
+ let n = t[0].replace(this.rules.other.codeRemoveIndent, "");
2884
+ return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : z(n, `
2885
+ `) };
2886
+ }
2887
+ }
2888
+ fences(e) {
2889
+ let t = this.rules.block.fences.exec(e);
2890
+ if (t) {
2891
+ let n = t[0], r = Ye(n, t[3] || "", this.rules);
2892
+ return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: r };
2893
+ }
2894
+ }
2895
+ heading(e) {
2896
+ let t = this.rules.block.heading.exec(e);
2897
+ if (t) {
2898
+ let n = t[2].trim();
2899
+ if (this.rules.other.endingHash.test(n)) {
2900
+ let r = z(n, "#");
2901
+ (this.options.pedantic || !r || this.rules.other.endingSpaceChar.test(r)) && (n = r.trim());
2902
+ }
2903
+ return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
2904
+ }
2905
+ }
2906
+ hr(e) {
2907
+ let t = this.rules.block.hr.exec(e);
2908
+ if (t) return { type: "hr", raw: z(t[0], `
2909
+ `) };
2910
+ }
2911
+ blockquote(e) {
2912
+ let t = this.rules.block.blockquote.exec(e);
2913
+ if (t) {
2914
+ let n = z(t[0], `
2915
+ `).split(`
2916
+ `), r = "", i = "", s = [];
2917
+ for (; n.length > 0; ) {
2918
+ let a = false, o = [], p;
2919
+ for (p = 0; p < n.length; p++) if (this.rules.other.blockquoteStart.test(n[p])) o.push(n[p]), a = true;
2920
+ else if (!a) o.push(n[p]);
2921
+ else break;
2922
+ n = n.slice(p);
2923
+ let u = o.join(`
2924
+ `), c = u.replace(this.rules.other.blockquoteSetextReplace, `
2925
+ $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
2926
+ r = r ? `${r}
2927
+ ${u}` : u, i = i ? `${i}
2928
+ ${c}` : c;
2929
+ let g = this.lexer.state.top;
2930
+ if (this.lexer.state.top = true, this.lexer.blockTokens(c, s, true), this.lexer.state.top = g, n.length === 0) break;
2931
+ let h = s.at(-1);
2932
+ if (h?.type === "code") break;
2933
+ if (h?.type === "blockquote") {
2934
+ let R = h, f = R.raw + `
2935
+ ` + n.join(`
2936
+ `), O = this.blockquote(f);
2937
+ s[s.length - 1] = O, r = r.substring(0, r.length - R.raw.length) + O.raw, i = i.substring(0, i.length - R.text.length) + O.text;
2938
+ break;
2939
+ } else if (h?.type === "list") {
2940
+ let R = h, f = R.raw + `
2941
+ ` + n.join(`
2942
+ `), O = this.list(f);
2943
+ s[s.length - 1] = O, r = r.substring(0, r.length - h.raw.length) + O.raw, i = i.substring(0, i.length - R.raw.length) + O.raw, n = f.substring(s.at(-1).raw.length).split(`
2944
+ `);
2945
+ continue;
2946
+ }
2947
+ }
2948
+ return { type: "blockquote", raw: r, tokens: s, text: i };
2949
+ }
2950
+ }
2951
+ list(e) {
2952
+ let t = this.rules.block.list.exec(e);
2953
+ if (t) {
2954
+ let n = t[1].trim(), r = n.length > 1, i = { type: "list", raw: "", ordered: r, start: r ? +n.slice(0, -1) : "", loose: false, items: [] };
2955
+ n = r ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = r ? n : "[*+-]");
2956
+ let s = this.rules.other.listItemRegex(n), a = false;
2957
+ for (; e; ) {
2958
+ let p = false, u = "", c = "";
2959
+ if (!(t = s.exec(e)) || this.rules.block.hr.test(e)) break;
2960
+ u = t[0], e = e.substring(u.length);
2961
+ let g = t[2].split(`
2962
+ `, 1)[0].replace(this.rules.other.listReplaceTabs, (H) => " ".repeat(3 * H.length)), h = e.split(`
2963
+ `, 1)[0], R = !g.trim(), f = 0;
2964
+ if (this.options.pedantic ? (f = 2, c = g.trimStart()) : R ? f = t[1].length + 1 : (f = t[2].search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, c = g.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h) && (u += h + `
2965
+ `, e = e.substring(h.length + 1), p = true), !p) {
2966
+ let H = this.rules.other.nextBulletRegex(f), ee = this.rules.other.hrRegex(f), te = this.rules.other.fencesBeginRegex(f), ne = this.rules.other.headingBeginRegex(f), xe = this.rules.other.htmlBeginRegex(f);
2967
+ for (; e; ) {
2968
+ let Z = e.split(`
2969
+ `, 1)[0], A;
2970
+ if (h = Z, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), A = h) : A = h.replace(this.rules.other.tabCharGlobal, " "), te.test(h) || ne.test(h) || xe.test(h) || H.test(h) || ee.test(h)) break;
2971
+ if (A.search(this.rules.other.nonSpaceChar) >= f || !h.trim()) c += `
2972
+ ` + A.slice(f);
2973
+ else {
2974
+ if (R || g.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || te.test(g) || ne.test(g) || ee.test(g)) break;
2975
+ c += `
2976
+ ` + h;
2977
+ }
2978
+ !R && !h.trim() && (R = true), u += Z + `
2979
+ `, e = e.substring(Z.length + 1), g = A.slice(f);
2980
+ }
2981
+ }
2982
+ i.loose || (a ? i.loose = true : this.rules.other.doubleBlankLine.test(u) && (a = true));
2983
+ let O = null, Y;
2984
+ this.options.gfm && (O = this.rules.other.listIsTask.exec(c), O && (Y = O[0] !== "[ ] ", c = c.replace(this.rules.other.listReplaceTask, ""))), i.items.push({ type: "list_item", raw: u, task: !!O, checked: Y, loose: false, text: c, tokens: [] }), i.raw += u;
2985
+ }
2986
+ let o = i.items.at(-1);
2987
+ if (o) o.raw = o.raw.trimEnd(), o.text = o.text.trimEnd();
2988
+ else return;
2989
+ i.raw = i.raw.trimEnd();
2990
+ for (let p = 0; p < i.items.length; p++) if (this.lexer.state.top = false, i.items[p].tokens = this.lexer.blockTokens(i.items[p].text, []), !i.loose) {
2991
+ let u = i.items[p].tokens.filter((g) => g.type === "space"), c = u.length > 0 && u.some((g) => this.rules.other.anyLine.test(g.raw));
2992
+ i.loose = c;
2993
+ }
2994
+ if (i.loose) for (let p = 0; p < i.items.length; p++) i.items[p].loose = true;
2995
+ return i;
2996
+ }
2997
+ }
2998
+ html(e) {
2999
+ let t = this.rules.block.html.exec(e);
3000
+ if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] };
3001
+ }
3002
+ def(e) {
3003
+ let t = this.rules.block.def.exec(e);
3004
+ if (t) {
3005
+ let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), r = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
3006
+ return { type: "def", tag: n, raw: t[0], href: r, title: i };
3007
+ }
3008
+ }
3009
+ table(e) {
3010
+ let t = this.rules.block.table.exec(e);
3011
+ if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
3012
+ let n = V(t[1]), r = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
3013
+ `) : [], s = { type: "table", raw: t[0], header: [], align: [], rows: [] };
3014
+ if (n.length === r.length) {
3015
+ for (let a of r) this.rules.other.tableAlignRight.test(a) ? s.align.push("right") : this.rules.other.tableAlignCenter.test(a) ? s.align.push("center") : this.rules.other.tableAlignLeft.test(a) ? s.align.push("left") : s.align.push(null);
3016
+ for (let a = 0; a < n.length; a++) s.header.push({ text: n[a], tokens: this.lexer.inline(n[a]), header: true, align: s.align[a] });
3017
+ for (let a of i) s.rows.push(V(a, s.header.length).map((o, p) => ({ text: o, tokens: this.lexer.inline(o), header: false, align: s.align[p] })));
3018
+ return s;
3019
+ }
3020
+ }
3021
+ lheading(e) {
3022
+ let t = this.rules.block.lheading.exec(e);
3023
+ if (t) return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: t[1], tokens: this.lexer.inline(t[1]) };
3024
+ }
3025
+ paragraph(e) {
3026
+ let t = this.rules.block.paragraph.exec(e);
3027
+ if (t) {
3028
+ let n = t[1].charAt(t[1].length - 1) === `
3029
+ ` ? t[1].slice(0, -1) : t[1];
3030
+ return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
3031
+ }
3032
+ }
3033
+ text(e) {
3034
+ let t = this.rules.block.text.exec(e);
3035
+ if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
3036
+ }
3037
+ escape(e) {
3038
+ let t = this.rules.inline.escape.exec(e);
3039
+ if (t) return { type: "escape", raw: t[0], text: t[1] };
3040
+ }
3041
+ tag(e) {
3042
+ let t = this.rules.inline.tag.exec(e);
3043
+ 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] };
3044
+ }
3045
+ link(e) {
3046
+ let t = this.rules.inline.link.exec(e);
3047
+ if (t) {
3048
+ let n = t[2].trim();
3049
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
3050
+ if (!this.rules.other.endAngleBracket.test(n)) return;
3051
+ let s = z(n.slice(0, -1), "\\");
3052
+ if ((n.length - s.length) % 2 === 0) return;
3053
+ } else {
3054
+ let s = fe(t[2], "()");
3055
+ if (s === -2) return;
3056
+ if (s > -1) {
3057
+ let o = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + s;
3058
+ t[2] = t[2].substring(0, s), t[0] = t[0].substring(0, o).trim(), t[3] = "";
3059
+ }
3060
+ }
3061
+ let r = t[2], i = "";
3062
+ if (this.options.pedantic) {
3063
+ let s = this.rules.other.pedanticHrefTitle.exec(r);
3064
+ s && (r = s[1], i = s[3]);
3065
+ } else i = t[3] ? t[3].slice(1, -1) : "";
3066
+ return r = r.trim(), this.rules.other.startAngleBracket.test(r) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? r = r.slice(1) : r = r.slice(1, -1)), me(t, { href: r && r.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
3067
+ }
3068
+ }
3069
+ reflink(e, t) {
3070
+ let n;
3071
+ if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
3072
+ let r = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[r.toLowerCase()];
3073
+ if (!i) {
3074
+ let s = n[0].charAt(0);
3075
+ return { type: "text", raw: s, text: s };
3076
+ }
3077
+ return me(n, i, n[0], this.lexer, this.rules);
3078
+ }
3079
+ }
3080
+ emStrong(e, t, n = "") {
3081
+ let r = this.rules.inline.emStrongLDelim.exec(e);
3082
+ if (!r || r[3] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
3083
+ if (!(r[1] || r[2] || "") || !n || this.rules.inline.punctuation.exec(n)) {
3084
+ let s = [...r[0]].length - 1, a, o, p = s, u = 0, c = r[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
3085
+ for (c.lastIndex = 0, t = t.slice(-1 * e.length + s); (r = c.exec(t)) != null; ) {
3086
+ if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a) continue;
3087
+ if (o = [...a].length, r[3] || r[4]) {
3088
+ p += o;
3089
+ continue;
3090
+ } else if ((r[5] || r[6]) && s % 3 && !((s + o) % 3)) {
3091
+ u += o;
3092
+ continue;
3093
+ }
3094
+ if (p -= o, p > 0) continue;
3095
+ o = Math.min(o, o + p + u);
3096
+ let g = [...r[0]][0].length, h = e.slice(0, s + r.index + g + o);
3097
+ if (Math.min(s, o) % 2) {
3098
+ let f = h.slice(1, -1);
3099
+ return { type: "em", raw: h, text: f, tokens: this.lexer.inlineTokens(f) };
3100
+ }
3101
+ let R = h.slice(2, -2);
3102
+ return { type: "strong", raw: h, text: R, tokens: this.lexer.inlineTokens(R) };
3103
+ }
3104
+ }
3105
+ }
3106
+ codespan(e) {
3107
+ let t = this.rules.inline.code.exec(e);
3108
+ if (t) {
3109
+ let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), r = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
3110
+ return r && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
3111
+ }
3112
+ }
3113
+ br(e) {
3114
+ let t = this.rules.inline.br.exec(e);
3115
+ if (t) return { type: "br", raw: t[0] };
3116
+ }
3117
+ del(e) {
3118
+ let t = this.rules.inline.del.exec(e);
3119
+ if (t) return { type: "del", raw: t[0], text: t[2], tokens: this.lexer.inlineTokens(t[2]) };
3120
+ }
3121
+ autolink(e) {
3122
+ let t = this.rules.inline.autolink.exec(e);
3123
+ if (t) {
3124
+ let n, r;
3125
+ return t[2] === "@" ? (n = t[1], r = "mailto:" + n) : (n = t[1], r = n), { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
3126
+ }
3127
+ }
3128
+ url(e) {
3129
+ let t;
3130
+ if (t = this.rules.inline.url.exec(e)) {
3131
+ let n, r;
3132
+ if (t[2] === "@") n = t[0], r = "mailto:" + n;
3133
+ else {
3134
+ let i;
3135
+ do
3136
+ i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
3137
+ while (i !== t[0]);
3138
+ n = t[0], t[1] === "www." ? r = "http://" + t[0] : r = t[0];
3139
+ }
3140
+ return { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
3141
+ }
3142
+ }
3143
+ inlineText(e) {
3144
+ let t = this.rules.inline.text.exec(e);
3145
+ if (t) {
3146
+ let n = this.lexer.state.inRawBlock;
3147
+ return { type: "text", raw: t[0], text: t[0], escaped: n };
3148
+ }
3149
+ }
3150
+ };
3151
+ var x = class l {
3152
+ tokens;
3153
+ options;
3154
+ state;
3155
+ tokenizer;
3156
+ inlineQueue;
3157
+ constructor(e) {
3158
+ 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, top: true };
3159
+ let t = { other: m, block: C.normal, inline: M.normal };
3160
+ this.options.pedantic ? (t.block = C.pedantic, t.inline = M.pedantic) : this.options.gfm && (t.block = C.gfm, this.options.breaks ? t.inline = M.breaks : t.inline = M.gfm), this.tokenizer.rules = t;
3161
+ }
3162
+ static get rules() {
3163
+ return { block: C, inline: M };
3164
+ }
3165
+ static lex(e, t) {
3166
+ return new l(t).lex(e);
3167
+ }
3168
+ static lexInline(e, t) {
3169
+ return new l(t).inlineTokens(e);
3170
+ }
3171
+ lex(e) {
3172
+ e = e.replace(m.carriageReturn, `
3173
+ `), this.blockTokens(e, this.tokens);
3174
+ for (let t = 0; t < this.inlineQueue.length; t++) {
3175
+ let n = this.inlineQueue[t];
3176
+ this.inlineTokens(n.src, n.tokens);
3177
+ }
3178
+ return this.inlineQueue = [], this.tokens;
3179
+ }
3180
+ blockTokens(e, t = [], n = false) {
3181
+ for (this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) {
3182
+ let r;
3183
+ if (this.options.extensions?.block?.some((s) => (r = s.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
3184
+ if (r = this.tokenizer.space(e)) {
3185
+ e = e.substring(r.raw.length);
3186
+ let s = t.at(-1);
3187
+ r.raw.length === 1 && s !== void 0 ? s.raw += `
3188
+ ` : t.push(r);
3189
+ continue;
3190
+ }
3191
+ if (r = this.tokenizer.code(e)) {
3192
+ e = e.substring(r.raw.length);
3193
+ let s = t.at(-1);
3194
+ s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
3195
+ `) ? "" : `
3196
+ `) + r.raw, s.text += `
3197
+ ` + r.text, this.inlineQueue.at(-1).src = s.text) : t.push(r);
3198
+ continue;
3199
+ }
3200
+ if (r = this.tokenizer.fences(e)) {
3201
+ e = e.substring(r.raw.length), t.push(r);
3202
+ continue;
3203
+ }
3204
+ if (r = this.tokenizer.heading(e)) {
3205
+ e = e.substring(r.raw.length), t.push(r);
3206
+ continue;
3207
+ }
3208
+ if (r = this.tokenizer.hr(e)) {
3209
+ e = e.substring(r.raw.length), t.push(r);
3210
+ continue;
3211
+ }
3212
+ if (r = this.tokenizer.blockquote(e)) {
3213
+ e = e.substring(r.raw.length), t.push(r);
3214
+ continue;
3215
+ }
3216
+ if (r = this.tokenizer.list(e)) {
3217
+ e = e.substring(r.raw.length), t.push(r);
3218
+ continue;
3219
+ }
3220
+ if (r = this.tokenizer.html(e)) {
3221
+ e = e.substring(r.raw.length), t.push(r);
3222
+ continue;
3223
+ }
3224
+ if (r = this.tokenizer.def(e)) {
3225
+ e = e.substring(r.raw.length);
3226
+ let s = t.at(-1);
3227
+ s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
3228
+ `) ? "" : `
3229
+ `) + r.raw, s.text += `
3230
+ ` + r.raw, this.inlineQueue.at(-1).src = s.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
3231
+ continue;
3232
+ }
3233
+ if (r = this.tokenizer.table(e)) {
3234
+ e = e.substring(r.raw.length), t.push(r);
3235
+ continue;
3236
+ }
3237
+ if (r = this.tokenizer.lheading(e)) {
3238
+ e = e.substring(r.raw.length), t.push(r);
3239
+ continue;
3240
+ }
3241
+ let i = e;
3242
+ if (this.options.extensions?.startBlock) {
3243
+ let s = 1 / 0, a = e.slice(1), o;
3244
+ this.options.extensions.startBlock.forEach((p) => {
3245
+ o = p.call({ lexer: this }, a), typeof o == "number" && o >= 0 && (s = Math.min(s, o));
3246
+ }), s < 1 / 0 && s >= 0 && (i = e.substring(0, s + 1));
3247
+ }
3248
+ if (this.state.top && (r = this.tokenizer.paragraph(i))) {
3249
+ let s = t.at(-1);
3250
+ n && s?.type === "paragraph" ? (s.raw += (s.raw.endsWith(`
3251
+ `) ? "" : `
3252
+ `) + r.raw, s.text += `
3253
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length);
3254
+ continue;
3255
+ }
3256
+ if (r = this.tokenizer.text(e)) {
3257
+ e = e.substring(r.raw.length);
3258
+ let s = t.at(-1);
3259
+ s?.type === "text" ? (s.raw += (s.raw.endsWith(`
3260
+ `) ? "" : `
3261
+ `) + r.raw, s.text += `
3262
+ ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r);
3263
+ continue;
3264
+ }
3265
+ if (e) {
3266
+ let s = "Infinite loop on byte: " + e.charCodeAt(0);
3267
+ if (this.options.silent) {
3268
+ console.error(s);
3269
+ break;
3270
+ } else throw new Error(s);
3271
+ }
3272
+ }
3273
+ return this.state.top = true, t;
3274
+ }
3275
+ inline(e, t = []) {
3276
+ return this.inlineQueue.push({ src: e, tokens: t }), t;
3277
+ }
3278
+ inlineTokens(e, t = []) {
3279
+ let n = e, r = null;
3280
+ if (this.tokens.links) {
3281
+ let o = Object.keys(this.tokens.links);
3282
+ if (o.length > 0) for (; (r = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) o.includes(r[0].slice(r[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, r.index) + "[" + "a".repeat(r[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
3283
+ }
3284
+ for (; (r = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) n = n.slice(0, r.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
3285
+ let i;
3286
+ for (; (r = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) i = r[2] ? r[2].length : 0, n = n.slice(0, r.index + i) + "[" + "a".repeat(r[0].length - i - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
3287
+ n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
3288
+ let s = false, a = "";
3289
+ for (; e; ) {
3290
+ s || (a = ""), s = false;
3291
+ let o;
3292
+ if (this.options.extensions?.inline?.some((u) => (o = u.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
3293
+ if (o = this.tokenizer.escape(e)) {
3294
+ e = e.substring(o.raw.length), t.push(o);
3295
+ continue;
3296
+ }
3297
+ if (o = this.tokenizer.tag(e)) {
3298
+ e = e.substring(o.raw.length), t.push(o);
3299
+ continue;
3300
+ }
3301
+ if (o = this.tokenizer.link(e)) {
3302
+ e = e.substring(o.raw.length), t.push(o);
3303
+ continue;
3304
+ }
3305
+ if (o = this.tokenizer.reflink(e, this.tokens.links)) {
3306
+ e = e.substring(o.raw.length);
3307
+ let u = t.at(-1);
3308
+ o.type === "text" && u?.type === "text" ? (u.raw += o.raw, u.text += o.text) : t.push(o);
3309
+ continue;
3310
+ }
3311
+ if (o = this.tokenizer.emStrong(e, n, a)) {
3312
+ e = e.substring(o.raw.length), t.push(o);
3313
+ continue;
3314
+ }
3315
+ if (o = this.tokenizer.codespan(e)) {
3316
+ e = e.substring(o.raw.length), t.push(o);
3317
+ continue;
3318
+ }
3319
+ if (o = this.tokenizer.br(e)) {
3320
+ e = e.substring(o.raw.length), t.push(o);
3321
+ continue;
3322
+ }
3323
+ if (o = this.tokenizer.del(e)) {
3324
+ e = e.substring(o.raw.length), t.push(o);
3325
+ continue;
3326
+ }
3327
+ if (o = this.tokenizer.autolink(e)) {
3328
+ e = e.substring(o.raw.length), t.push(o);
3329
+ continue;
3330
+ }
3331
+ if (!this.state.inLink && (o = this.tokenizer.url(e))) {
3332
+ e = e.substring(o.raw.length), t.push(o);
3333
+ continue;
3334
+ }
3335
+ let p = e;
3336
+ if (this.options.extensions?.startInline) {
3337
+ let u = 1 / 0, c = e.slice(1), g;
3338
+ this.options.extensions.startInline.forEach((h) => {
3339
+ g = h.call({ lexer: this }, c), typeof g == "number" && g >= 0 && (u = Math.min(u, g));
3340
+ }), u < 1 / 0 && u >= 0 && (p = e.substring(0, u + 1));
3341
+ }
3342
+ if (o = this.tokenizer.inlineText(p)) {
3343
+ e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (a = o.raw.slice(-1)), s = true;
3344
+ let u = t.at(-1);
3345
+ u?.type === "text" ? (u.raw += o.raw, u.text += o.text) : t.push(o);
3346
+ continue;
3347
+ }
3348
+ if (e) {
3349
+ let u = "Infinite loop on byte: " + e.charCodeAt(0);
3350
+ if (this.options.silent) {
3351
+ console.error(u);
3352
+ break;
3353
+ } else throw new Error(u);
3354
+ }
3355
+ }
3356
+ return t;
3357
+ }
3358
+ };
3359
+ var P = class {
3360
+ options;
3361
+ parser;
3362
+ constructor(e) {
3363
+ this.options = e || T;
3364
+ }
3365
+ space(e) {
3366
+ return "";
3367
+ }
3368
+ code({ text: e, lang: t, escaped: n }) {
3369
+ let r = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + `
3370
+ `;
3371
+ return r ? '<pre><code class="language-' + w(r) + '">' + (n ? i : w(i, true)) + `</code></pre>
3372
+ ` : "<pre><code>" + (n ? i : w(i, true)) + `</code></pre>
3373
+ `;
3374
+ }
3375
+ blockquote({ tokens: e }) {
3376
+ return `<blockquote>
3377
+ ${this.parser.parse(e)}</blockquote>
3378
+ `;
3379
+ }
3380
+ html({ text: e }) {
3381
+ return e;
3382
+ }
3383
+ def(e) {
3384
+ return "";
3385
+ }
3386
+ heading({ tokens: e, depth: t }) {
3387
+ return `<h${t}>${this.parser.parseInline(e)}</h${t}>
3388
+ `;
3389
+ }
3390
+ hr(e) {
3391
+ return `<hr>
3392
+ `;
3393
+ }
3394
+ list(e) {
3395
+ let t = e.ordered, n = e.start, r = "";
3396
+ for (let a = 0; a < e.items.length; a++) {
3397
+ let o = e.items[a];
3398
+ r += this.listitem(o);
3399
+ }
3400
+ let i = t ? "ol" : "ul", s = t && n !== 1 ? ' start="' + n + '"' : "";
3401
+ return "<" + i + s + `>
3402
+ ` + r + "</" + i + `>
3403
+ `;
3404
+ }
3405
+ listitem(e) {
3406
+ let t = "";
3407
+ if (e.task) {
3408
+ let n = this.checkbox({ checked: !!e.checked });
3409
+ e.loose ? e.tokens[0]?.type === "paragraph" ? (e.tokens[0].text = n + " " + e.tokens[0].text, e.tokens[0].tokens && e.tokens[0].tokens.length > 0 && e.tokens[0].tokens[0].type === "text" && (e.tokens[0].tokens[0].text = n + " " + w(e.tokens[0].tokens[0].text), e.tokens[0].tokens[0].escaped = true)) : e.tokens.unshift({ type: "text", raw: n + " ", text: n + " ", escaped: true }) : t += n + " ";
3410
+ }
3411
+ return t += this.parser.parse(e.tokens, !!e.loose), `<li>${t}</li>
3412
+ `;
3413
+ }
3414
+ checkbox({ checked: e }) {
3415
+ return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
3416
+ }
3417
+ paragraph({ tokens: e }) {
3418
+ return `<p>${this.parser.parseInline(e)}</p>
3419
+ `;
3420
+ }
3421
+ table(e) {
3422
+ let t = "", n = "";
3423
+ for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]);
3424
+ t += this.tablerow({ text: n });
3425
+ let r = "";
3426
+ for (let i = 0; i < e.rows.length; i++) {
3427
+ let s = e.rows[i];
3428
+ n = "";
3429
+ for (let a = 0; a < s.length; a++) n += this.tablecell(s[a]);
3430
+ r += this.tablerow({ text: n });
3431
+ }
3432
+ return r && (r = `<tbody>${r}</tbody>`), `<table>
3433
+ <thead>
3434
+ ` + t + `</thead>
3435
+ ` + r + `</table>
3436
+ `;
3437
+ }
3438
+ tablerow({ text: e }) {
3439
+ return `<tr>
3440
+ ${e}</tr>
3441
+ `;
3442
+ }
3443
+ tablecell(e) {
3444
+ let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
3445
+ return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
3446
+ `;
3447
+ }
3448
+ strong({ tokens: e }) {
3449
+ return `<strong>${this.parser.parseInline(e)}</strong>`;
3450
+ }
3451
+ em({ tokens: e }) {
3452
+ return `<em>${this.parser.parseInline(e)}</em>`;
3453
+ }
3454
+ codespan({ text: e }) {
3455
+ return `<code>${w(e, true)}</code>`;
3456
+ }
3457
+ br(e) {
3458
+ return "<br>";
3459
+ }
3460
+ del({ tokens: e }) {
3461
+ return `<del>${this.parser.parseInline(e)}</del>`;
3462
+ }
3463
+ link({ href: e, title: t, tokens: n }) {
3464
+ let r = this.parser.parseInline(n), i = J(e);
3465
+ if (i === null) return r;
3466
+ e = i;
3467
+ let s = '<a href="' + e + '"';
3468
+ return t && (s += ' title="' + w(t) + '"'), s += ">" + r + "</a>", s;
3469
+ }
3470
+ image({ href: e, title: t, text: n, tokens: r }) {
3471
+ r && (n = this.parser.parseInline(r, this.parser.textRenderer));
3472
+ let i = J(e);
3473
+ if (i === null) return w(n);
3474
+ e = i;
3475
+ let s = `<img src="${e}" alt="${n}"`;
3476
+ return t && (s += ` title="${w(t)}"`), s += ">", s;
3477
+ }
3478
+ text(e) {
3479
+ return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : w(e.text);
3480
+ }
3481
+ };
3482
+ var $ = class {
3483
+ strong({ text: e }) {
3484
+ return e;
3485
+ }
3486
+ em({ text: e }) {
3487
+ return e;
3488
+ }
3489
+ codespan({ text: e }) {
3490
+ return e;
3491
+ }
3492
+ del({ text: e }) {
3493
+ return e;
3494
+ }
3495
+ html({ text: e }) {
3496
+ return e;
3497
+ }
3498
+ text({ text: e }) {
3499
+ return e;
3500
+ }
3501
+ link({ text: e }) {
3502
+ return "" + e;
3503
+ }
3504
+ image({ text: e }) {
3505
+ return "" + e;
3506
+ }
3507
+ br() {
3508
+ return "";
3509
+ }
3510
+ };
3511
+ var b = class l2 {
3512
+ options;
3513
+ renderer;
3514
+ textRenderer;
3515
+ constructor(e) {
3516
+ 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 $();
3517
+ }
3518
+ static parse(e, t) {
3519
+ return new l2(t).parse(e);
3520
+ }
3521
+ static parseInline(e, t) {
3522
+ return new l2(t).parseInline(e);
3523
+ }
3524
+ parse(e, t = true) {
3525
+ let n = "";
3526
+ for (let r = 0; r < e.length; r++) {
3527
+ let i = e[r];
3528
+ if (this.options.extensions?.renderers?.[i.type]) {
3529
+ let a = i, o = this.options.extensions.renderers[a.type].call({ parser: this }, a);
3530
+ if (o !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(a.type)) {
3531
+ n += o || "";
3532
+ continue;
3533
+ }
3534
+ }
3535
+ let s = i;
3536
+ switch (s.type) {
3537
+ case "space": {
3538
+ n += this.renderer.space(s);
3539
+ continue;
3540
+ }
3541
+ case "hr": {
3542
+ n += this.renderer.hr(s);
3543
+ continue;
3544
+ }
3545
+ case "heading": {
3546
+ n += this.renderer.heading(s);
3547
+ continue;
3548
+ }
3549
+ case "code": {
3550
+ n += this.renderer.code(s);
3551
+ continue;
3552
+ }
3553
+ case "table": {
3554
+ n += this.renderer.table(s);
3555
+ continue;
3556
+ }
3557
+ case "blockquote": {
3558
+ n += this.renderer.blockquote(s);
3559
+ continue;
3560
+ }
3561
+ case "list": {
3562
+ n += this.renderer.list(s);
3563
+ continue;
3564
+ }
3565
+ case "html": {
3566
+ n += this.renderer.html(s);
3567
+ continue;
3568
+ }
3569
+ case "def": {
3570
+ n += this.renderer.def(s);
3571
+ continue;
3572
+ }
3573
+ case "paragraph": {
3574
+ n += this.renderer.paragraph(s);
3575
+ continue;
3576
+ }
3577
+ case "text": {
3578
+ let a = s, o = this.renderer.text(a);
3579
+ for (; r + 1 < e.length && e[r + 1].type === "text"; ) a = e[++r], o += `
3580
+ ` + this.renderer.text(a);
3581
+ t ? n += this.renderer.paragraph({ type: "paragraph", raw: o, text: o, tokens: [{ type: "text", raw: o, text: o, escaped: true }] }) : n += o;
3582
+ continue;
3583
+ }
3584
+ default: {
3585
+ let a = 'Token with "' + s.type + '" type was not found.';
3586
+ if (this.options.silent) return console.error(a), "";
3587
+ throw new Error(a);
3588
+ }
3589
+ }
3590
+ }
3591
+ return n;
3592
+ }
3593
+ parseInline(e, t = this.renderer) {
3594
+ let n = "";
3595
+ for (let r = 0; r < e.length; r++) {
3596
+ let i = e[r];
3597
+ if (this.options.extensions?.renderers?.[i.type]) {
3598
+ let a = this.options.extensions.renderers[i.type].call({ parser: this }, i);
3599
+ if (a !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) {
3600
+ n += a || "";
3601
+ continue;
3602
+ }
3603
+ }
3604
+ let s = i;
3605
+ switch (s.type) {
3606
+ case "escape": {
3607
+ n += t.text(s);
3608
+ break;
3609
+ }
3610
+ case "html": {
3611
+ n += t.html(s);
3612
+ break;
3613
+ }
3614
+ case "link": {
3615
+ n += t.link(s);
3616
+ break;
3617
+ }
3618
+ case "image": {
3619
+ n += t.image(s);
3620
+ break;
3621
+ }
3622
+ case "strong": {
3623
+ n += t.strong(s);
3624
+ break;
3625
+ }
3626
+ case "em": {
3627
+ n += t.em(s);
3628
+ break;
3629
+ }
3630
+ case "codespan": {
3631
+ n += t.codespan(s);
3632
+ break;
3633
+ }
3634
+ case "br": {
3635
+ n += t.br(s);
3636
+ break;
3637
+ }
3638
+ case "del": {
3639
+ n += t.del(s);
3640
+ break;
3641
+ }
3642
+ case "text": {
3643
+ n += t.text(s);
3644
+ break;
3645
+ }
3646
+ default: {
3647
+ let a = 'Token with "' + s.type + '" type was not found.';
3648
+ if (this.options.silent) return console.error(a), "";
3649
+ throw new Error(a);
3650
+ }
3651
+ }
3652
+ }
3653
+ return n;
3654
+ }
3655
+ };
3656
+ var S = class {
3657
+ options;
3658
+ block;
3659
+ constructor(e) {
3660
+ this.options = e || T;
3661
+ }
3662
+ static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
3663
+ static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
3664
+ preprocess(e) {
3665
+ return e;
3666
+ }
3667
+ postprocess(e) {
3668
+ return e;
3669
+ }
3670
+ processAllTokens(e) {
3671
+ return e;
3672
+ }
3673
+ emStrongMask(e) {
3674
+ return e;
3675
+ }
3676
+ provideLexer() {
3677
+ return this.block ? x.lex : x.lexInline;
3678
+ }
3679
+ provideParser() {
3680
+ return this.block ? b.parse : b.parseInline;
3681
+ }
3682
+ };
3683
+ var B = class {
3684
+ defaults = L();
3685
+ options = this.setOptions;
3686
+ parse = this.parseMarkdown(true);
3687
+ parseInline = this.parseMarkdown(false);
3688
+ Parser = b;
3689
+ Renderer = P;
3690
+ TextRenderer = $;
3691
+ Lexer = x;
3692
+ Tokenizer = y;
3693
+ Hooks = S;
3694
+ constructor(...e) {
3695
+ this.use(...e);
3696
+ }
3697
+ walkTokens(e, t) {
3698
+ let n = [];
3699
+ for (let r of e) switch (n = n.concat(t.call(this, r)), r.type) {
3700
+ case "table": {
3701
+ let i = r;
3702
+ for (let s of i.header) n = n.concat(this.walkTokens(s.tokens, t));
3703
+ for (let s of i.rows) for (let a of s) n = n.concat(this.walkTokens(a.tokens, t));
3704
+ break;
3705
+ }
3706
+ case "list": {
3707
+ let i = r;
3708
+ n = n.concat(this.walkTokens(i.items, t));
3709
+ break;
3710
+ }
3711
+ default: {
3712
+ let i = r;
3713
+ this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((s) => {
3714
+ let a = i[s].flat(1 / 0);
3715
+ n = n.concat(this.walkTokens(a, t));
3716
+ }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t)));
3717
+ }
3718
+ }
3719
+ return n;
3720
+ }
3721
+ use(...e) {
3722
+ let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
3723
+ return e.forEach((n) => {
3724
+ let r = { ...n };
3725
+ if (r.async = this.defaults.async || r.async || false, n.extensions && (n.extensions.forEach((i) => {
3726
+ if (!i.name) throw new Error("extension name required");
3727
+ if ("renderer" in i) {
3728
+ let s = t.renderers[i.name];
3729
+ s ? t.renderers[i.name] = function(...a) {
3730
+ let o = i.renderer.apply(this, a);
3731
+ return o === false && (o = s.apply(this, a)), o;
3732
+ } : t.renderers[i.name] = i.renderer;
3733
+ }
3734
+ if ("tokenizer" in i) {
3735
+ if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
3736
+ let s = t[i.level];
3737
+ s ? s.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start]));
3738
+ }
3739
+ "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens);
3740
+ }), r.extensions = t), n.renderer) {
3741
+ let i = this.defaults.renderer || new P(this.defaults);
3742
+ for (let s in n.renderer) {
3743
+ if (!(s in i)) throw new Error(`renderer '${s}' does not exist`);
3744
+ if (["options", "parser"].includes(s)) continue;
3745
+ let a = s, o = n.renderer[a], p = i[a];
3746
+ i[a] = (...u) => {
3747
+ let c = o.apply(i, u);
3748
+ return c === false && (c = p.apply(i, u)), c || "";
3749
+ };
3750
+ }
3751
+ r.renderer = i;
3752
+ }
3753
+ if (n.tokenizer) {
3754
+ let i = this.defaults.tokenizer || new y(this.defaults);
3755
+ for (let s in n.tokenizer) {
3756
+ if (!(s in i)) throw new Error(`tokenizer '${s}' does not exist`);
3757
+ if (["options", "rules", "lexer"].includes(s)) continue;
3758
+ let a = s, o = n.tokenizer[a], p = i[a];
3759
+ i[a] = (...u) => {
3760
+ let c = o.apply(i, u);
3761
+ return c === false && (c = p.apply(i, u)), c;
3762
+ };
3763
+ }
3764
+ r.tokenizer = i;
3765
+ }
3766
+ if (n.hooks) {
3767
+ let i = this.defaults.hooks || new S();
3768
+ for (let s in n.hooks) {
3769
+ if (!(s in i)) throw new Error(`hook '${s}' does not exist`);
3770
+ if (["options", "block"].includes(s)) continue;
3771
+ let a = s, o = n.hooks[a], p = i[a];
3772
+ S.passThroughHooks.has(s) ? i[a] = (u) => {
3773
+ if (this.defaults.async && S.passThroughHooksRespectAsync.has(s)) return (async () => {
3774
+ let g = await o.call(i, u);
3775
+ return p.call(i, g);
3776
+ })();
3777
+ let c = o.call(i, u);
3778
+ return p.call(i, c);
3779
+ } : i[a] = (...u) => {
3780
+ if (this.defaults.async) return (async () => {
3781
+ let g = await o.apply(i, u);
3782
+ return g === false && (g = await p.apply(i, u)), g;
3783
+ })();
3784
+ let c = o.apply(i, u);
3785
+ return c === false && (c = p.apply(i, u)), c;
3786
+ };
3787
+ }
3788
+ r.hooks = i;
3789
+ }
3790
+ if (n.walkTokens) {
3791
+ let i = this.defaults.walkTokens, s = n.walkTokens;
3792
+ r.walkTokens = function(a) {
3793
+ let o = [];
3794
+ return o.push(s.call(this, a)), i && (o = o.concat(i.call(this, a))), o;
3795
+ };
3796
+ }
3797
+ this.defaults = { ...this.defaults, ...r };
3798
+ }), this;
3799
+ }
3800
+ setOptions(e) {
3801
+ return this.defaults = { ...this.defaults, ...e }, this;
3802
+ }
3803
+ lexer(e, t) {
3804
+ return x.lex(e, t ?? this.defaults);
3805
+ }
3806
+ parser(e, t) {
3807
+ return b.parse(e, t ?? this.defaults);
3808
+ }
3809
+ parseMarkdown(e) {
3810
+ return (n, r) => {
3811
+ let i = { ...r }, s = { ...this.defaults, ...i }, a = this.onError(!!s.silent, !!s.async);
3812
+ if (this.defaults.async === true && i.async === false) return a(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."));
3813
+ if (typeof n > "u" || n === null) return a(new Error("marked(): input parameter is undefined or null"));
3814
+ if (typeof n != "string") return a(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
3815
+ if (s.hooks && (s.hooks.options = s, s.hooks.block = e), s.async) return (async () => {
3816
+ let o = s.hooks ? await s.hooks.preprocess(n) : n, u = await (s.hooks ? await s.hooks.provideLexer() : e ? x.lex : x.lexInline)(o, s), c = s.hooks ? await s.hooks.processAllTokens(u) : u;
3817
+ s.walkTokens && await Promise.all(this.walkTokens(c, s.walkTokens));
3818
+ let h = await (s.hooks ? await s.hooks.provideParser() : e ? b.parse : b.parseInline)(c, s);
3819
+ return s.hooks ? await s.hooks.postprocess(h) : h;
3820
+ })().catch(a);
3821
+ try {
3822
+ s.hooks && (n = s.hooks.preprocess(n));
3823
+ let p = (s.hooks ? s.hooks.provideLexer() : e ? x.lex : x.lexInline)(n, s);
3824
+ s.hooks && (p = s.hooks.processAllTokens(p)), s.walkTokens && this.walkTokens(p, s.walkTokens);
3825
+ let c = (s.hooks ? s.hooks.provideParser() : e ? b.parse : b.parseInline)(p, s);
3826
+ return s.hooks && (c = s.hooks.postprocess(c)), c;
3827
+ } catch (o) {
3828
+ return a(o);
3829
+ }
3830
+ };
3831
+ }
3832
+ onError(e, t) {
3833
+ return (n) => {
3834
+ if (n.message += `
3835
+ Please report this to https://github.com/markedjs/marked.`, e) {
3836
+ let r = "<p>An error occurred:</p><pre>" + w(n.message + "", true) + "</pre>";
3837
+ return t ? Promise.resolve(r) : r;
3838
+ }
3839
+ if (t) return Promise.reject(n);
3840
+ throw n;
3841
+ };
3842
+ }
3843
+ };
3844
+ var _ = new B();
3845
+ function k(l3, e) {
3846
+ return _.parse(l3, e);
3847
+ }
3848
+ k.options = k.setOptions = function(l3) {
3849
+ return _.setOptions(l3), k.defaults = _.defaults, G(k.defaults), k;
3850
+ };
3851
+ k.getDefaults = L;
3852
+ k.defaults = T;
3853
+ k.use = function(...l3) {
3854
+ return _.use(...l3), k.defaults = _.defaults, G(k.defaults), k;
3855
+ };
3856
+ k.walkTokens = function(l3, e) {
3857
+ return _.walkTokens(l3, e);
3858
+ };
3859
+ k.parseInline = _.parseInline;
3860
+ k.Parser = b;
3861
+ k.parser = b.parse;
3862
+ k.Renderer = P;
3863
+ k.TextRenderer = $;
3864
+ k.Lexer = x;
3865
+ k.lexer = x.lex;
3866
+ k.Tokenizer = y;
3867
+ k.Hooks = S;
3868
+ k.parse = k;
3869
+ var Zt = k.options;
3870
+ var Gt = k.setOptions;
3871
+ var Nt = k.use;
3872
+ var Ft = k.walkTokens;
3873
+ var jt = k.parseInline;
3874
+ var Ut = b.parse;
3875
+ var Kt = x.lex;
3876
+
3877
+ // src/markdown.ts
3878
+ k.setOptions({
3879
+ gfm: true,
3880
+ breaks: true
3881
+ });
3882
+ var renderer = new k.Renderer();
3883
+ renderer.link = ({ href, text: text2 }) => `<a href="${href}" target="_blank" rel="noopener noreferrer">${text2}</a>`;
3884
+ renderer.html = () => "";
3885
+ k.use({ renderer });
3886
+ function renderMarkdown(text2) {
3887
+ if (!text2) return "";
3888
+ const html2 = k.parse(text2, { async: false });
3889
+ return purify.sanitize(html2, {
3890
+ ALLOWED_TAGS: [
3891
+ "p",
3892
+ "br",
3893
+ "strong",
3894
+ "b",
3895
+ "em",
3896
+ "i",
3897
+ "s",
3898
+ "del",
3899
+ "code",
3900
+ "pre",
3901
+ "a",
3902
+ "ul",
3903
+ "ol",
3904
+ "li",
3905
+ "h1",
3906
+ "h2",
3907
+ "h3",
3908
+ "h4",
3909
+ "h5",
3910
+ "h6",
3911
+ "blockquote",
3912
+ "span"
3913
+ ],
3914
+ ALLOWED_ATTR: ["href", "target", "rel", "class"]
3915
+ });
3916
+ }
3917
+
3918
+ // src/element-event-controller.ts
3919
+ var AssistantElementEventController = class {
3920
+ #host;
3921
+ #assistantBody;
3922
+ #assistantText = "";
3923
+ #completedTool;
3924
+ #streamKind;
3925
+ #proposalCards = /* @__PURE__ */ new Map();
3926
+ constructor(host) {
3927
+ this.#host = host;
3928
+ }
3929
+ handle(event) {
3930
+ if (event.event === "view_available") {
3931
+ this.#host.element.dispatchEvent(
3932
+ new CustomEvent("assistant-view-available", {
3933
+ detail: event.data
3934
+ })
3935
+ );
3936
+ return;
3937
+ }
3938
+ if (event.event === "unrecognized") return;
3939
+ const { event: name, data } = event;
3940
+ if (name === "session_started") {
3941
+ if (isRecord4(data.configuration)) {
3942
+ this.#host.applyConfiguration(data.configuration);
3943
+ }
3944
+ this.#host.element.dispatchEvent(
3945
+ new CustomEvent("assistant-session-started", {
3946
+ detail: { expiresAt: String(data.expiresAt ?? "") }
3947
+ })
3948
+ );
3949
+ return;
3950
+ }
3951
+ if (name === "session_expired") {
3952
+ this.#host.element.dispatchEvent(new CustomEvent("assistant-session-expired"));
3953
+ return;
3954
+ }
3955
+ if (name === "session_reset") {
3956
+ this.resetConversation();
3957
+ return;
3958
+ }
3959
+ if (name === "context_changed") {
3960
+ this.#host.element.dispatchEvent(
3961
+ new CustomEvent("assistant-context-changed", { detail: { context: data.context } })
3962
+ );
3963
+ return;
3964
+ }
3965
+ if (name === "model_context_changed") {
3966
+ this.#host.element.dispatchEvent(
3967
+ new CustomEvent("assistant-model-context-changed", {
3968
+ detail: { modelContext: data.modelContext }
3969
+ })
3970
+ );
3971
+ return;
3972
+ }
3973
+ if (name === "message_started") {
3974
+ this.#startStream("message");
3975
+ const body = this.#host.appendMessage("user", String(data.message ?? ""));
3976
+ const messages = this.#host.messages();
3977
+ if (body && messages) this.#revealLatestMessage(messages);
3978
+ this.#host.element.dispatchEvent(new CustomEvent("assistant-message-started"));
3979
+ return;
3980
+ }
3981
+ if (name === "message_completed") {
3982
+ if (this.#streamKind !== "message") return;
3983
+ this.#clearStream();
3984
+ this.#host.element.dispatchEvent(new CustomEvent("assistant-message-completed"));
3985
+ return;
3986
+ }
3987
+ if (name === "interaction_started") {
3988
+ this.#startStream("interaction");
3989
+ this.#completedTool = void 0;
3990
+ return;
3991
+ }
3992
+ if (name === "interaction_completed") {
3993
+ if (this.#streamKind !== "interaction") return;
3994
+ this.#finishInteraction(String(data.id ?? ""), String(data.action ?? "accept"));
3995
+ return;
3996
+ }
3997
+ if (name === "content") {
3998
+ this.#appendContent(String(data.delta ?? ""));
3999
+ return;
4000
+ }
4001
+ if (name === "tool_proposed" || name === "interaction_proposed") {
4002
+ if (!this.#streamKind) return;
4003
+ this.#appendToolProposal(
4004
+ String(data.id ?? ""),
4005
+ String(data.tool ?? ("title" in data ? data.title : void 0) ?? "Action"),
4006
+ isRecord4(data.arguments) ? data.arguments : void 0
4007
+ );
4008
+ return;
4009
+ }
4010
+ if (name === "input_requested" && isRecord4(data.requestedSchema)) {
4011
+ if (!this.#streamKind) return;
4012
+ this.#appendInputRequest(
4013
+ String(data.id ?? ""),
4014
+ String(data.message ?? "More information is required"),
4015
+ data.requestedSchema
4016
+ );
4017
+ return;
4018
+ }
4019
+ if (name === "tool_completed") {
4020
+ this.#completedTool = data;
4021
+ return;
4022
+ }
4023
+ if (name === "error") {
4024
+ this.#clearStream();
4025
+ this.#host.dispatchError({
4026
+ code: String(data.code ?? "stream_failed"),
4027
+ ...typeof data.status === "number" ? { status: data.status } : {},
4028
+ retryable: data.retryable === true
4029
+ });
4030
+ }
4031
+ }
4032
+ resetConversation() {
4033
+ const messages = this.#host.messages();
4034
+ messages?.replaceChildren();
4035
+ if (messages) messages.scrollTop = 0;
4036
+ this.#proposalCards.clear();
4037
+ this.#clearStream();
4038
+ this.#completedTool = void 0;
4039
+ this.#host.element.removeAttribute("has-messages");
4040
+ this.#host.element.dispatchEvent(new CustomEvent("assistant-session-reset"));
4041
+ }
4042
+ #finishInteraction(id, action) {
4043
+ if (this.#completedTool && !this.#assistantBody) {
4044
+ this.#host.appendMessage("assistant", JSON.stringify(this.#completedTool.result ?? {}) ?? "");
4045
+ }
4046
+ this.#proposalCards.get(id)?.remove();
4047
+ this.#proposalCards.delete(id);
4048
+ if (action === "accept") {
4049
+ this.#host.element.dispatchEvent(
4050
+ new CustomEvent("assistant-tool-completed", { detail: { id } })
4051
+ );
4052
+ }
4053
+ this.#host.element.dispatchEvent(
4054
+ new CustomEvent("assistant-interaction-resolved", { detail: { id, action } })
4055
+ );
4056
+ this.#clearStream();
4057
+ this.#completedTool = void 0;
4058
+ }
4059
+ #appendToolProposal(id, tool, arguments_) {
4060
+ const messages = this.#host.messages();
4061
+ if (!messages || !id) return;
4062
+ this.#proposalCards.get(id)?.remove();
4063
+ const labels = this.#host.labels();
4064
+ const card = createInteractionCard({
4065
+ tool,
4066
+ ...arguments_ ? { arguments: arguments_ } : {},
4067
+ labels: {
4068
+ accept: labels.confirm,
4069
+ decline: "Decline",
4070
+ cancel: labels.cancel
4071
+ },
4072
+ respond: (action) => this.#host.respond(id, { action })
4073
+ });
4074
+ messages.append(card);
4075
+ this.#proposalCards.set(id, card);
4076
+ this.#revealLatestMessage(messages);
4077
+ this.#host.element.dispatchEvent(
4078
+ new CustomEvent("assistant-tool-proposed", { detail: { id, tool, arguments: arguments_ } })
4079
+ );
4080
+ }
4081
+ #appendInputRequest(id, message, requestedSchema) {
4082
+ const messages = this.#host.messages();
4083
+ if (!messages || !id) return;
4084
+ this.#proposalCards.get(id)?.remove();
4085
+ const labels = this.#host.labels();
4086
+ const card = createInputRequestCard({
4087
+ message,
4088
+ requestedSchema,
4089
+ labels: {
4090
+ submit: labels.confirm,
4091
+ decline: "Decline",
4092
+ cancel: labels.cancel
4093
+ },
4094
+ respond: (response) => this.#host.respond(id, response)
4095
+ });
4096
+ messages.append(card);
4097
+ this.#proposalCards.set(id, card);
4098
+ this.#revealLatestMessage(messages);
4099
+ this.#host.element.dispatchEvent(
4100
+ new CustomEvent("assistant-input-requested", {
4101
+ detail: { id, message, requestedSchema }
4102
+ })
4103
+ );
4104
+ }
4105
+ #startStream(kind) {
4106
+ this.#assistantBody = void 0;
4107
+ this.#assistantText = "";
4108
+ this.#streamKind = kind;
4109
+ }
4110
+ #clearStream() {
4111
+ this.#assistantBody = void 0;
4112
+ this.#assistantText = "";
4113
+ this.#streamKind = void 0;
4114
+ }
4115
+ #appendContent(delta) {
4116
+ if (!this.#streamKind || !delta) return;
4117
+ this.#assistantText += delta;
4118
+ const html2 = renderMarkdown(this.#assistantText);
4119
+ if (!html2) return;
4120
+ const body = this.#assistantBody ?? this.#host.appendMessage("assistant", "");
4121
+ this.#assistantBody = body;
4122
+ if (!body) return;
4123
+ body.innerHTML = html2;
4124
+ const messages = this.#host.messages();
4125
+ if (messages) this.#revealLatestMessage(messages);
4126
+ }
4127
+ #revealLatestMessage(messages) {
4128
+ this.#host.element.setAttribute("has-messages", "");
4129
+ messages.scrollTop = messages.scrollHeight;
4130
+ }
4131
+ };
4132
+ function isRecord4(value) {
4133
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4134
+ }
4135
+
4136
+ // src/element-helpers.ts
4137
+ function camelToKebab(value) {
4138
+ return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
4139
+ }
4140
+ function tokenValue(name, value) {
4141
+ if (typeof value !== "number") return value;
4142
+ if (name === "lineHeight" || name === "motionScale") return String(value);
4143
+ return `${value}px`;
4144
+ }
4145
+ function escapeAttribute(value) {
4146
+ return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;");
4147
+ }
4148
+ function queryRequired(root, selector) {
4149
+ const element = root.querySelector(selector);
4150
+ if (!element) throw new Error(`assistant renderer is missing ${selector}`);
4151
+ return element;
4152
+ }
4153
+
4154
+ // src/element-styles.ts
4155
+ var ASSISTANT_ELEMENT_STYLES = `<style>
4156
+ *, *::before, *::after { box-sizing: border-box; }
4157
+ .visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }
4158
+ .visually-hidden[hidden] { display: none !important; }
4159
+ :host { color-scheme: light dark; font-family: var(--ns-assistant-font-family, var(--ns-assistant-default-font-family)); font-size: var(--ns-assistant-base-font-size, var(--ns-assistant-default-base-font-size)); line-height: var(--ns-assistant-line-height, var(--ns-assistant-default-line-height)); z-index: var(--ns-assistant-z-index, var(--ns-assistant-default-z-index)); -webkit-font-smoothing: antialiased; }
4160
+ :host([data-mode="floating"]) { position: fixed; bottom: 20px; right: 20px; }
4161
+ :host([data-mode="floating"][data-position="bottom-left"]) { right: auto; left: 20px; }
4162
+ button { font: inherit; }
4163
+ button, textarea, input, select { -webkit-tap-highlight-color: transparent; }
4164
+ .launcher { display: grid; place-items: center; width: 48px; height: 48px; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 82%, transparent); box-shadow: 0 4px 20px rgba(0,0,0,.12); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); cursor: pointer; transition: transform .5s cubic-bezier(.25,1,.5,1), box-shadow .2s ease; }
4165
+ .launcher:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 8px 26px rgba(0,0,0,.16); }
4166
+ .launcher img { width: 28px; height: 28px; border-radius: 50%; object-fit: contain; }
4167
+ .panel { display: none; flex-direction: column; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 40px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 40px)); overflow: hidden; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 88%, transparent); border: 1px solid color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 74%, transparent); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); transform-origin: bottom right; animation: halo-panel-in .32s cubic-bezier(.23,1,.32,1) both; }
4168
+ :host([open]) .panel { display: flex; }
4169
+ :host([open]) .launcher { display: none; }
4170
+ header { display: flex; flex: 0 0 auto; gap: 10px; align-items: center; min-height: 64px; padding: 14px 18px; border-bottom: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); }
4171
+ header strong { flex: 1; font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
4172
+ .brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }
4173
+ .close, .send { display: grid; place-items: center; border: 0; border-radius: 999px; cursor: pointer; }
4174
+ .close { width: 32px; height: 32px; padding: 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; font-size: 24px; font-weight: 300; line-height: 1; transition: background .15s ease, color .15s ease; }
4175
+ .close:hover { color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); }
4176
+ .welcome { flex: 0 0 auto; padding: 30px 22px 18px; }
4177
+ .welcome h2 { margin: 0; font-size: 1.42em; line-height: 1.25; letter-spacing: -.025em; }
4178
+ .welcome p { max-width: 42ch; margin: 7px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
4179
+ :host([has-messages]) .welcome, :host([has-messages]) .suggested-prompts { display: none; }
4180
+ .suggested-prompts { display: flex; flex: 0 0 auto; flex-wrap: wrap; gap: 8px; padding: 0 20px 16px; }
4181
+ .suggested-prompts:empty { display: none; }
4182
+ .suggested-prompts button { padding: 7px 12px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; cursor: pointer; transition: background .2s ease, color .2s ease, transform .2s ease; }
4183
+ .suggested-prompts button:hover { color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); transform: translateY(-1px); }
4184
+ .messages { flex: 1 1 auto; min-height: 0; padding: 18px 20px; overflow-y: auto; overscroll-behavior: contain; scroll-behavior: smooth; }
4185
+ .messages::-webkit-scrollbar { width: 6px; }
4186
+ .messages::-webkit-scrollbar-thumb { background: var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; }
4187
+ .message { width: fit-content; max-width: 88%; margin: 0 0 14px; padding: 0; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: transparent; white-space: pre-wrap; animation: halo-message-in .2s ease both; }
4188
+ .message > span, .message > .markdown { overflow-wrap: anywhere; }
4189
+ .message .avatar { float: left; width: 24px; height: 24px; margin-right: 9px; border-radius: 50%; object-fit: cover; }
4190
+ .message time { display: block; margin-top: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; line-height: 1.2; }
4191
+ .message.user { display: grid; justify-items: start; gap: 3px; margin-left: auto; padding: 10px 16px 8px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); font-size: .94em; }
4192
+ .message.user time { margin-top: 0; }
4193
+ .markdown { white-space: normal; }
4194
+ .markdown p { margin: 0 0 8px; }
4195
+ .markdown p:last-child { margin-bottom: 0; }
4196
+ .markdown strong, .markdown b { font-weight: 650; }
4197
+ .markdown em, .markdown i { font-style: italic; }
4198
+ .markdown a { color: var(--ns-assistant-link, var(--ns-assistant-default-link)); text-decoration: underline; text-underline-offset: 2px; }
4199
+ .markdown a:hover { opacity: .8; }
4200
+ .markdown code { padding: 2px 6px; border-radius: 5px; background: var(--ns-assistant-code, var(--ns-assistant-default-code)); font-family: var(--ns-assistant-mono-font-family, var(--ns-assistant-default-mono-font-family)); font-size: .87em; }
4201
+ .markdown pre { margin: 10px 0; padding: 12px 14px; overflow-x: auto; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 10px; background: var(--ns-assistant-code, var(--ns-assistant-default-code)); white-space: pre; }
4202
+ .markdown pre code { padding: 0; background: transparent; font-size: .86em; }
4203
+ .markdown ul, .markdown ol { margin: 8px 0; padding-left: 22px; }
4204
+ .markdown li { margin: 3px 0; }
4205
+ .markdown blockquote { margin: 10px 0; padding-left: 12px; border-left: 3px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
4206
+ .markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6 { margin: 14px 0 7px; line-height: 1.25; letter-spacing: -.015em; }
4207
+ .markdown h1:first-child, .markdown h2:first-child, .markdown h3:first-child { margin-top: 0; }
4208
+ .markdown h1 { font-size: 1.3em; } .markdown h2 { font-size: 1.18em; } .markdown h3 { font-size: 1.08em; }
4209
+ .message.thinking > span { display: inline-block; color: transparent; background: linear-gradient(90deg, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)) 25%, var(--ns-assistant-text, var(--ns-assistant-default-text)) 50%, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)) 75%); background-size: 300% 100%; background-clip: text; -webkit-background-clip: text; font-style: italic; font-weight: 500; animation: halo-shimmer 2s linear infinite; }
4210
+ .tool-proposal { display: grid; gap: 10px; align-items: start; margin: 8px 0 14px; padding: 12px 14px; border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 14px; background: color-mix(in srgb, var(--ns-assistant-input, var(--ns-assistant-default-input)) 78%, transparent); animation: halo-message-in .2s ease both; }
4211
+ .tool-proposal > strong { font-weight: 650; overflow-wrap: anywhere; }
4212
+ .proposal-arguments { display: grid; grid-template-columns: minmax(90px, auto) minmax(0, 1fr); gap: 4px 10px; margin: 0; font-size: .9em; }
4213
+ .proposal-arguments dt { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
4214
+ .proposal-arguments dd { margin: 0; overflow-wrap: anywhere; }
4215
+ .proposal-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: end; }
4216
+ .tool-proposal button { padding: 7px 11px; border: 0; border-radius: 999px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); cursor: pointer; }
4217
+ .tool-proposal button:first-of-type { color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)); background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
4218
+ .tool-proposal button:disabled { opacity: .55; cursor: not-allowed; }
4219
+ .input-request form { display: grid; gap: 10px; align-items: stretch; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
4220
+ .input-request form:focus-within { box-shadow: none; }
4221
+ .input-request label { display: grid; gap: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .9em; }
4222
+ .input-request input, .input-request select { width: 100%; padding: 8px 10px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); outline: 0; font: inherit; }
4223
+ .input-request select[multiple] { min-height: 88px; }
4224
+ .input-request input[type="checkbox"] { width: auto; justify-self: start; accent-color: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
4225
+ .input-request input:focus-visible, .input-request select:focus-visible { border-color: var(--ns-assistant-focus, var(--ns-assistant-default-focus)); box-shadow: 0 0 0 2px var(--ns-assistant-focus, var(--ns-assistant-default-focus)); }
4226
+ .input-request .proposal-actions { margin-top: 2px; }
4227
+ form { display: flex; flex: 0 0 auto; gap: 8px; align-items: center; min-height: 48px; margin: 8px 16px 12px; padding: 8px 8px 8px 16px; border: 0; border-radius: 999px; background: var(--ns-assistant-input, var(--ns-assistant-default-input)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 60%, transparent); transition: box-shadow .15s ease; }
4228
+ form:focus-within { box-shadow: inset 0 0 0 1px var(--ns-assistant-focus, var(--ns-assistant-default-focus)), 0 0 0 2px var(--ns-assistant-focus, var(--ns-assistant-default-focus)); }
4229
+ textarea { flex: 1; min-height: 24px; max-height: 120px; resize: none; padding: 0; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: transparent; border: 0; border-radius: 0; outline: 0; box-shadow: none; appearance: none; -webkit-appearance: none; font: inherit; font-size: 16px; line-height: 24px; }
4230
+ textarea::placeholder { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
4231
+ textarea:focus, textarea:focus-visible { outline: none; box-shadow: none; }
4232
+ button:focus-visible { outline: 3px solid var(--ns-assistant-focus, var(--ns-assistant-default-focus)); outline-offset: 2px; }
4233
+ .send { position: relative; display: block; width: 32px; height: 32px; flex: 0 0 32px; padding: 0; overflow: hidden; color: transparent; background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); font-size: 0; line-height: 0; transition: transform .15s ease, background .15s ease; }
4234
+ .send::before { content: ''; position: absolute; top: 50%; left: 50%; width: 16px; height: 16px; background: var(--ns-assistant-text, var(--ns-assistant-default-text)); transform: translate(-50%, -50%); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 19V5M5 12l7-7 7 7' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 19V5M5 12l7-7 7 7' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
4235
+ .send:hover { transform: scale(1.05); background: var(--ns-assistant-hover, var(--ns-assistant-default-hover)); }
4236
+ .send:disabled, textarea:disabled { opacity: .55; cursor: not-allowed; }
4237
+ .legal { display: flex; gap: 12px; justify-content: center; padding: 0 12px 9px; font-size: .75em; }
4238
+ .legal:empty { display: none; }
4239
+ .legal a { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); text-underline-offset: 2px; }
4240
+ ::slotted([slot="conversation-footer"]) { display: block; padding: 0 16px 12px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: 11px; text-align: center; }
4241
+ @keyframes halo-panel-in { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
4242
+ @keyframes halo-message-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
4243
+ @keyframes halo-shimmer { from { background-position: 100% center; } to { background-position: 0 center; } }
4244
+ :host([data-density="compact"]) .welcome { padding: 20px 18px 12px; }
4245
+ @media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border: 0; border-radius: 0; } }
4246
+ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } .messages { scroll-behavior: auto; } }
4247
+ @media (forced-colors: active) { .message.thinking > span { color: CanvasText; background: none; } }
4248
+ @media (max-width: 560px) { :host([data-mode="floating"]) { inset: auto 12px 12px; } :host([open]) .panel { width: calc(100vw - 24px); max-height: calc(100vh - 24px); } }
4249
+ </style>`;
4250
+
4251
+ // src/presentation.ts
4252
+ function syncAssistantPresentation(host, root, appearance, mode, sessionState) {
4253
+ const presentation = appearance.presentation;
4254
+ host.dataset.panelSurface = presentation.panel.surface;
4255
+ host.dataset.panelElevation = presentation.panel.elevation;
4256
+ host.dataset.panelBorder = presentation.panel.border;
4257
+ host.dataset.launcherEffect = presentation.launcher.effect;
4258
+ host.dataset.messageUserStyle = presentation.messages.userStyle;
4259
+ host.dataset.messageAssistantStyle = presentation.messages.assistantStyle;
4260
+ host.dataset.sessionState = sessionState;
4261
+ const radius = presentation.panel.radius;
4262
+ if (radius === void 0) {
4263
+ host.style.removeProperty("--ns-assistant-presentation-panel-radius");
4264
+ } else {
4265
+ host.style.setProperty("--ns-assistant-presentation-panel-radius", `${radius}px`);
4266
+ }
4267
+ host.style.setProperty(
4268
+ "--ns-assistant-presentation-launcher-size",
4269
+ presentation.launcher.size === "lg" ? "56px" : "48px"
4270
+ );
4271
+ host.style.setProperty(
4272
+ "--ns-assistant-presentation-panel-background",
4273
+ presentation.panel.surface === "solid" ? "var(--ns-assistant-panel, var(--ns-assistant-default-panel))" : "color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 88%, transparent)"
4274
+ );
4275
+ host.style.setProperty(
4276
+ "--ns-assistant-presentation-shadow",
4277
+ panelShadow(presentation.panel.elevation)
4278
+ );
4279
+ host.style.setProperty(
4280
+ "--ns-assistant-presentation-border",
4281
+ panelBorder(presentation.panel.border)
4282
+ );
4283
+ replaceFallback(root, "launcher-icon", [launcherVisual(appearance, mode, sessionState)]);
4284
+ const accessibleStatus = root.querySelector("[data-session-status]");
4285
+ if (accessibleStatus) {
4286
+ accessibleStatus.hidden = presentation.launcher.status !== "session";
4287
+ accessibleStatus.textContent = sessionStateLabel(appearance, sessionState);
4288
+ }
4289
+ replaceFallback(root, "header-leading", headerLeading(appearance, mode));
4290
+ replaceFallback(root, "header-actions", headerBadge(appearance));
4291
+ replaceFallback(root, "empty-state", [emptyState(appearance)]);
4292
+ replaceFallback(root, "composer-leading", composerLeading(appearance, mode));
4293
+ replaceFallback(root, "conversation-footer", []);
4294
+ const form = root.querySelector("form");
4295
+ if (form) form.dataset.shape = presentation.composer.shape;
4296
+ const send = root.querySelector(".send");
4297
+ if (send) send.dataset.icon = presentation.composer.sendIcon;
4298
+ }
4299
+ function syncAssistantSessionVisualState(host, root, state, appearance) {
4300
+ host.dataset.sessionState = state;
4301
+ root?.querySelectorAll("[data-session-indicator]").forEach((indicator) => {
4302
+ indicator.dataset.state = state;
4303
+ });
4304
+ root?.querySelectorAll("[data-session-status]").forEach((status) => {
4305
+ status.textContent = sessionStateLabel(appearance, state);
4306
+ });
4307
+ }
4308
+ function panelShadow(elevation) {
4309
+ if (elevation === "dramatic") {
4310
+ return "0 34px 100px color-mix(in srgb, var(--ns-assistant-overlay, var(--ns-assistant-default-overlay)) 72%, transparent)";
4311
+ }
4312
+ return "var(--ns-assistant-default-shadow)";
4313
+ }
4314
+ function panelBorder(border) {
4315
+ if (border === "strong") {
4316
+ return "1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider))";
4317
+ }
4318
+ return "1px solid color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 74%, transparent)";
4319
+ }
4320
+ function launcherVisual(appearance, mode, sessionState) {
4321
+ const launcher = appearance.presentation.launcher;
4322
+ const visual = document.createElement("span");
4323
+ visual.className = "launcher-visual";
4324
+ visual.setAttribute("aria-hidden", "true");
4325
+ visual.append(icon(launcher.icon, appearance, mode, "launcher-glyph"));
4326
+ if (launcher.status === "session") {
4327
+ const status = document.createElement("span");
4328
+ status.className = "launcher-status";
4329
+ status.dataset.sessionIndicator = "";
4330
+ status.dataset.state = sessionState;
4331
+ visual.append(status);
4332
+ }
4333
+ return visual;
4334
+ }
4335
+ function sessionStateLabel(appearance, state) {
4336
+ if (state === "loading") return appearance.labels.sessionLoading;
4337
+ if (state === "ready") return appearance.labels.sessionReady;
4338
+ if (state === "error") return appearance.labels.sessionError;
4339
+ return appearance.labels.sessionIdle;
4340
+ }
4341
+ function headerLeading(appearance, mode) {
4342
+ const variant = appearance.presentation.header.mark;
4343
+ if (variant === "none") return [];
4344
+ const mark = document.createElement("span");
4345
+ mark.className = "header-mark";
4346
+ mark.dataset.variant = variant;
4347
+ mark.setAttribute("aria-hidden", "true");
4348
+ if (variant === "brand-mark") {
4349
+ mark.append(icon("brand-mark", appearance, mode, "header-mark-glyph"));
4350
+ } else {
4351
+ const core = document.createElement("span");
4352
+ core.className = "header-mark-core";
4353
+ mark.append(core);
4354
+ }
4355
+ return [mark];
4356
+ }
4357
+ function headerBadge(appearance) {
4358
+ const config = appearance.presentation.header;
4359
+ if (!config.badge) return [];
4360
+ const group = document.createElement("div");
4361
+ group.className = "header-actions";
4362
+ const badge = document.createElement("span");
4363
+ badge.className = "header-badge";
4364
+ badge.dataset.tone = config.badge.tone;
4365
+ if (config.badge.indicator) badge.append(toneIndicator(config.badge.tone));
4366
+ const text2 = document.createElement("span");
4367
+ text2.textContent = config.badge.text;
4368
+ badge.append(text2);
4369
+ group.append(badge);
4370
+ return [group];
4371
+ }
4372
+ function emptyState(appearance) {
4373
+ const section = document.createElement("section");
4374
+ section.className = "empty-state";
4375
+ const heading = document.createElement("h2");
4376
+ heading.textContent = appearance.labels.welcomeHeading;
4377
+ section.append(heading);
4378
+ const description = appearance.labels.welcomeMessage;
4379
+ if (description) {
4380
+ const paragraph = document.createElement("p");
4381
+ paragraph.textContent = description;
4382
+ section.append(paragraph);
4383
+ }
4384
+ return section;
4385
+ }
4386
+ function composerLeading(appearance, mode) {
4387
+ const leading = appearance.presentation.composer.leadingIcon;
4388
+ if (leading === "none") return [];
4389
+ const wrapper = document.createElement("span");
4390
+ wrapper.className = "composer-leading";
4391
+ wrapper.dataset.icon = leading;
4392
+ wrapper.setAttribute("aria-hidden", "true");
4393
+ wrapper.append(icon(leading, appearance, mode, "composer-leading-glyph"));
4394
+ return [wrapper];
4395
+ }
4396
+ function toneIndicator(tone) {
4397
+ const indicator = document.createElement("i");
4398
+ indicator.className = "tone-indicator";
4399
+ indicator.dataset.tone = tone;
4400
+ indicator.setAttribute("aria-hidden", "true");
4401
+ return indicator;
4402
+ }
4403
+ function icon(kind, appearance, mode, className) {
4404
+ const mark = appearance.brand.mark[mode];
4405
+ if (kind === "brand-mark" && mark) {
4406
+ const image = document.createElement("img");
4407
+ image.className = className;
4408
+ image.src = mark;
4409
+ image.alt = "";
4410
+ return image;
4411
+ }
4412
+ const glyph = document.createElement("span");
4413
+ glyph.className = className;
4414
+ glyph.dataset.icon = kind === "brand-mark" ? "sparkles" : kind;
4415
+ glyph.setAttribute("aria-hidden", "true");
4416
+ return glyph;
4417
+ }
4418
+ function replaceFallback(root, slotName, nodes) {
4419
+ const slot = root.querySelector(`slot[name="${slotName}"]`);
4420
+ slot?.replaceChildren(...nodes);
4421
+ }
4422
+
4423
+ // src/presentation-styles.ts
4424
+ var presentationStyles = `<style>
4425
+ :host([data-mode="floating"]) {
4426
+ bottom: var(--ns-assistant-edge-offset, var(--ns-assistant-default-edge-offset));
4427
+ right: var(--ns-assistant-edge-offset, var(--ns-assistant-default-edge-offset));
4428
+ }
4429
+ :host([data-mode="floating"][data-position="bottom-left"]) {
4430
+ right: auto;
4431
+ left: var(--ns-assistant-edge-offset, var(--ns-assistant-default-edge-offset));
4432
+ }
4433
+ .panel {
4434
+ background: var(--ns-assistant-panel-background, var(--ns-assistant-presentation-panel-background));
4435
+ border: var(--ns-assistant-panel-border, var(--ns-assistant-presentation-border));
4436
+ border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-presentation-panel-radius, var(--ns-assistant-default-panel-radius)));
4437
+ box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-presentation-shadow));
4438
+ }
4439
+ :host([data-panel-surface="solid"]) .panel {
4440
+ backdrop-filter: none;
4441
+ -webkit-backdrop-filter: none;
4442
+ }
4443
+
4444
+ .launcher {
4445
+ position: relative;
4446
+ width: var(--ns-assistant-launcher-size, var(--ns-assistant-presentation-launcher-size));
4447
+ height: var(--ns-assistant-launcher-size, var(--ns-assistant-presentation-launcher-size));
4448
+ border-radius: var(--ns-assistant-launcher-radius, var(--ns-assistant-default-launcher-radius));
4449
+ isolation: isolate;
4450
+ }
4451
+ :host([data-launcher-effect="pulse"]) .launcher {
4452
+ animation: assistant-launcher-pulse 2s ease-in-out infinite;
4453
+ }
4454
+ .launcher-visual {
4455
+ position: relative;
4456
+ display: grid;
4457
+ width: 100%;
4458
+ height: 100%;
4459
+ place-items: center;
4460
+ border-radius: inherit;
4461
+ }
4462
+ .launcher-glyph, .composer-leading-glyph {
4463
+ display: block;
4464
+ width: 18px;
4465
+ height: 18px;
4466
+ background: currentColor;
4467
+ -webkit-mask-position: center;
4468
+ -webkit-mask-repeat: no-repeat;
4469
+ -webkit-mask-size: contain;
4470
+ mask-position: center;
4471
+ mask-repeat: no-repeat;
4472
+ mask-size: contain;
4473
+ }
4474
+ [data-icon="sparkles"] {
4475
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 3 1.7 5.3L19 10l-5.3 1.7L12 17l-1.7-5.3L5 10l5.3-1.7L12 3Zm6 11 .8 2.2L21 17l-2.2.8L18 20l-.8-2.2L15 17l2.2-.8L18 14Z'/%3E%3C/svg%3E");
4476
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m12 3 1.7 5.3L19 10l-5.3 1.7L12 17l-1.7-5.3L5 10l5.3-1.7L12 3Zm6 11 .8 2.2L21 17l-2.2.8L18 20l-.8-2.2L15 17l2.2-.8L18 14Z'/%3E%3C/svg%3E");
4477
+ }
4478
+ [data-icon="chat"] {
4479
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 4h16v12H9l-5 4V4Zm4 5h8v2H8V9Z'/%3E%3C/svg%3E");
4480
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 4h16v12H9l-5 4V4Zm4 5h8v2H8V9Z'/%3E%3C/svg%3E");
4481
+ }
4482
+ [data-icon="none"] { display: none; }
4483
+ .launcher-glyph:is(img), .composer-leading-glyph:is(img), .header-mark-glyph:is(img) {
4484
+ background: none;
4485
+ object-fit: contain;
4486
+ -webkit-mask: none;
4487
+ mask: none;
4488
+ }
4489
+ .launcher-status {
4490
+ position: absolute;
4491
+ right: 1px;
4492
+ bottom: 1px;
4493
+ width: 10px;
4494
+ height: 10px;
4495
+ border: 2px solid var(--ns-assistant-panel, var(--ns-assistant-default-panel));
4496
+ border-radius: 50%;
4497
+ background: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text));
4498
+ }
4499
+ .launcher-status[data-state="loading"] {
4500
+ background: var(--ns-assistant-warning, var(--ns-assistant-default-warning));
4501
+ animation: assistant-launcher-pulse 1.2s ease-in-out infinite;
4502
+ }
4503
+ .launcher-status[data-state="ready"] {
4504
+ background: var(--ns-assistant-success, var(--ns-assistant-default-success));
4505
+ box-shadow: 0 0 9px color-mix(in srgb, var(--ns-assistant-success, var(--ns-assistant-default-success)) 70%, transparent);
4506
+ }
4507
+ .launcher-status[data-state="error"] {
4508
+ background: var(--ns-assistant-danger, var(--ns-assistant-default-danger));
4509
+ }
4510
+
4511
+ .header-mark {
4512
+ position: relative;
4513
+ display: grid;
4514
+ width: 26px;
4515
+ height: 26px;
4516
+ flex: 0 0 26px;
4517
+ place-items: center;
4518
+ color: var(--ns-assistant-accent, var(--ns-assistant-default-accent));
4519
+ }
4520
+ .header-mark[data-variant="status"] .header-mark-core {
4521
+ width: 9px;
4522
+ height: 9px;
4523
+ border-radius: 50%;
4524
+ background: var(--ns-assistant-success, var(--ns-assistant-default-success));
4525
+ box-shadow: 0 0 0 5px color-mix(in srgb, var(--ns-assistant-success, var(--ns-assistant-default-success)) 16%, transparent);
4526
+ }
4527
+ .header-mark-glyph {
4528
+ width: 24px;
4529
+ height: 24px;
4530
+ object-fit: contain;
4531
+ }
4532
+ .header-actions {
4533
+ display: flex;
4534
+ align-items: center;
4535
+ }
4536
+ .header-badge {
4537
+ display: inline-flex;
4538
+ align-items: center;
4539
+ gap: 6px;
4540
+ min-height: 28px;
4541
+ padding: 0 10px;
4542
+ border: 1px solid color-mix(in srgb, var(--presentation-tone, var(--ns-assistant-accent, var(--ns-assistant-default-accent))) 22%, transparent);
4543
+ border-radius: 999px;
4544
+ color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text));
4545
+ background: color-mix(in srgb, var(--presentation-tone, var(--ns-assistant-accent, var(--ns-assistant-default-accent))) 7%, transparent);
4546
+ font-family: var(--ns-assistant-mono-font-family, var(--ns-assistant-default-mono-font-family));
4547
+ font-size: 9px;
4548
+ font-weight: 650;
4549
+ letter-spacing: .11em;
4550
+ text-transform: uppercase;
4551
+ }
4552
+ [data-tone="success"] { --presentation-tone: var(--ns-assistant-success, var(--ns-assistant-default-success)); }
4553
+ [data-tone="warning"] { --presentation-tone: var(--ns-assistant-warning, var(--ns-assistant-default-warning)); }
4554
+ [data-tone="danger"] { --presentation-tone: var(--ns-assistant-danger, var(--ns-assistant-default-danger)); }
4555
+ [data-tone="neutral"] { --presentation-tone: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
4556
+ .tone-indicator {
4557
+ display: inline-block;
4558
+ width: 6px;
4559
+ height: 6px;
4560
+ flex: 0 0 6px;
4561
+ border-radius: 50%;
4562
+ background: var(--presentation-tone);
4563
+ box-shadow: 0 0 8px color-mix(in srgb, var(--presentation-tone) 72%, transparent);
4564
+ }
4565
+
4566
+ .empty-state { min-width: 0; }
4567
+ .composer-leading {
4568
+ display: grid;
4569
+ width: 20px;
4570
+ height: 20px;
4571
+ flex: 0 0 20px;
4572
+ place-items: center;
4573
+ color: var(--ns-assistant-accent, var(--ns-assistant-default-accent));
4574
+ }
4575
+ .composer-leading-glyph { width: 15px; height: 15px; }
4576
+ form[data-shape="rounded"] {
4577
+ border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius));
4578
+ }
4579
+ form[data-shape="pill"] { border-radius: 999px; }
4580
+ .send[data-icon="paper-plane"]::before {
4581
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m3 4 18 8-18 8 3-7 9-1-9-1-3-7Z'/%3E%3C/svg%3E");
4582
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m3 4 18 8-18 8 3-7 9-1-9-1-3-7Z'/%3E%3C/svg%3E");
4583
+ }
4584
+
4585
+ :host([data-message-user-style="accent"]) .message.user {
4586
+ color: var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text));
4587
+ background: var(--ns-assistant-accent, var(--ns-assistant-default-accent));
4588
+ }
4589
+ :host([data-message-user-style="accent"]) .message.user time {
4590
+ color: color-mix(in srgb, var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text)) 72%, transparent);
4591
+ }
4592
+ :host([data-message-assistant-style="bubble"]) .message.assistant {
4593
+ padding: 10px 14px;
4594
+ background: var(--ns-assistant-input, var(--ns-assistant-default-input));
4595
+ }
4596
+
4597
+ @keyframes assistant-launcher-pulse { 50% { opacity: .55; transform: scale(.9); } }
4598
+
4599
+ @media (max-width: 640px) {
4600
+ .header-badge { display: none; }
4601
+ }
4602
+ @media (prefers-reduced-motion: reduce) {
4603
+ .launcher, .launcher-status { animation: none !important; }
4604
+ }
4605
+ </style>`;
4606
+
4607
+ // src/element.ts
4608
+ var ASSISTANT_TAG_NAME = "noodle-assistant";
4609
+ var HTMLElementBase = globalThis.HTMLElement ?? class {
4610
+ };
4611
+ var NoodleAssistantElement = class extends HTMLElementBase {
4612
+ static observedAttributes = ["open", "theme"];
4613
+ #appearance = resolveAppearance();
4614
+ #client;
4615
+ #clientEndpoint = "";
4616
+ #unsubscribeClient;
4617
+ #sessionBootstrap;
4618
+ #conversationGeneration = 0;
4619
+ #messages;
4620
+ #thinking;
4621
+ #media;
4622
+ #context;
4623
+ #modelContext;
4624
+ #pendingUserEcho;
4625
+ #sessionState = "idle";
4626
+ #startOpenApplied = false;
4627
+ sessionEndpoint = "";
4628
+ #events = new AssistantElementEventController({
4629
+ element: this,
4630
+ messages: () => this.#messages,
4631
+ appendMessage: (role, text2) => {
4632
+ if (role === "user" && text2 === this.#pendingUserEcho) {
4633
+ this.#pendingUserEcho = void 0;
4634
+ return void 0;
4635
+ }
4636
+ return this.#appendMessage(role, text2);
4637
+ },
4638
+ applyConfiguration: (configuration) => {
4639
+ this.#appearance = resolveAppearance(configuration);
4640
+ this.#syncAppearance();
4641
+ this.#applyStartOpenPolicy();
4642
+ },
4643
+ labels: () => ({
4644
+ confirm: this.#appearance.labels.confirm,
1450
4645
  cancel: this.#appearance.labels.cancel
1451
4646
  }),
1452
4647
  respond: (id, response) => this.respond(id, response),
@@ -1459,22 +4654,27 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1459
4654
  this.#media?.addEventListener("change", this.#handleSystemTheme);
1460
4655
  document.addEventListener("keydown", this.#handleDocumentKeydown);
1461
4656
  document.addEventListener("pointerdown", this.#handleDocumentPointerDown);
1462
- if (this.#appearance.behavior.startOpen) this.setAttribute("open", "");
4657
+ if (this.#appearance.behavior.startOpen) this.#applyStartOpenPolicy();
1463
4658
  this.#render();
1464
4659
  this.dispatchEvent(new CustomEvent("assistant-ready"));
4660
+ this.#primeSession();
1465
4661
  }
1466
4662
  disconnectedCallback() {
4663
+ this.#conversationGeneration += 1;
1467
4664
  this.#client?.abort();
1468
4665
  this.#unsubscribeClient?.();
1469
4666
  this.#client = void 0;
1470
4667
  this.#clientEndpoint = "";
1471
4668
  this.#unsubscribeClient = void 0;
4669
+ this.#sessionBootstrap = void 0;
4670
+ this.#setBusy(false);
1472
4671
  this.#media?.removeEventListener("change", this.#handleSystemTheme);
1473
4672
  document.removeEventListener("keydown", this.#handleDocumentKeydown);
1474
4673
  document.removeEventListener("pointerdown", this.#handleDocumentPointerDown);
1475
4674
  }
1476
4675
  attributeChangedCallback(name) {
1477
4676
  if (name === "theme") this.#applyTheme();
4677
+ if (name === "open") this.#syncOpenState();
1478
4678
  }
1479
4679
  open() {
1480
4680
  this.setAttribute("open", "");
@@ -1491,11 +4691,18 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1491
4691
  this.shadowRoot?.querySelector("textarea")?.focus();
1492
4692
  }
1493
4693
  resetSession() {
1494
- if (this.#client) {
1495
- this.#client.resetSession();
1496
- } else {
1497
- this.#events.resetConversation();
1498
- }
4694
+ this.#conversationGeneration += 1;
4695
+ this.#client?.abort();
4696
+ this.#unsubscribeClient?.();
4697
+ this.#client = void 0;
4698
+ this.#clientEndpoint = "";
4699
+ this.#unsubscribeClient = void 0;
4700
+ this.#sessionBootstrap = void 0;
4701
+ this.#events.resetConversation();
4702
+ this.#pendingUserEcho = void 0;
4703
+ this.removeAttribute("has-messages");
4704
+ this.#setBusy(false);
4705
+ this.#setSessionState("idle");
1499
4706
  }
1500
4707
  updateContext(context) {
1501
4708
  this.#context = { ...context };
@@ -1520,14 +4727,25 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1520
4727
  );
1521
4728
  }
1522
4729
  }
1523
- async sendMessage(text) {
1524
- const message = text.trim();
4730
+ async sendMessage(text2) {
4731
+ const message = text2.trim();
1525
4732
  if (!message) return;
4733
+ const generation = this.#conversationGeneration;
4734
+ this.#pendingUserEcho = message;
4735
+ this.#appendMessage("user", message);
4736
+ this.#setBusy(true);
4737
+ if (this.#sessionState !== "ready") this.#setSessionState("loading");
1526
4738
  try {
4739
+ await this.#sessionBootstrap;
4740
+ if (generation !== this.#conversationGeneration) return;
1527
4741
  await this.#ensureClient().sendMessage(message);
1528
4742
  } catch (error) {
4743
+ if (generation !== this.#conversationGeneration) return;
1529
4744
  this.#dispatchClientError(error, "turn_failed");
1530
4745
  throw error;
4746
+ } finally {
4747
+ if (this.#pendingUserEcho === message) this.#pendingUserEcho = void 0;
4748
+ if (generation === this.#conversationGeneration) this.#setBusy(false);
1531
4749
  }
1532
4750
  }
1533
4751
  /**
@@ -1536,25 +4754,30 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1536
4754
  * never escape as unhandled rejections into the embedding page. Programmatic callers use
1537
4755
  * `sendMessage`/`confirmTool` directly and keep the rejection.
1538
4756
  */
1539
- #sendGuarded(text) {
1540
- void this.sendMessage(text).catch(() => {
4757
+ #sendGuarded(text2) {
4758
+ void this.sendMessage(text2).catch(() => {
1541
4759
  });
1542
4760
  }
1543
4761
  async confirmTool(id) {
1544
4762
  await this.respond(id, { action: "accept" });
1545
4763
  }
1546
4764
  async respond(id, response) {
4765
+ const generation = this.#conversationGeneration;
4766
+ this.#setBusy(true);
1547
4767
  try {
1548
4768
  await this.#ensureClient().respond(id, response);
1549
4769
  } catch (error) {
4770
+ if (generation !== this.#conversationGeneration) return;
1550
4771
  this.#dispatchClientError(error, "confirmation_failed");
1551
4772
  throw error;
4773
+ } finally {
4774
+ if (generation === this.#conversationGeneration) this.#setBusy(false);
1552
4775
  }
1553
4776
  }
1554
4777
  #handleSystemTheme = () => this.#applyTheme();
1555
4778
  #handleDocumentKeydown = (event) => {
1556
4779
  if (event.key === "Escape" && this.hasAttribute("open") && this.#appearance.behavior.closeOnEscape) {
1557
- this.close();
4780
+ this.#closeAndRestoreFocus();
1558
4781
  }
1559
4782
  };
1560
4783
  #handleDocumentPointerDown = (event) => {
@@ -1566,6 +4789,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1566
4789
  if (this.#client && this.#clientEndpoint === this.sessionEndpoint) return this.#client;
1567
4790
  this.#client?.abort();
1568
4791
  this.#unsubscribeClient?.();
4792
+ this.#sessionBootstrap = void 0;
1569
4793
  const client = createAssistantClient({
1570
4794
  sessionEndpoint: this.sessionEndpoint,
1571
4795
  ...this.#context ? { context: this.#context } : {},
@@ -1574,10 +4798,65 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1574
4798
  });
1575
4799
  this.#client = client;
1576
4800
  this.#clientEndpoint = this.sessionEndpoint;
1577
- this.#unsubscribeClient = client.subscribe((event) => this.#events.handle(event));
4801
+ this.#unsubscribeClient = client.subscribe((event) => {
4802
+ if (this.#client === client) this.#handleClientEvent(event);
4803
+ });
1578
4804
  return client;
1579
4805
  }
1580
- #appendMessage(role, text) {
4806
+ #primeSession() {
4807
+ if (!this.sessionEndpoint) return;
4808
+ const client = this.#ensureClient();
4809
+ const generation = this.#conversationGeneration;
4810
+ this.#setSessionState("loading");
4811
+ const bootstrap = client.connect().catch((error) => {
4812
+ if (generation !== this.#conversationGeneration || this.#client !== client) return;
4813
+ this.#dispatchClientError(error, "session_failed");
4814
+ }).finally(() => {
4815
+ if (this.#sessionBootstrap === bootstrap) this.#sessionBootstrap = void 0;
4816
+ });
4817
+ this.#sessionBootstrap = bootstrap;
4818
+ }
4819
+ #handleClientEvent(event) {
4820
+ this.#events.handle(event);
4821
+ if (event.event === "session_started") this.#setSessionState("ready");
4822
+ if (event.event === "session_expired" || event.event === "session_reset") {
4823
+ this.#setSessionState("idle");
4824
+ }
4825
+ if (event.event === "tool_proposed" || event.event === "interaction_proposed" || event.event === "input_requested") {
4826
+ this.#removeThinking();
4827
+ this.setAttribute("has-messages", "");
4828
+ this.#scrollToBottom();
4829
+ }
4830
+ if (event.event === "content" || event.event === "message_completed" || event.event === "interaction_completed" || event.event === "error") {
4831
+ this.#removeThinking();
4832
+ this.#scrollToBottom();
4833
+ }
4834
+ }
4835
+ #setBusy(busy) {
4836
+ this.toggleAttribute("busy", busy);
4837
+ const textarea = this.shadowRoot?.querySelector("textarea");
4838
+ const send = this.shadowRoot?.querySelector(".send");
4839
+ if (textarea) textarea.disabled = busy;
4840
+ if (send) send.disabled = busy;
4841
+ if (!busy) {
4842
+ this.#removeThinking();
4843
+ return;
4844
+ }
4845
+ if (!this.#messages || this.#thinking) return;
4846
+ const thinking = document.createElement("div");
4847
+ thinking.className = "message assistant thinking";
4848
+ const label = document.createElement("span");
4849
+ label.textContent = this.#appearance.labels.thinking;
4850
+ thinking.append(label);
4851
+ this.#messages.append(thinking);
4852
+ this.#thinking = thinking;
4853
+ this.#scrollToBottom();
4854
+ }
4855
+ #removeThinking() {
4856
+ this.#thinking?.remove();
4857
+ this.#thinking = void 0;
4858
+ }
4859
+ #appendMessage(role, text2) {
1581
4860
  if (!this.#messages) return void 0;
1582
4861
  const message = document.createElement("div");
1583
4862
  message.className = `message ${role}`;
@@ -1588,8 +4867,13 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1588
4867
  avatar.alt = "";
1589
4868
  message.append(avatar);
1590
4869
  }
1591
- const body = document.createElement("span");
1592
- body.textContent = text;
4870
+ const body = document.createElement(role === "assistant" ? "div" : "span");
4871
+ if (role === "assistant") {
4872
+ body.className = "markdown";
4873
+ body.innerHTML = renderMarkdown(text2);
4874
+ } else {
4875
+ body.textContent = text2;
4876
+ }
1593
4877
  message.append(body);
1594
4878
  if (this.#appearance.behavior.showTimestamps) {
1595
4879
  const timestamp = document.createElement("time");
@@ -1601,12 +4885,20 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1601
4885
  message.append(timestamp);
1602
4886
  }
1603
4887
  this.#messages.append(message);
4888
+ this.setAttribute("has-messages", "");
4889
+ this.#scrollToBottom();
1604
4890
  return body;
1605
4891
  }
4892
+ #scrollToBottom() {
4893
+ if (this.#messages) this.#messages.scrollTop = this.#messages.scrollHeight;
4894
+ }
1606
4895
  #dispatchError(detail) {
1607
4896
  this.dispatchEvent(new CustomEvent("assistant-error", { detail }));
1608
4897
  }
1609
4898
  #dispatchClientError(error, fallbackCode) {
4899
+ if (error instanceof AssistantClientError && error.detail.code === "session_failed") {
4900
+ this.#setSessionState("error");
4901
+ }
1610
4902
  this.#dispatchError(
1611
4903
  error instanceof AssistantClientError ? error.detail : { code: fallbackCode, retryable: false }
1612
4904
  );
@@ -1641,12 +4933,78 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1641
4933
  "--ns-assistant-default-z-index",
1642
4934
  String(this.#appearance.layout.zIndex)
1643
4935
  );
4936
+ this.style.setProperty(
4937
+ "--ns-assistant-default-edge-offset",
4938
+ `${this.#appearance.layout.edgeOffset}px`
4939
+ );
1644
4940
  const logo = this.shadowRoot?.querySelector(".brand-logo");
1645
4941
  const logoUrl = this.#appearance.brand.logo[mode];
1646
4942
  if (logo) {
1647
4943
  logo.hidden = !logoUrl;
1648
4944
  if (logoUrl) logo.src = logoUrl;
1649
4945
  }
4946
+ if (this.shadowRoot) {
4947
+ syncAssistantPresentation(this, this.shadowRoot, this.#appearance, mode, this.#sessionState);
4948
+ }
4949
+ }
4950
+ #setSessionState(state) {
4951
+ this.#sessionState = state;
4952
+ syncAssistantSessionVisualState(this, this.shadowRoot, state, this.#appearance);
4953
+ }
4954
+ #syncOpenState() {
4955
+ this.shadowRoot?.querySelector(".launcher")?.setAttribute("aria-expanded", String(this.hasAttribute("open")));
4956
+ }
4957
+ #closeAndRestoreFocus() {
4958
+ this.close();
4959
+ this.shadowRoot?.querySelector(".launcher")?.focus();
4960
+ }
4961
+ #applyStartOpenPolicy() {
4962
+ if (this.#startOpenApplied) return;
4963
+ this.#startOpenApplied = true;
4964
+ if (this.#appearance.behavior.startOpen) this.setAttribute("open", "");
4965
+ }
4966
+ #syncAppearance() {
4967
+ if (!this.shadowRoot) return;
4968
+ const appearance = this.#appearance;
4969
+ this.setAttribute("aria-label", appearance.brand.name);
4970
+ this.setAttribute("lang", appearance.locale);
4971
+ this.setAttribute("dir", appearance.direction);
4972
+ this.dataset.mode = appearance.layout.mode;
4973
+ this.dataset.position = appearance.layout.position;
4974
+ this.dataset.density = appearance.layout.density;
4975
+ this.toggleAttribute("mobile-fullscreen", appearance.layout.mobileFullscreen);
4976
+ queryRequired(this.shadowRoot, ".panel").setAttribute(
4977
+ "aria-label",
4978
+ appearance.brand.name
4979
+ );
4980
+ queryRequired(this.shadowRoot, "header strong").textContent = appearance.brand.name;
4981
+ const textarea = queryRequired(this.shadowRoot, "textarea");
4982
+ textarea.placeholder = appearance.labels.composerPlaceholder;
4983
+ textarea.setAttribute("aria-label", appearance.labels.composerPlaceholder);
4984
+ queryRequired(this.shadowRoot, ".send").textContent = appearance.labels.send;
4985
+ queryRequired(this.shadowRoot, ".launcher").setAttribute(
4986
+ "aria-label",
4987
+ appearance.labels.open
4988
+ );
4989
+ queryRequired(this.shadowRoot, ".close").setAttribute(
4990
+ "aria-label",
4991
+ appearance.labels.close
4992
+ );
4993
+ const prompts = queryRequired(this.shadowRoot, ".suggested-prompts");
4994
+ prompts.replaceChildren();
4995
+ for (const prompt of appearance.suggestedPrompts) {
4996
+ const button2 = document.createElement("button");
4997
+ button2.type = "button";
4998
+ button2.textContent = prompt;
4999
+ button2.addEventListener("click", () => this.#sendGuarded(prompt));
5000
+ prompts.append(button2);
5001
+ }
5002
+ queryRequired(this.shadowRoot, ".launcher").hidden = !appearance.behavior.showLauncher;
5003
+ queryRequired(this.shadowRoot, "header").hidden = !appearance.behavior.showHeader;
5004
+ const legal = queryRequired(this.shadowRoot, ".legal");
5005
+ legal.replaceChildren();
5006
+ this.#appendLegalLinks(legal);
5007
+ this.#applyTheme();
1650
5008
  }
1651
5009
  #render() {
1652
5010
  if (!this.shadowRoot) return;
@@ -1660,11 +5018,11 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1660
5018
  this.dataset.position = appearance.layout.position;
1661
5019
  this.dataset.density = appearance.layout.density;
1662
5020
  this.toggleAttribute("mobile-fullscreen", appearance.layout.mobileFullscreen);
1663
- this.shadowRoot.innerHTML = `${ASSISTANT_ELEMENT_STYLES}
1664
- <button class="launcher" type="button" aria-label="${escapeAttribute(appearance.labels.open)}"><slot name="launcher-icon">\u2726</slot></button>
1665
- <section class="panel" aria-label="${escapeAttribute(appearance.brand.name)}">
5021
+ this.shadowRoot.innerHTML = `${ASSISTANT_ELEMENT_STYLES}${presentationStyles}
5022
+ <button class="launcher" type="button" aria-label="${escapeAttribute(appearance.labels.open)}" aria-controls="assistant-panel" aria-expanded="${String(this.hasAttribute("open"))}"><slot name="launcher-icon"></slot><span class="visually-hidden" data-session-status aria-live="polite" hidden></span></button>
5023
+ <section class="panel" id="assistant-panel" role="dialog" aria-label="${escapeAttribute(appearance.brand.name)}">
1666
5024
  <header><slot name="header-leading"></slot><img class="brand-logo" alt=""><strong></strong><slot name="header-actions"></slot><button class="close" type="button" aria-label="${escapeAttribute(appearance.labels.close)}">\xD7</button></header>
1667
- <div class="welcome"><slot name="empty-state"><h2></h2><p></p></slot></div>
5025
+ <div class="welcome"><slot name="empty-state"></slot></div>
1668
5026
  <div class="suggested-prompts"></div>
1669
5027
  <div class="messages" aria-live="polite"></div>
1670
5028
  <form><slot name="composer-leading"></slot><textarea rows="1"></textarea><button class="send" type="submit"></button><slot name="composer-trailing"></slot></form>
@@ -1672,17 +5030,6 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1672
5030
  <slot name="conversation-footer"></slot>
1673
5031
  </section>`;
1674
5032
  queryRequired(this.shadowRoot, "strong").textContent = appearance.brand.name;
1675
- const launcherIcon = appearance.brand.mark[this.#resolvedMode()];
1676
- if (launcherIcon) {
1677
- const launcherSlot = queryRequired(
1678
- this.shadowRoot,
1679
- 'slot[name="launcher-icon"]'
1680
- );
1681
- const icon = document.createElement("img");
1682
- icon.src = launcherIcon;
1683
- icon.alt = "";
1684
- launcherSlot.replaceChildren(icon);
1685
- }
1686
5033
  const logo = queryRequired(this.shadowRoot, ".brand-logo");
1687
5034
  const logoUrl = appearance.brand.logo[this.#resolvedMode()];
1688
5035
  if (logoUrl) {
@@ -1691,8 +5038,6 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1691
5038
  } else {
1692
5039
  logo.hidden = true;
1693
5040
  }
1694
- queryRequired(this.shadowRoot, "h2").textContent = appearance.labels.welcomeHeading;
1695
- queryRequired(this.shadowRoot, "p").textContent = appearance.labels.welcomeMessage;
1696
5041
  const textarea = queryRequired(this.shadowRoot, "textarea");
1697
5042
  textarea.placeholder = appearance.labels.composerPlaceholder;
1698
5043
  textarea.setAttribute("aria-label", appearance.labels.composerPlaceholder);
@@ -1710,9 +5055,38 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1710
5055
  if (!appearance.behavior.showHeader)
1711
5056
  queryRequired(this.shadowRoot, "header").hidden = true;
1712
5057
  const legal = queryRequired(this.shadowRoot, ".legal");
5058
+ this.#appendLegalLinks(legal);
5059
+ this.#messages = this.shadowRoot.querySelector(".messages") ?? void 0;
5060
+ this.#messages?.append(...conversation);
5061
+ this.#thinking = this.#messages?.querySelector(".thinking") ?? void 0;
5062
+ this.shadowRoot.querySelector(".launcher")?.addEventListener("click", () => {
5063
+ this.open();
5064
+ this.focusComposer();
5065
+ });
5066
+ this.shadowRoot.querySelector(".close")?.addEventListener("click", () => this.#closeAndRestoreFocus());
5067
+ const form = queryRequired(this.shadowRoot, "form");
5068
+ form.addEventListener("submit", (event) => {
5069
+ event.preventDefault();
5070
+ const value = textarea.value;
5071
+ textarea.value = "";
5072
+ textarea.style.height = "auto";
5073
+ this.#sendGuarded(value);
5074
+ });
5075
+ textarea.addEventListener("input", () => {
5076
+ textarea.style.height = "auto";
5077
+ textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
5078
+ });
5079
+ textarea.addEventListener("keydown", (event) => {
5080
+ if (event.key !== "Enter" || event.shiftKey || event.isComposing) return;
5081
+ event.preventDefault();
5082
+ form.requestSubmit();
5083
+ });
5084
+ this.#applyTheme();
5085
+ }
5086
+ #appendLegalLinks(legal) {
1713
5087
  for (const [label, href] of [
1714
- ["Privacy", appearance.privacyUrl],
1715
- ["Terms", appearance.termsUrl]
5088
+ ["Privacy", this.#appearance.privacyUrl],
5089
+ ["Terms", this.#appearance.termsUrl]
1716
5090
  ]) {
1717
5091
  if (!href) continue;
1718
5092
  const link = document.createElement("a");
@@ -1722,17 +5096,6 @@ var NoodleAssistantElement = class extends HTMLElementBase {
1722
5096
  link.textContent = label;
1723
5097
  legal.append(link);
1724
5098
  }
1725
- this.#messages = this.shadowRoot.querySelector(".messages") ?? void 0;
1726
- this.#messages?.append(...conversation);
1727
- this.shadowRoot.querySelector(".launcher")?.addEventListener("click", () => this.open());
1728
- this.shadowRoot.querySelector(".close")?.addEventListener("click", () => this.close());
1729
- this.shadowRoot.querySelector("form")?.addEventListener("submit", (event) => {
1730
- event.preventDefault();
1731
- const value = textarea.value;
1732
- textarea.value = "";
1733
- this.#sendGuarded(value);
1734
- });
1735
- this.#applyTheme();
1736
5099
  }
1737
5100
  };
1738
5101
  function registerNoodleAssistant() {
@@ -1740,22 +5103,6 @@ function registerNoodleAssistant() {
1740
5103
  customElements.define(ASSISTANT_TAG_NAME, NoodleAssistantElement);
1741
5104
  }
1742
5105
  }
1743
- function camelToKebab(value) {
1744
- return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
1745
- }
1746
- function tokenValue(name, value) {
1747
- if (typeof value !== "number") return value;
1748
- if (name === "lineHeight" || name === "motionScale") return String(value);
1749
- return `${value}px`;
1750
- }
1751
- function escapeAttribute(value) {
1752
- return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;");
1753
- }
1754
- function queryRequired(root, selector) {
1755
- const element = root.querySelector(selector);
1756
- if (!element) throw new Error(`assistant renderer is missing ${selector}`);
1757
- return element;
1758
- }
1759
5106
 
1760
5107
  // src/index.ts
1761
5108
  registerNoodleAssistant();
@@ -1765,4 +5112,9 @@ registerNoodleAssistant();
1765
5112
  NoodleAssistantElement,
1766
5113
  registerNoodleAssistant
1767
5114
  });
5115
+ /*! Bundled license information:
5116
+
5117
+ dompurify/dist/purify.es.mjs:
5118
+ (*! @license DOMPurify 3.4.11 | (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.11/LICENSE *)
5119
+ */
1768
5120
  //# sourceMappingURL=index.cjs.map