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