@artooi/ag-ui-web-component 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +99 -1
- package/README.md +242 -50
- package/dist/ag-ui-web-component.bundle.js +451 -46
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +34 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/{ag_ui_chat.d.ts → core/ag_ui_chat.d.ts} +63 -6
- package/dist/core/ag_ui_chat.d.ts.map +1 -0
- package/dist/{agui_client.d.ts → core/agui_client.d.ts} +13 -0
- package/dist/core/agui_client.d.ts.map +1 -0
- package/dist/core/conversation_store.d.ts.map +1 -0
- package/dist/core/create_http_agent.d.ts.map +1 -0
- package/dist/core/define_ag_ui_chat.d.ts.map +1 -0
- package/dist/dom/animations.d.ts +71 -0
- package/dist/dom/animations.d.ts.map +1 -0
- package/dist/{dom_driver.d.ts → dom/dom_driver.d.ts} +7 -1
- package/dist/dom/dom_driver.d.ts.map +1 -0
- package/dist/dom/native_setter.d.ts +5 -0
- package/dist/dom/native_setter.d.ts.map +1 -0
- package/dist/index.d.ts +19 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3934 -373
- package/dist/index.js.map +4 -4
- package/dist/skills/fill_template.d.ts +17 -0
- package/dist/skills/fill_template.d.ts.map +1 -0
- package/dist/skills/parse_skills.d.ts +8 -0
- package/dist/skills/parse_skills.d.ts.map +1 -0
- package/dist/skills/skill.d.ts +24 -0
- package/dist/skills/skill.d.ts.map +1 -0
- package/dist/{client_tool_registry.d.ts → tools/client_tool_registry.d.ts} +6 -1
- package/dist/tools/client_tool_registry.d.ts.map +1 -0
- package/dist/tools/is_destructive.d.ts.map +1 -0
- package/dist/tools/is_navigates.d.ts.map +1 -0
- package/dist/tools/page_map.d.ts.map +1 -0
- package/dist/tools/route_map.d.ts +40 -0
- package/dist/tools/route_map.d.ts.map +1 -0
- package/dist/tools/state_hook.d.ts.map +1 -0
- package/dist/ui/confirmation_card.d.ts +22 -0
- package/dist/ui/confirmation_card.d.ts.map +1 -0
- package/dist/ui/render_markdown.d.ts +13 -0
- package/dist/ui/render_markdown.d.ts.map +1 -0
- package/dist/ui/reveal_words.d.ts +8 -0
- package/dist/ui/reveal_words.d.ts.map +1 -0
- package/dist/ui/skills_menu.d.ts +35 -0
- package/dist/ui/skills_menu.d.ts.map +1 -0
- package/dist/ui/styles.d.ts +2 -0
- package/dist/ui/styles.d.ts.map +1 -0
- package/dist/ui/tool_call_card.d.ts +35 -0
- package/dist/ui/tool_call_card.d.ts.map +1 -0
- package/package.json +5 -3
- package/src/constants.ts +38 -0
- package/src/core/ag_ui_chat.ts +851 -0
- package/src/{agui_client.ts → core/agui_client.ts} +19 -1
- package/src/{define_ag_ui_chat.ts → core/define_ag_ui_chat.ts} +1 -1
- package/src/dom/animations.ts +201 -0
- package/src/{dom_driver.ts → dom/dom_driver.ts} +35 -2
- package/src/dom/native_setter.ts +42 -0
- package/src/index.ts +61 -32
- package/src/skills/fill_template.ts +32 -0
- package/src/skills/parse_skills.ts +26 -0
- package/src/skills/skill.ts +23 -0
- package/src/{client_tool_registry.ts → tools/client_tool_registry.ts} +6 -4
- package/src/{is_destructive.ts → tools/is_destructive.ts} +1 -1
- package/src/{is_navigates.ts → tools/is_navigates.ts} +1 -1
- package/src/tools/route_map.ts +140 -0
- package/src/{state_hook.ts → tools/state_hook.ts} +1 -1
- package/src/ui/confirmation_card.ts +71 -0
- package/src/ui/render_markdown.ts +68 -0
- package/src/ui/reveal_words.ts +41 -0
- package/src/ui/skills_menu.ts +171 -0
- package/src/ui/styles.ts +631 -0
- package/src/{tool_call_card.ts → ui/tool_call_card.ts} +50 -19
- package/src/version.ts +1 -1
- package/dist/ag_ui_chat.d.ts.map +0 -1
- package/dist/agui_client.d.ts.map +0 -1
- package/dist/animations.d.ts +0 -33
- package/dist/animations.d.ts.map +0 -1
- package/dist/client_tool_registry.d.ts.map +0 -1
- package/dist/confirmation_modal.d.ts +0 -14
- package/dist/confirmation_modal.d.ts.map +0 -1
- package/dist/conversation_store.d.ts.map +0 -1
- package/dist/create_http_agent.d.ts.map +0 -1
- package/dist/define_ag_ui_chat.d.ts.map +0 -1
- package/dist/dom_driver.d.ts.map +0 -1
- package/dist/is_destructive.d.ts.map +0 -1
- package/dist/is_navigates.d.ts.map +0 -1
- package/dist/page_map.d.ts.map +0 -1
- package/dist/route_map.d.ts +0 -27
- package/dist/route_map.d.ts.map +0 -1
- package/dist/state_hook.d.ts.map +0 -1
- package/dist/styles.d.ts +0 -2
- package/dist/styles.d.ts.map +0 -1
- package/dist/tool_call_card.d.ts +0 -29
- package/dist/tool_call_card.d.ts.map +0 -1
- package/src/ag_ui_chat.ts +0 -411
- package/src/animations.ts +0 -86
- package/src/confirmation_modal.ts +0 -69
- package/src/route_map.ts +0 -83
- package/src/styles.ts +0 -296
- /package/dist/{conversation_store.d.ts → core/conversation_store.d.ts} +0 -0
- /package/dist/{create_http_agent.d.ts → core/create_http_agent.d.ts} +0 -0
- /package/dist/{define_ag_ui_chat.d.ts → core/define_ag_ui_chat.d.ts} +0 -0
- /package/dist/{is_destructive.d.ts → tools/is_destructive.d.ts} +0 -0
- /package/dist/{is_navigates.d.ts → tools/is_navigates.d.ts} +0 -0
- /package/dist/{page_map.d.ts → tools/page_map.d.ts} +0 -0
- /package/dist/{state_hook.d.ts → tools/state_hook.d.ts} +0 -0
- /package/src/{conversation_store.ts → core/conversation_store.ts} +0 -0
- /package/src/{create_http_agent.ts → core/create_http_agent.ts} +0 -0
- /package/src/{page_map.ts → tools/page_map.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
// src/agui_client.ts
|
|
2
|
-
import { randomUUID } from "@ag-ui/client";
|
|
3
|
-
|
|
4
1
|
// src/constants.ts
|
|
5
2
|
var ELEMENT_TAG = "ag-ui-chat";
|
|
6
3
|
var SUBMIT_EVENT = "ag-ui-submit";
|
|
4
|
+
var TOGGLE_EVENT = "ag-ui-toggle";
|
|
7
5
|
var MESSAGE_ROLE = {
|
|
8
6
|
USER: "user",
|
|
9
7
|
ASSISTANT: "assistant"
|
|
10
8
|
};
|
|
11
9
|
var X_DESTRUCTIVE_KEY = "x-destructive";
|
|
10
|
+
var X_CONFIRM_KEY = "x-confirm";
|
|
11
|
+
var X_SUMMARY_KEY = "x-summary";
|
|
12
12
|
var X_NAVIGATES_KEY = "x-navigates";
|
|
13
13
|
var MAX_TOOL_ROUNDS = 10;
|
|
14
14
|
var TOOL_CALL_STATUS = {
|
|
@@ -17,137 +17,54 @@ var TOOL_CALL_STATUS = {
|
|
|
17
17
|
ERROR: "error",
|
|
18
18
|
DECLINED: "declined"
|
|
19
19
|
};
|
|
20
|
+
var TOOL_DISPLAY = {
|
|
21
|
+
MINIMAL: "minimal",
|
|
22
|
+
COMPACT: "compact",
|
|
23
|
+
FULL: "full"
|
|
24
|
+
};
|
|
20
25
|
|
|
21
|
-
// src/
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.#agent = config.agent;
|
|
31
|
-
this.#handlers = config.handlers;
|
|
32
|
-
this.#getTools = config.getTools ?? (() => []);
|
|
33
|
-
this.#getContext = config.getContext ?? (() => []);
|
|
34
|
-
this.#executeTool = config.executeTool ?? null;
|
|
35
|
-
this.#onPersist = config.onPersist ?? (() => {
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
/** Whether a run is currently in flight. */
|
|
39
|
-
get running() {
|
|
40
|
-
return this.#agent.isRunning;
|
|
41
|
-
}
|
|
42
|
-
/** The current conversation history (for persistence / rehydration). */
|
|
43
|
-
get messages() {
|
|
44
|
-
return this.#agent.messages;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Append a user message and run the agent to completion.
|
|
48
|
-
*
|
|
49
|
-
* When the agent calls frontend tools, this executes them and re-runs the
|
|
50
|
-
* agent with the results, looping until the agent stops calling frontend
|
|
51
|
-
* tools (bounded by {@link MAX_TOOL_ROUNDS}).
|
|
52
|
-
*/
|
|
53
|
-
async send(content) {
|
|
54
|
-
this.#agent.addMessage({ id: randomUUID(), role: "user", content });
|
|
55
|
-
this.#onPersist(this.#agent.messages);
|
|
56
|
-
await this.#run();
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Resume the run loop after a navigating tool's result was supplied
|
|
60
|
-
* post-reload (via {@link addToolResult}). Unlike {@link send}, adds no user
|
|
61
|
-
* message — it simply continues the conversation already in history.
|
|
62
|
-
*/
|
|
63
|
-
async resume() {
|
|
64
|
-
await this.#run();
|
|
65
|
-
}
|
|
66
|
-
/** Append a frontend tool result to history (used by the resume path). */
|
|
67
|
-
addToolResult(toolCallId, content) {
|
|
68
|
-
this.#agent.addMessage({ id: randomUUID(), role: "tool", content, toolCallId });
|
|
69
|
-
this.#onPersist(this.#agent.messages);
|
|
70
|
-
}
|
|
71
|
-
async #run() {
|
|
72
|
-
try {
|
|
73
|
-
await this.#runLoop();
|
|
74
|
-
} catch (error) {
|
|
75
|
-
this.#handlers.onError(error instanceof Error ? error.message : String(error));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
async #runLoop() {
|
|
79
|
-
for (let round = 0; round < MAX_TOOL_ROUNDS; round += 1) {
|
|
80
|
-
const pending = [];
|
|
81
|
-
await this.#agent.runAgent(
|
|
82
|
-
{ tools: this.#getTools(), context: this.#getContext() },
|
|
83
|
-
this.#buildSubscriber(pending)
|
|
84
|
-
);
|
|
85
|
-
this.#onPersist(this.#agent.messages);
|
|
86
|
-
if (this.#executeTool === null || pending.length === 0) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
let executed = false;
|
|
90
|
-
for (const call of pending) {
|
|
91
|
-
const result = await this.#executeTool(call);
|
|
92
|
-
if (result === null) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (result.halt === true) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
this.#agent.addMessage({
|
|
99
|
-
id: randomUUID(),
|
|
100
|
-
role: "tool",
|
|
101
|
-
content: result.content,
|
|
102
|
-
toolCallId: call.id
|
|
103
|
-
});
|
|
104
|
-
this.#onPersist(this.#agent.messages);
|
|
105
|
-
executed = true;
|
|
106
|
-
}
|
|
107
|
-
if (!executed) {
|
|
108
|
-
return;
|
|
26
|
+
// src/skills/fill_template.ts
|
|
27
|
+
var PLACEHOLDER_RE = /\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
28
|
+
function fillTemplate(template, values) {
|
|
29
|
+
const missing = [];
|
|
30
|
+
const text2 = template.replace(PLACEHOLDER_RE, (token, key) => {
|
|
31
|
+
const value = values[key];
|
|
32
|
+
if (value === void 0 || value === null || value === "") {
|
|
33
|
+
if (!missing.includes(key)) {
|
|
34
|
+
missing.push(key);
|
|
109
35
|
}
|
|
36
|
+
return token;
|
|
110
37
|
}
|
|
38
|
+
return String(value);
|
|
39
|
+
});
|
|
40
|
+
return { text: text2, missing };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/skills/parse_skills.ts
|
|
44
|
+
function isSkill(value) {
|
|
45
|
+
if (typeof value !== "object" || value === null) {
|
|
46
|
+
return false;
|
|
111
47
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
onTextMessageContentEvent({ textMessageBuffer }) {
|
|
119
|
-
h.onTextDelta(textMessageBuffer);
|
|
120
|
-
},
|
|
121
|
-
onTextMessageEndEvent({ textMessageBuffer }) {
|
|
122
|
-
h.onTextEnd(textMessageBuffer);
|
|
123
|
-
},
|
|
124
|
-
onToolCallEndEvent({ event, toolCallName, toolCallArgs }) {
|
|
125
|
-
const call = {
|
|
126
|
-
id: event.toolCallId,
|
|
127
|
-
name: toolCallName,
|
|
128
|
-
args: toolCallArgs
|
|
129
|
-
};
|
|
130
|
-
pending.push(call);
|
|
131
|
-
h.onToolCall(call);
|
|
132
|
-
},
|
|
133
|
-
onRunErrorEvent({ event }) {
|
|
134
|
-
h.onError(event.message);
|
|
135
|
-
},
|
|
136
|
-
onRunFinalized() {
|
|
137
|
-
h.onRunEnd();
|
|
138
|
-
}
|
|
139
|
-
};
|
|
48
|
+
const record = value;
|
|
49
|
+
return typeof record["name"] === "string" && typeof record["title"] === "string" && typeof record["prompt"] === "string";
|
|
50
|
+
}
|
|
51
|
+
function parseSkills(value) {
|
|
52
|
+
if (!Array.isArray(value)) {
|
|
53
|
+
return [];
|
|
140
54
|
}
|
|
141
|
-
|
|
55
|
+
return value.filter(isSkill);
|
|
56
|
+
}
|
|
142
57
|
|
|
143
|
-
// src/client_tool_registry.ts
|
|
58
|
+
// src/tools/client_tool_registry.ts
|
|
144
59
|
var ClientToolRegistry = class {
|
|
145
60
|
#tools = /* @__PURE__ */ new Map();
|
|
146
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Register a tool, replacing any existing one with the same name.
|
|
63
|
+
*
|
|
64
|
+
* Idempotent on the name so re-fired host refs / React StrictMode's
|
|
65
|
+
* double-invoke don't throw — re-registering is a replace, not an error.
|
|
66
|
+
*/
|
|
147
67
|
register(tool) {
|
|
148
|
-
if (this.#tools.has(tool.name)) {
|
|
149
|
-
throw new Error(`tool "${tool.name}" already registered`);
|
|
150
|
-
}
|
|
151
68
|
this.#tools.set(tool.name, tool);
|
|
152
69
|
}
|
|
153
70
|
has(name) {
|
|
@@ -171,131 +88,17 @@ var ClientToolRegistry = class {
|
|
|
171
88
|
}
|
|
172
89
|
};
|
|
173
90
|
|
|
174
|
-
// src/
|
|
175
|
-
function requestConfirmation(host, request) {
|
|
176
|
-
return new Promise((resolve) => {
|
|
177
|
-
const overlay = document.createElement("div");
|
|
178
|
-
overlay.className = "modal-overlay";
|
|
179
|
-
const dialog = document.createElement("div");
|
|
180
|
-
dialog.className = "modal";
|
|
181
|
-
const title = document.createElement("div");
|
|
182
|
-
title.className = "modal-title";
|
|
183
|
-
title.textContent = "Confirm action";
|
|
184
|
-
const body = document.createElement("div");
|
|
185
|
-
body.className = "modal-body";
|
|
186
|
-
body.textContent = `Run \u201C${request.toolName}\u201D?`;
|
|
187
|
-
const args = document.createElement("pre");
|
|
188
|
-
args.className = "modal-args";
|
|
189
|
-
args.textContent = JSON.stringify(request.args, null, 2);
|
|
190
|
-
const actions = document.createElement("div");
|
|
191
|
-
actions.className = "modal-actions";
|
|
192
|
-
const cancel = document.createElement("button");
|
|
193
|
-
cancel.className = "modal-btn modal-btn--cancel";
|
|
194
|
-
cancel.type = "button";
|
|
195
|
-
cancel.textContent = "Cancel";
|
|
196
|
-
const confirm = document.createElement("button");
|
|
197
|
-
confirm.className = "modal-btn modal-btn--confirm";
|
|
198
|
-
confirm.type = "button";
|
|
199
|
-
confirm.textContent = "Run";
|
|
200
|
-
const close = (accepted) => {
|
|
201
|
-
overlay.remove();
|
|
202
|
-
resolve(accepted);
|
|
203
|
-
};
|
|
204
|
-
cancel.addEventListener("click", () => close(false));
|
|
205
|
-
confirm.addEventListener("click", () => close(true));
|
|
206
|
-
overlay.addEventListener("click", (event) => {
|
|
207
|
-
if (event.target === overlay) {
|
|
208
|
-
close(false);
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
actions.append(cancel, confirm);
|
|
212
|
-
dialog.append(title, body, args, actions);
|
|
213
|
-
overlay.append(dialog);
|
|
214
|
-
host.appendChild(overlay);
|
|
215
|
-
confirm.focus();
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// src/conversation_store.ts
|
|
220
|
-
import { randomUUID as randomUUID2 } from "@ag-ui/client";
|
|
221
|
-
var THREAD_KEY = "ag-ui-chat:thread";
|
|
222
|
-
var MESSAGES_PREFIX = "ag-ui-chat:messages:";
|
|
223
|
-
var CHECKPOINT_PREFIX = "ag-ui-chat:checkpoint:";
|
|
224
|
-
var SessionStorageStore = class {
|
|
225
|
-
threadId() {
|
|
226
|
-
const existing = sessionStorage.getItem(THREAD_KEY);
|
|
227
|
-
if (existing !== null) {
|
|
228
|
-
return existing;
|
|
229
|
-
}
|
|
230
|
-
const id = randomUUID2();
|
|
231
|
-
sessionStorage.setItem(THREAD_KEY, id);
|
|
232
|
-
return id;
|
|
233
|
-
}
|
|
234
|
-
loadMessages(threadId) {
|
|
235
|
-
return Promise.resolve(this.#readJson(MESSAGES_PREFIX + threadId));
|
|
236
|
-
}
|
|
237
|
-
saveMessages(threadId, messages) {
|
|
238
|
-
sessionStorage.setItem(MESSAGES_PREFIX + threadId, JSON.stringify(messages));
|
|
239
|
-
}
|
|
240
|
-
loadCheckpoint(threadId) {
|
|
241
|
-
return this.#readJson(CHECKPOINT_PREFIX + threadId);
|
|
242
|
-
}
|
|
243
|
-
saveCheckpoint(threadId, checkpoint) {
|
|
244
|
-
const key = CHECKPOINT_PREFIX + threadId;
|
|
245
|
-
if (checkpoint === null) {
|
|
246
|
-
sessionStorage.removeItem(key);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
sessionStorage.setItem(key, JSON.stringify(checkpoint));
|
|
250
|
-
}
|
|
251
|
-
clear(threadId) {
|
|
252
|
-
sessionStorage.removeItem(MESSAGES_PREFIX + threadId);
|
|
253
|
-
sessionStorage.removeItem(CHECKPOINT_PREFIX + threadId);
|
|
254
|
-
sessionStorage.removeItem(THREAD_KEY);
|
|
255
|
-
}
|
|
256
|
-
/** Parse a stored JSON value, returning `null` when absent or corrupt. */
|
|
257
|
-
#readJson(key) {
|
|
258
|
-
const raw = sessionStorage.getItem(key);
|
|
259
|
-
if (raw === null) {
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
try {
|
|
263
|
-
return JSON.parse(raw);
|
|
264
|
-
} catch {
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
// src/create_http_agent.ts
|
|
271
|
-
import { HttpAgent } from "@ag-ui/client";
|
|
272
|
-
function createHttpAgent(options) {
|
|
273
|
-
return new HttpAgent({
|
|
274
|
-
url: options.endpoint,
|
|
275
|
-
headers: options.headers ?? {},
|
|
276
|
-
// HttpAgent invokes its configured fetch as a method (`this.fetch(...)`),
|
|
277
|
-
// which would rebind the global `fetch` to the agent instance and trigger
|
|
278
|
-
// "Illegal invocation" in browsers. Wrap it so `fetch` is always called as
|
|
279
|
-
// a free function with the correct receiver.
|
|
280
|
-
fetch: (url, init) => fetch(url, init),
|
|
281
|
-
// Spread conditionally: under `exactOptionalPropertyTypes` an explicit
|
|
282
|
-
// `undefined` is not assignable to these optional config fields.
|
|
283
|
-
...options.threadId !== void 0 ? { threadId: options.threadId } : {},
|
|
284
|
-
...options.initialMessages !== void 0 ? { initialMessages: [...options.initialMessages] } : {}
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// src/is_destructive.ts
|
|
91
|
+
// src/tools/is_destructive.ts
|
|
289
92
|
function isDestructive(parameters) {
|
|
290
93
|
return parameters[X_DESTRUCTIVE_KEY] === true;
|
|
291
94
|
}
|
|
292
95
|
|
|
293
|
-
// src/is_navigates.ts
|
|
96
|
+
// src/tools/is_navigates.ts
|
|
294
97
|
function isNavigates(parameters) {
|
|
295
98
|
return parameters[X_NAVIGATES_KEY] === true;
|
|
296
99
|
}
|
|
297
100
|
|
|
298
|
-
// src/page_map.ts
|
|
101
|
+
// src/tools/page_map.ts
|
|
299
102
|
function createPageMapContext(getPageMap, autoInject) {
|
|
300
103
|
if (!autoInject || getPageMap === null) {
|
|
301
104
|
return [];
|
|
@@ -303,11 +106,31 @@ function createPageMapContext(getPageMap, autoInject) {
|
|
|
303
106
|
return [{ description: "page_map", value: JSON.stringify(getPageMap()) }];
|
|
304
107
|
}
|
|
305
108
|
|
|
306
|
-
// src/route_map.ts
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
109
|
+
// src/tools/route_map.ts
|
|
110
|
+
var PATH_PARAM_RE = /:([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
111
|
+
function pathParamNames(path) {
|
|
112
|
+
const names = [];
|
|
113
|
+
for (const match of path.matchAll(PATH_PARAM_RE)) {
|
|
114
|
+
const name = match[1];
|
|
115
|
+
if (name !== void 0) {
|
|
116
|
+
names.push(name);
|
|
117
|
+
}
|
|
310
118
|
}
|
|
119
|
+
return names;
|
|
120
|
+
}
|
|
121
|
+
function fillPath(routeId, path, params) {
|
|
122
|
+
const leftover = { ...params };
|
|
123
|
+
const filled = path.replace(PATH_PARAM_RE, (_match, name) => {
|
|
124
|
+
const value = params[name];
|
|
125
|
+
if (value === void 0 || value === null || String(value) === "") {
|
|
126
|
+
throw new Error(`route "${routeId}" requires path param "${name}"`);
|
|
127
|
+
}
|
|
128
|
+
delete leftover[name];
|
|
129
|
+
return encodeURIComponent(String(value));
|
|
130
|
+
});
|
|
131
|
+
return { path: filled, leftover };
|
|
132
|
+
}
|
|
133
|
+
function withQuery(path, params) {
|
|
311
134
|
const usp = new URLSearchParams();
|
|
312
135
|
for (const [key, value] of Object.entries(params)) {
|
|
313
136
|
usp.set(key, String(value));
|
|
@@ -319,13 +142,13 @@ function createRouteTools(getRouteMap, getNavigate) {
|
|
|
319
142
|
return [
|
|
320
143
|
{
|
|
321
144
|
name: "list_routes",
|
|
322
|
-
description: "List the routes the app can navigate to.",
|
|
145
|
+
description: "List the routes the app can navigate to. Each route's `pathParams` names the dynamic segments to pass as `params` to `navigate_to_route`.",
|
|
323
146
|
parameters: { type: "object", properties: {}, required: [] },
|
|
324
|
-
handler: () => getRouteMap()
|
|
147
|
+
handler: () => getRouteMap().map((route) => ({ ...route, pathParams: pathParamNames(route.path) }))
|
|
325
148
|
},
|
|
326
149
|
{
|
|
327
150
|
name: "navigate_to_route",
|
|
328
|
-
description: "Navigate to one of the app's routes by its id
|
|
151
|
+
description: "Navigate to one of the app's routes by its id, filling any dynamic `:name` path segments (and extra query params) from `params`.",
|
|
329
152
|
parameters: {
|
|
330
153
|
type: "object",
|
|
331
154
|
properties: {
|
|
@@ -341,7 +164,9 @@ function createRouteTools(getRouteMap, getNavigate) {
|
|
|
341
164
|
if (route === void 0) {
|
|
342
165
|
throw new Error(`unknown route "${String(routeId)}"`);
|
|
343
166
|
}
|
|
344
|
-
const
|
|
167
|
+
const provided = args["params"] ?? {};
|
|
168
|
+
const { path: filledPath, leftover } = fillPath(route.id, route.path, provided);
|
|
169
|
+
const path = withQuery(filledPath, leftover);
|
|
345
170
|
const navigate = getNavigate();
|
|
346
171
|
if (navigate !== null) {
|
|
347
172
|
navigate(path);
|
|
@@ -354,7 +179,7 @@ function createRouteTools(getRouteMap, getNavigate) {
|
|
|
354
179
|
];
|
|
355
180
|
}
|
|
356
181
|
|
|
357
|
-
// src/state_hook.ts
|
|
182
|
+
// src/tools/state_hook.ts
|
|
358
183
|
function createStateHookTools(hook) {
|
|
359
184
|
const tools = [
|
|
360
185
|
{
|
|
@@ -376,33 +201,2744 @@ function createStateHookTools(hook) {
|
|
|
376
201
|
return tools;
|
|
377
202
|
}
|
|
378
203
|
|
|
379
|
-
// src/
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
204
|
+
// src/ui/confirmation_card.ts
|
|
205
|
+
function actionButton(modifier, label) {
|
|
206
|
+
const button = document.createElement("button");
|
|
207
|
+
button.type = "button";
|
|
208
|
+
button.className = `confirm-btn confirm-btn--${modifier}`;
|
|
209
|
+
button.textContent = label;
|
|
210
|
+
return button;
|
|
211
|
+
}
|
|
212
|
+
function requestConfirmation(host, request) {
|
|
213
|
+
return new Promise((resolve) => {
|
|
214
|
+
const card = document.createElement("div");
|
|
215
|
+
card.className = "confirm";
|
|
216
|
+
card.setAttribute("data-tool-name", request.toolName);
|
|
217
|
+
card.setAttribute("role", "group");
|
|
218
|
+
card.setAttribute("aria-label", "Confirm action");
|
|
219
|
+
const body = document.createElement("div");
|
|
220
|
+
body.className = "confirm-body";
|
|
221
|
+
body.textContent = request.message ?? `Run \u201C${request.toolName}\u201D?`;
|
|
222
|
+
const args = document.createElement("pre");
|
|
223
|
+
args.className = "confirm-args";
|
|
224
|
+
args.textContent = JSON.stringify(request.args, null, 2);
|
|
225
|
+
const actions = document.createElement("div");
|
|
226
|
+
actions.className = "confirm-actions";
|
|
227
|
+
const cancel = actionButton("cancel", "Cancel");
|
|
228
|
+
const confirm = actionButton("confirm", "Confirm");
|
|
229
|
+
const close = (accepted) => {
|
|
230
|
+
cancel.disabled = true;
|
|
231
|
+
confirm.disabled = true;
|
|
232
|
+
card.setAttribute("data-resolved", accepted ? "confirmed" : "declined");
|
|
233
|
+
resolve(accepted);
|
|
234
|
+
};
|
|
235
|
+
cancel.addEventListener("click", () => close(false));
|
|
236
|
+
confirm.addEventListener("click", () => close(true));
|
|
237
|
+
actions.append(cancel, confirm);
|
|
238
|
+
card.append(body, args, actions);
|
|
239
|
+
host.appendChild(card);
|
|
240
|
+
confirm.focus();
|
|
241
|
+
});
|
|
242
|
+
}
|
|
396
243
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
244
|
+
// node_modules/.pnpm/dompurify@3.4.7/node_modules/dompurify/dist/purify.es.mjs
|
|
245
|
+
function _arrayLikeToArray(r, a) {
|
|
246
|
+
(null == a || a > r.length) && (a = r.length);
|
|
247
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
248
|
+
return n;
|
|
249
|
+
}
|
|
250
|
+
function _arrayWithHoles(r) {
|
|
251
|
+
if (Array.isArray(r)) return r;
|
|
252
|
+
}
|
|
253
|
+
function _iterableToArrayLimit(r, l3) {
|
|
254
|
+
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
255
|
+
if (null != t) {
|
|
256
|
+
var e, n, i, u, a = [], f = true, o = false;
|
|
257
|
+
try {
|
|
258
|
+
if (i = (t = t.call(r)).next, 0 === l3) ;
|
|
259
|
+
else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l3); f = true) ;
|
|
260
|
+
} catch (r2) {
|
|
261
|
+
o = true, n = r2;
|
|
262
|
+
} finally {
|
|
263
|
+
try {
|
|
264
|
+
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
265
|
+
} finally {
|
|
266
|
+
if (o) throw n;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return a;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function _nonIterableRest() {
|
|
273
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
274
|
+
}
|
|
275
|
+
function _slicedToArray(r, e) {
|
|
276
|
+
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
277
|
+
}
|
|
278
|
+
function _unsupportedIterableToArray(r, a) {
|
|
279
|
+
if (r) {
|
|
280
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
281
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
282
|
+
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;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
var entries = Object.entries;
|
|
286
|
+
var setPrototypeOf = Object.setPrototypeOf;
|
|
287
|
+
var isFrozen = Object.isFrozen;
|
|
288
|
+
var getPrototypeOf = Object.getPrototypeOf;
|
|
289
|
+
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
290
|
+
var freeze = Object.freeze;
|
|
291
|
+
var seal = Object.seal;
|
|
292
|
+
var create = Object.create;
|
|
293
|
+
var _ref = typeof Reflect !== "undefined" && Reflect;
|
|
294
|
+
var apply = _ref.apply;
|
|
295
|
+
var construct = _ref.construct;
|
|
296
|
+
if (!freeze) {
|
|
297
|
+
freeze = function freeze2(x2) {
|
|
298
|
+
return x2;
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
if (!seal) {
|
|
302
|
+
seal = function seal2(x2) {
|
|
303
|
+
return x2;
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
if (!apply) {
|
|
307
|
+
apply = function apply2(func, thisArg) {
|
|
308
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
309
|
+
args[_key - 2] = arguments[_key];
|
|
310
|
+
}
|
|
311
|
+
return func.apply(thisArg, args);
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
if (!construct) {
|
|
315
|
+
construct = function construct2(Func) {
|
|
316
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
317
|
+
args[_key2 - 1] = arguments[_key2];
|
|
318
|
+
}
|
|
319
|
+
return new Func(...args);
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
var arrayForEach = unapply(Array.prototype.forEach);
|
|
323
|
+
var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
|
|
324
|
+
var arrayPop = unapply(Array.prototype.pop);
|
|
325
|
+
var arrayPush = unapply(Array.prototype.push);
|
|
326
|
+
var arraySplice = unapply(Array.prototype.splice);
|
|
327
|
+
var arrayIsArray = Array.isArray;
|
|
328
|
+
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
329
|
+
var stringToString = unapply(String.prototype.toString);
|
|
330
|
+
var stringMatch = unapply(String.prototype.match);
|
|
331
|
+
var stringReplace = unapply(String.prototype.replace);
|
|
332
|
+
var stringIndexOf = unapply(String.prototype.indexOf);
|
|
333
|
+
var stringTrim = unapply(String.prototype.trim);
|
|
334
|
+
var numberToString = unapply(Number.prototype.toString);
|
|
335
|
+
var booleanToString = unapply(Boolean.prototype.toString);
|
|
336
|
+
var bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
|
|
337
|
+
var symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
|
|
338
|
+
var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
|
339
|
+
var objectToString = unapply(Object.prototype.toString);
|
|
340
|
+
var regExpTest = unapply(RegExp.prototype.test);
|
|
341
|
+
var typeErrorCreate = unconstruct(TypeError);
|
|
342
|
+
function unapply(func) {
|
|
343
|
+
return function(thisArg) {
|
|
344
|
+
if (thisArg instanceof RegExp) {
|
|
345
|
+
thisArg.lastIndex = 0;
|
|
346
|
+
}
|
|
347
|
+
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
348
|
+
args[_key3 - 1] = arguments[_key3];
|
|
349
|
+
}
|
|
350
|
+
return apply(func, thisArg, args);
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function unconstruct(Func) {
|
|
354
|
+
return function() {
|
|
355
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
356
|
+
args[_key4] = arguments[_key4];
|
|
357
|
+
}
|
|
358
|
+
return construct(Func, args);
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
function addToSet(set, array) {
|
|
362
|
+
let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
|
|
363
|
+
if (setPrototypeOf) {
|
|
364
|
+
setPrototypeOf(set, null);
|
|
365
|
+
}
|
|
366
|
+
if (!arrayIsArray(array)) {
|
|
367
|
+
return set;
|
|
368
|
+
}
|
|
369
|
+
let l3 = array.length;
|
|
370
|
+
while (l3--) {
|
|
371
|
+
let element = array[l3];
|
|
372
|
+
if (typeof element === "string") {
|
|
373
|
+
const lcElement = transformCaseFunc(element);
|
|
374
|
+
if (lcElement !== element) {
|
|
375
|
+
if (!isFrozen(array)) {
|
|
376
|
+
array[l3] = lcElement;
|
|
377
|
+
}
|
|
378
|
+
element = lcElement;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
set[element] = true;
|
|
382
|
+
}
|
|
383
|
+
return set;
|
|
384
|
+
}
|
|
385
|
+
function cleanArray(array) {
|
|
386
|
+
for (let index = 0; index < array.length; index++) {
|
|
387
|
+
const isPropertyExist = objectHasOwnProperty(array, index);
|
|
388
|
+
if (!isPropertyExist) {
|
|
389
|
+
array[index] = null;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return array;
|
|
393
|
+
}
|
|
394
|
+
function clone(object) {
|
|
395
|
+
const newObject = create(null);
|
|
396
|
+
for (const _ref2 of entries(object)) {
|
|
397
|
+
var _ref3 = _slicedToArray(_ref2, 2);
|
|
398
|
+
const property = _ref3[0];
|
|
399
|
+
const value = _ref3[1];
|
|
400
|
+
const isPropertyExist = objectHasOwnProperty(object, property);
|
|
401
|
+
if (isPropertyExist) {
|
|
402
|
+
if (arrayIsArray(value)) {
|
|
403
|
+
newObject[property] = cleanArray(value);
|
|
404
|
+
} else if (value && typeof value === "object" && value.constructor === Object) {
|
|
405
|
+
newObject[property] = clone(value);
|
|
406
|
+
} else {
|
|
407
|
+
newObject[property] = value;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return newObject;
|
|
412
|
+
}
|
|
413
|
+
function stringifyValue(value) {
|
|
414
|
+
switch (typeof value) {
|
|
415
|
+
case "string": {
|
|
416
|
+
return value;
|
|
417
|
+
}
|
|
418
|
+
case "number": {
|
|
419
|
+
return numberToString(value);
|
|
420
|
+
}
|
|
421
|
+
case "boolean": {
|
|
422
|
+
return booleanToString(value);
|
|
423
|
+
}
|
|
424
|
+
case "bigint": {
|
|
425
|
+
return bigintToString ? bigintToString(value) : "0";
|
|
426
|
+
}
|
|
427
|
+
case "symbol": {
|
|
428
|
+
return symbolToString ? symbolToString(value) : "Symbol()";
|
|
429
|
+
}
|
|
430
|
+
case "undefined": {
|
|
431
|
+
return objectToString(value);
|
|
432
|
+
}
|
|
433
|
+
case "function":
|
|
434
|
+
case "object": {
|
|
435
|
+
if (value === null) {
|
|
436
|
+
return objectToString(value);
|
|
437
|
+
}
|
|
438
|
+
const valueAsRecord = value;
|
|
439
|
+
const valueToString = lookupGetter(valueAsRecord, "toString");
|
|
440
|
+
if (typeof valueToString === "function") {
|
|
441
|
+
const stringified = valueToString(valueAsRecord);
|
|
442
|
+
return typeof stringified === "string" ? stringified : objectToString(stringified);
|
|
443
|
+
}
|
|
444
|
+
return objectToString(value);
|
|
445
|
+
}
|
|
446
|
+
default: {
|
|
447
|
+
return objectToString(value);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function lookupGetter(object, prop) {
|
|
452
|
+
while (object !== null) {
|
|
453
|
+
const desc = getOwnPropertyDescriptor(object, prop);
|
|
454
|
+
if (desc) {
|
|
455
|
+
if (desc.get) {
|
|
456
|
+
return unapply(desc.get);
|
|
457
|
+
}
|
|
458
|
+
if (typeof desc.value === "function") {
|
|
459
|
+
return unapply(desc.value);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
object = getPrototypeOf(object);
|
|
463
|
+
}
|
|
464
|
+
function fallbackValue() {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
return fallbackValue;
|
|
468
|
+
}
|
|
469
|
+
function isRegex(value) {
|
|
470
|
+
try {
|
|
471
|
+
regExpTest(value, "");
|
|
472
|
+
return true;
|
|
473
|
+
} catch (_unused) {
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
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"]);
|
|
478
|
+
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"]);
|
|
479
|
+
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"]);
|
|
480
|
+
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"]);
|
|
481
|
+
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"]);
|
|
482
|
+
var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
|
|
483
|
+
var text = freeze(["#text"]);
|
|
484
|
+
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"]);
|
|
485
|
+
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"]);
|
|
486
|
+
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"]);
|
|
487
|
+
var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
|
|
488
|
+
var MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
|
|
489
|
+
var ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
|
|
490
|
+
var TMPLIT_EXPR = seal(/\${[\w\W]*/g);
|
|
491
|
+
var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
|
|
492
|
+
var ARIA_ATTR = seal(/^aria-[\-\w]+$/);
|
|
493
|
+
var IS_ALLOWED_URI = seal(
|
|
494
|
+
/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
|
|
495
|
+
// eslint-disable-line no-useless-escape
|
|
496
|
+
);
|
|
497
|
+
var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
498
|
+
var ATTR_WHITESPACE = seal(
|
|
499
|
+
/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
|
|
500
|
+
// eslint-disable-line no-control-regex
|
|
501
|
+
);
|
|
502
|
+
var DOCTYPE_NAME = seal(/^html$/i);
|
|
503
|
+
var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
|
|
504
|
+
var NODE_TYPE = {
|
|
505
|
+
element: 1,
|
|
506
|
+
attribute: 2,
|
|
507
|
+
text: 3,
|
|
508
|
+
cdataSection: 4,
|
|
509
|
+
entityReference: 5,
|
|
510
|
+
// Deprecated
|
|
511
|
+
entityNode: 6,
|
|
512
|
+
// Deprecated
|
|
513
|
+
progressingInstruction: 7,
|
|
514
|
+
comment: 8,
|
|
515
|
+
document: 9,
|
|
516
|
+
documentType: 10,
|
|
517
|
+
documentFragment: 11,
|
|
518
|
+
notation: 12
|
|
519
|
+
// Deprecated
|
|
520
|
+
};
|
|
521
|
+
var getGlobal = function getGlobal2() {
|
|
522
|
+
return typeof window === "undefined" ? null : window;
|
|
523
|
+
};
|
|
524
|
+
var _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, purifyHostElement) {
|
|
525
|
+
if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") {
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
let suffix = null;
|
|
529
|
+
const ATTR_NAME = "data-tt-policy-suffix";
|
|
530
|
+
if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
|
|
531
|
+
suffix = purifyHostElement.getAttribute(ATTR_NAME);
|
|
532
|
+
}
|
|
533
|
+
const policyName = "dompurify" + (suffix ? "#" + suffix : "");
|
|
534
|
+
try {
|
|
535
|
+
return trustedTypes.createPolicy(policyName, {
|
|
536
|
+
createHTML(html2) {
|
|
537
|
+
return html2;
|
|
538
|
+
},
|
|
539
|
+
createScriptURL(scriptUrl) {
|
|
540
|
+
return scriptUrl;
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
} catch (_2) {
|
|
544
|
+
console.warn("TrustedTypes policy " + policyName + " could not be created.");
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
var _createHooksMap = function _createHooksMap2() {
|
|
549
|
+
return {
|
|
550
|
+
afterSanitizeAttributes: [],
|
|
551
|
+
afterSanitizeElements: [],
|
|
552
|
+
afterSanitizeShadowDOM: [],
|
|
553
|
+
beforeSanitizeAttributes: [],
|
|
554
|
+
beforeSanitizeElements: [],
|
|
555
|
+
beforeSanitizeShadowDOM: [],
|
|
556
|
+
uponSanitizeAttribute: [],
|
|
557
|
+
uponSanitizeElement: [],
|
|
558
|
+
uponSanitizeShadowNode: []
|
|
559
|
+
};
|
|
560
|
+
};
|
|
561
|
+
function createDOMPurify() {
|
|
562
|
+
let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
|
|
563
|
+
const DOMPurify = (root) => createDOMPurify(root);
|
|
564
|
+
DOMPurify.version = "3.4.7";
|
|
565
|
+
DOMPurify.removed = [];
|
|
566
|
+
if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
|
|
567
|
+
DOMPurify.isSupported = false;
|
|
568
|
+
return DOMPurify;
|
|
569
|
+
}
|
|
570
|
+
let document2 = window2.document;
|
|
571
|
+
const originalDocument = document2;
|
|
572
|
+
const currentScript = originalDocument.currentScript;
|
|
573
|
+
window2.DocumentFragment;
|
|
574
|
+
const HTMLTemplateElement = window2.HTMLTemplateElement, Node2 = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap;
|
|
575
|
+
_window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap;
|
|
576
|
+
window2.HTMLFormElement;
|
|
577
|
+
const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
|
|
578
|
+
const ElementPrototype = Element.prototype;
|
|
579
|
+
const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
|
|
580
|
+
const remove = lookupGetter(ElementPrototype, "remove");
|
|
581
|
+
const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
|
|
582
|
+
const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
|
|
583
|
+
const getParentNode = lookupGetter(ElementPrototype, "parentNode");
|
|
584
|
+
const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
|
|
585
|
+
const getAttributes = lookupGetter(ElementPrototype, "attributes");
|
|
586
|
+
const getNodeType = Node2 && Node2.prototype ? lookupGetter(Node2.prototype, "nodeType") : null;
|
|
587
|
+
const getNodeName = Node2 && Node2.prototype ? lookupGetter(Node2.prototype, "nodeName") : null;
|
|
588
|
+
if (typeof HTMLTemplateElement === "function") {
|
|
589
|
+
const template = document2.createElement("template");
|
|
590
|
+
if (template.content && template.content.ownerDocument) {
|
|
591
|
+
document2 = template.content.ownerDocument;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
let trustedTypesPolicy;
|
|
595
|
+
let emptyHTML = "";
|
|
596
|
+
const _document = document2, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
|
|
597
|
+
const importNode = originalDocument.importNode;
|
|
598
|
+
let hooks = _createHooksMap();
|
|
599
|
+
DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
|
|
600
|
+
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;
|
|
601
|
+
let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
|
|
602
|
+
let ALLOWED_TAGS2 = null;
|
|
603
|
+
const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
|
|
604
|
+
let ALLOWED_ATTR2 = null;
|
|
605
|
+
const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
|
|
606
|
+
let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
607
|
+
tagNameCheck: {
|
|
608
|
+
writable: true,
|
|
609
|
+
configurable: false,
|
|
610
|
+
enumerable: true,
|
|
611
|
+
value: null
|
|
612
|
+
},
|
|
613
|
+
attributeNameCheck: {
|
|
614
|
+
writable: true,
|
|
615
|
+
configurable: false,
|
|
616
|
+
enumerable: true,
|
|
617
|
+
value: null
|
|
618
|
+
},
|
|
619
|
+
allowCustomizedBuiltInElements: {
|
|
620
|
+
writable: true,
|
|
621
|
+
configurable: false,
|
|
622
|
+
enumerable: true,
|
|
623
|
+
value: false
|
|
624
|
+
}
|
|
625
|
+
}));
|
|
626
|
+
let FORBID_TAGS = null;
|
|
627
|
+
let FORBID_ATTR = null;
|
|
628
|
+
const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
629
|
+
tagCheck: {
|
|
630
|
+
writable: true,
|
|
631
|
+
configurable: false,
|
|
632
|
+
enumerable: true,
|
|
633
|
+
value: null
|
|
634
|
+
},
|
|
635
|
+
attributeCheck: {
|
|
636
|
+
writable: true,
|
|
637
|
+
configurable: false,
|
|
638
|
+
enumerable: true,
|
|
639
|
+
value: null
|
|
640
|
+
}
|
|
641
|
+
}));
|
|
642
|
+
let ALLOW_ARIA_ATTR = true;
|
|
643
|
+
let ALLOW_DATA_ATTR = true;
|
|
644
|
+
let ALLOW_UNKNOWN_PROTOCOLS = false;
|
|
645
|
+
let ALLOW_SELF_CLOSE_IN_ATTR = true;
|
|
646
|
+
let SAFE_FOR_TEMPLATES = false;
|
|
647
|
+
let SAFE_FOR_XML = true;
|
|
648
|
+
let WHOLE_DOCUMENT = false;
|
|
649
|
+
let SET_CONFIG = false;
|
|
650
|
+
let FORCE_BODY = false;
|
|
651
|
+
let RETURN_DOM = false;
|
|
652
|
+
let RETURN_DOM_FRAGMENT = false;
|
|
653
|
+
let RETURN_TRUSTED_TYPE = false;
|
|
654
|
+
let SANITIZE_DOM = true;
|
|
655
|
+
let SANITIZE_NAMED_PROPS = false;
|
|
656
|
+
const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
|
|
657
|
+
let KEEP_CONTENT = true;
|
|
658
|
+
let IN_PLACE = false;
|
|
659
|
+
let USE_PROFILES = {};
|
|
660
|
+
let FORBID_CONTENTS = null;
|
|
661
|
+
const DEFAULT_FORBID_CONTENTS = addToSet({}, ["annotation-xml", "audio", "colgroup", "desc", "foreignobject", "head", "iframe", "math", "mi", "mn", "mo", "ms", "mtext", "noembed", "noframes", "noscript", "plaintext", "script", "style", "svg", "template", "thead", "title", "video", "xmp"]);
|
|
662
|
+
let DATA_URI_TAGS = null;
|
|
663
|
+
const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
|
|
664
|
+
let URI_SAFE_ATTRIBUTES = null;
|
|
665
|
+
const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ["alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns"]);
|
|
666
|
+
const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
|
|
667
|
+
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
668
|
+
const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|
669
|
+
let NAMESPACE = HTML_NAMESPACE;
|
|
670
|
+
let IS_EMPTY_INPUT = false;
|
|
671
|
+
let ALLOWED_NAMESPACES = null;
|
|
672
|
+
const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
|
|
673
|
+
let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
|
|
674
|
+
let HTML_INTEGRATION_POINTS = addToSet({}, ["annotation-xml"]);
|
|
675
|
+
const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
|
|
676
|
+
let PARSER_MEDIA_TYPE = null;
|
|
677
|
+
const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
|
|
678
|
+
const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
|
|
679
|
+
let transformCaseFunc = null;
|
|
680
|
+
let CONFIG = null;
|
|
681
|
+
const formElement = document2.createElement("form");
|
|
682
|
+
const isRegexOrFunction = function isRegexOrFunction2(testValue) {
|
|
683
|
+
return testValue instanceof RegExp || testValue instanceof Function;
|
|
684
|
+
};
|
|
685
|
+
const _parseConfig = function _parseConfig2() {
|
|
686
|
+
let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
687
|
+
if (CONFIG && CONFIG === cfg) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
if (!cfg || typeof cfg !== "object") {
|
|
691
|
+
cfg = {};
|
|
692
|
+
}
|
|
693
|
+
cfg = clone(cfg);
|
|
694
|
+
PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
|
|
695
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
|
|
696
|
+
transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
|
|
697
|
+
ALLOWED_TAGS2 = objectHasOwnProperty(cfg, "ALLOWED_TAGS") && arrayIsArray(cfg.ALLOWED_TAGS) ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
|
|
698
|
+
ALLOWED_ATTR2 = objectHasOwnProperty(cfg, "ALLOWED_ATTR") && arrayIsArray(cfg.ALLOWED_ATTR) ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
|
|
699
|
+
ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, "ALLOWED_NAMESPACES") && arrayIsArray(cfg.ALLOWED_NAMESPACES) ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
|
|
700
|
+
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR) ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
701
|
+
DATA_URI_TAGS = objectHasOwnProperty(cfg, "ADD_DATA_URI_TAGS") && arrayIsArray(cfg.ADD_DATA_URI_TAGS) ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
|
|
702
|
+
FORBID_CONTENTS = objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS) ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
|
703
|
+
FORBID_TAGS = objectHasOwnProperty(cfg, "FORBID_TAGS") && arrayIsArray(cfg.FORBID_TAGS) ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
|
|
704
|
+
FORBID_ATTR = objectHasOwnProperty(cfg, "FORBID_ATTR") && arrayIsArray(cfg.FORBID_ATTR) ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
|
|
705
|
+
USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
|
|
706
|
+
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
|
|
707
|
+
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
|
|
708
|
+
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
|
|
709
|
+
ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
|
|
710
|
+
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
|
|
711
|
+
SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
|
|
712
|
+
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
|
|
713
|
+
RETURN_DOM = cfg.RETURN_DOM || false;
|
|
714
|
+
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
|
|
715
|
+
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
|
|
716
|
+
FORCE_BODY = cfg.FORCE_BODY || false;
|
|
717
|
+
SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
|
|
718
|
+
SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
|
|
719
|
+
KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
|
|
720
|
+
IN_PLACE = cfg.IN_PLACE || false;
|
|
721
|
+
IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
|
|
722
|
+
NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
|
|
723
|
+
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({}, ["mi", "mo", "mn", "ms", "mtext"]);
|
|
724
|
+
HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, ["annotation-xml"]);
|
|
725
|
+
const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
|
|
726
|
+
CUSTOM_ELEMENT_HANDLING = create(null);
|
|
727
|
+
if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
|
|
728
|
+
CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
|
|
729
|
+
}
|
|
730
|
+
if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
|
|
731
|
+
CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
|
|
732
|
+
}
|
|
733
|
+
if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
|
|
734
|
+
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
|
|
735
|
+
}
|
|
736
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
737
|
+
ALLOW_DATA_ATTR = false;
|
|
738
|
+
}
|
|
739
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
740
|
+
RETURN_DOM = true;
|
|
741
|
+
}
|
|
742
|
+
if (USE_PROFILES) {
|
|
743
|
+
ALLOWED_TAGS2 = addToSet({}, text);
|
|
744
|
+
ALLOWED_ATTR2 = create(null);
|
|
745
|
+
if (USE_PROFILES.html === true) {
|
|
746
|
+
addToSet(ALLOWED_TAGS2, html$1);
|
|
747
|
+
addToSet(ALLOWED_ATTR2, html);
|
|
748
|
+
}
|
|
749
|
+
if (USE_PROFILES.svg === true) {
|
|
750
|
+
addToSet(ALLOWED_TAGS2, svg$1);
|
|
751
|
+
addToSet(ALLOWED_ATTR2, svg);
|
|
752
|
+
addToSet(ALLOWED_ATTR2, xml);
|
|
753
|
+
}
|
|
754
|
+
if (USE_PROFILES.svgFilters === true) {
|
|
755
|
+
addToSet(ALLOWED_TAGS2, svgFilters);
|
|
756
|
+
addToSet(ALLOWED_ATTR2, svg);
|
|
757
|
+
addToSet(ALLOWED_ATTR2, xml);
|
|
758
|
+
}
|
|
759
|
+
if (USE_PROFILES.mathMl === true) {
|
|
760
|
+
addToSet(ALLOWED_TAGS2, mathMl$1);
|
|
761
|
+
addToSet(ALLOWED_ATTR2, mathMl);
|
|
762
|
+
addToSet(ALLOWED_ATTR2, xml);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = null;
|
|
766
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = null;
|
|
767
|
+
if (objectHasOwnProperty(cfg, "ADD_TAGS")) {
|
|
768
|
+
if (typeof cfg.ADD_TAGS === "function") {
|
|
769
|
+
EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
|
|
770
|
+
} else if (arrayIsArray(cfg.ADD_TAGS)) {
|
|
771
|
+
if (ALLOWED_TAGS2 === DEFAULT_ALLOWED_TAGS) {
|
|
772
|
+
ALLOWED_TAGS2 = clone(ALLOWED_TAGS2);
|
|
773
|
+
}
|
|
774
|
+
addToSet(ALLOWED_TAGS2, cfg.ADD_TAGS, transformCaseFunc);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (objectHasOwnProperty(cfg, "ADD_ATTR")) {
|
|
778
|
+
if (typeof cfg.ADD_ATTR === "function") {
|
|
779
|
+
EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
|
|
780
|
+
} else if (arrayIsArray(cfg.ADD_ATTR)) {
|
|
781
|
+
if (ALLOWED_ATTR2 === DEFAULT_ALLOWED_ATTR) {
|
|
782
|
+
ALLOWED_ATTR2 = clone(ALLOWED_ATTR2);
|
|
783
|
+
}
|
|
784
|
+
addToSet(ALLOWED_ATTR2, cfg.ADD_ATTR, transformCaseFunc);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
|
|
788
|
+
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
789
|
+
}
|
|
790
|
+
if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
|
|
791
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
792
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
793
|
+
}
|
|
794
|
+
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
795
|
+
}
|
|
796
|
+
if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
|
|
797
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
798
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
799
|
+
}
|
|
800
|
+
addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
|
|
801
|
+
}
|
|
802
|
+
if (KEEP_CONTENT) {
|
|
803
|
+
ALLOWED_TAGS2["#text"] = true;
|
|
804
|
+
}
|
|
805
|
+
if (WHOLE_DOCUMENT) {
|
|
806
|
+
addToSet(ALLOWED_TAGS2, ["html", "head", "body"]);
|
|
807
|
+
}
|
|
808
|
+
if (ALLOWED_TAGS2.table) {
|
|
809
|
+
addToSet(ALLOWED_TAGS2, ["tbody"]);
|
|
810
|
+
delete FORBID_TAGS.tbody;
|
|
811
|
+
}
|
|
812
|
+
if (cfg.TRUSTED_TYPES_POLICY) {
|
|
813
|
+
if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") {
|
|
814
|
+
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
|
|
815
|
+
}
|
|
816
|
+
if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
|
|
817
|
+
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
|
|
818
|
+
}
|
|
819
|
+
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
|
|
820
|
+
emptyHTML = trustedTypesPolicy.createHTML("");
|
|
821
|
+
} else {
|
|
822
|
+
if (trustedTypesPolicy === void 0) {
|
|
823
|
+
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
|
824
|
+
}
|
|
825
|
+
if (trustedTypesPolicy !== null && typeof emptyHTML === "string") {
|
|
826
|
+
emptyHTML = trustedTypesPolicy.createHTML("");
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
if ((hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) && ALLOWED_TAGS2 === DEFAULT_ALLOWED_TAGS) {
|
|
830
|
+
ALLOWED_TAGS2 = clone(ALLOWED_TAGS2);
|
|
831
|
+
}
|
|
832
|
+
if (hooks.uponSanitizeAttribute.length > 0 && ALLOWED_ATTR2 === DEFAULT_ALLOWED_ATTR) {
|
|
833
|
+
ALLOWED_ATTR2 = clone(ALLOWED_ATTR2);
|
|
834
|
+
}
|
|
835
|
+
if (freeze) {
|
|
836
|
+
freeze(cfg);
|
|
837
|
+
}
|
|
838
|
+
CONFIG = cfg;
|
|
839
|
+
};
|
|
840
|
+
const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
|
|
841
|
+
const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
|
|
842
|
+
const _checkValidNamespace = function _checkValidNamespace2(element) {
|
|
843
|
+
let parent = getParentNode(element);
|
|
844
|
+
if (!parent || !parent.tagName) {
|
|
845
|
+
parent = {
|
|
846
|
+
namespaceURI: NAMESPACE,
|
|
847
|
+
tagName: "template"
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
const tagName = stringToLowerCase(element.tagName);
|
|
851
|
+
const parentTagName = stringToLowerCase(parent.tagName);
|
|
852
|
+
if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
|
|
853
|
+
return false;
|
|
854
|
+
}
|
|
855
|
+
if (element.namespaceURI === SVG_NAMESPACE) {
|
|
856
|
+
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
857
|
+
return tagName === "svg";
|
|
858
|
+
}
|
|
859
|
+
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
|
860
|
+
return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
|
861
|
+
}
|
|
862
|
+
return Boolean(ALL_SVG_TAGS[tagName]);
|
|
863
|
+
}
|
|
864
|
+
if (element.namespaceURI === MATHML_NAMESPACE) {
|
|
865
|
+
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
866
|
+
return tagName === "math";
|
|
867
|
+
}
|
|
868
|
+
if (parent.namespaceURI === SVG_NAMESPACE) {
|
|
869
|
+
return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
|
|
870
|
+
}
|
|
871
|
+
return Boolean(ALL_MATHML_TAGS[tagName]);
|
|
872
|
+
}
|
|
873
|
+
if (element.namespaceURI === HTML_NAMESPACE) {
|
|
874
|
+
if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
|
878
|
+
return false;
|
|
879
|
+
}
|
|
880
|
+
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
|
881
|
+
}
|
|
882
|
+
if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
|
|
883
|
+
return true;
|
|
884
|
+
}
|
|
885
|
+
return false;
|
|
886
|
+
};
|
|
887
|
+
const _forceRemove = function _forceRemove2(node) {
|
|
888
|
+
arrayPush(DOMPurify.removed, {
|
|
889
|
+
element: node
|
|
890
|
+
});
|
|
891
|
+
try {
|
|
892
|
+
getParentNode(node).removeChild(node);
|
|
893
|
+
} catch (_2) {
|
|
894
|
+
remove(node);
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
const _removeAttribute = function _removeAttribute2(name, element) {
|
|
898
|
+
try {
|
|
899
|
+
arrayPush(DOMPurify.removed, {
|
|
900
|
+
attribute: element.getAttributeNode(name),
|
|
901
|
+
from: element
|
|
902
|
+
});
|
|
903
|
+
} catch (_2) {
|
|
904
|
+
arrayPush(DOMPurify.removed, {
|
|
905
|
+
attribute: null,
|
|
906
|
+
from: element
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
element.removeAttribute(name);
|
|
910
|
+
if (name === "is") {
|
|
911
|
+
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
|
912
|
+
try {
|
|
913
|
+
_forceRemove(element);
|
|
914
|
+
} catch (_2) {
|
|
915
|
+
}
|
|
916
|
+
} else {
|
|
917
|
+
try {
|
|
918
|
+
element.setAttribute(name, "");
|
|
919
|
+
} catch (_2) {
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
const _initDocument = function _initDocument2(dirty) {
|
|
925
|
+
let doc = null;
|
|
926
|
+
let leadingWhitespace = null;
|
|
927
|
+
if (FORCE_BODY) {
|
|
928
|
+
dirty = "<remove></remove>" + dirty;
|
|
929
|
+
} else {
|
|
930
|
+
const matches = stringMatch(dirty, /^[\r\n\t ]+/);
|
|
931
|
+
leadingWhitespace = matches && matches[0];
|
|
932
|
+
}
|
|
933
|
+
if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
|
|
934
|
+
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
|
|
935
|
+
}
|
|
936
|
+
const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
937
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
938
|
+
try {
|
|
939
|
+
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
940
|
+
} catch (_2) {
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (!doc || !doc.documentElement) {
|
|
944
|
+
doc = implementation.createDocument(NAMESPACE, "template", null);
|
|
945
|
+
try {
|
|
946
|
+
doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
|
|
947
|
+
} catch (_2) {
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
const body = doc.body || doc.documentElement;
|
|
951
|
+
if (dirty && leadingWhitespace) {
|
|
952
|
+
body.insertBefore(document2.createTextNode(leadingWhitespace), body.childNodes[0] || null);
|
|
953
|
+
}
|
|
954
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
955
|
+
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
|
|
956
|
+
}
|
|
957
|
+
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
958
|
+
};
|
|
959
|
+
const _createNodeIterator = function _createNodeIterator2(root) {
|
|
960
|
+
return createNodeIterator.call(
|
|
961
|
+
root.ownerDocument || root,
|
|
962
|
+
root,
|
|
963
|
+
// eslint-disable-next-line no-bitwise
|
|
964
|
+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION,
|
|
965
|
+
null
|
|
966
|
+
);
|
|
967
|
+
};
|
|
968
|
+
const _scrubTemplateExpressions = function _scrubTemplateExpressions2(node) {
|
|
969
|
+
node.normalize();
|
|
970
|
+
const walker = createNodeIterator.call(
|
|
971
|
+
node.ownerDocument || node,
|
|
972
|
+
node,
|
|
973
|
+
// eslint-disable-next-line no-bitwise
|
|
974
|
+
NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION,
|
|
975
|
+
null
|
|
976
|
+
);
|
|
977
|
+
let currentNode = walker.nextNode();
|
|
978
|
+
while (currentNode) {
|
|
979
|
+
let data = currentNode.data;
|
|
980
|
+
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
|
981
|
+
data = stringReplace(data, expr, " ");
|
|
982
|
+
});
|
|
983
|
+
currentNode.data = data;
|
|
984
|
+
currentNode = walker.nextNode();
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
const _isClobbered = function _isClobbered2(element) {
|
|
988
|
+
const realTagName = getNodeName ? getNodeName(element) : null;
|
|
989
|
+
if (typeof realTagName !== "string") {
|
|
990
|
+
return false;
|
|
991
|
+
}
|
|
992
|
+
if (transformCaseFunc(realTagName) !== "form") {
|
|
993
|
+
return false;
|
|
994
|
+
}
|
|
995
|
+
return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || // Realm-safe NamedNodeMap detection: equality against the cached
|
|
996
|
+
// prototype getter. Clobbered .attributes (e.g. <input name="attributes">)
|
|
997
|
+
// makes the direct read diverge from the cached read; a clean form
|
|
998
|
+
// (same-realm OR foreign-realm) has both reads pointing at the same
|
|
999
|
+
// canonical NamedNodeMap.
|
|
1000
|
+
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
|
|
1001
|
+
// returns the integer 1 for any Element regardless of realm; direct
|
|
1002
|
+
// read on a clobbered form (e.g. <input name="nodeType">) returns
|
|
1003
|
+
// the named child element. Cheap addition — nodeType is read from
|
|
1004
|
+
// an internal slot, no serialization cost — and removes a residual
|
|
1005
|
+
// clobbering surface used by several mXSS / PI / comment branches
|
|
1006
|
+
// in _sanitizeElements that compare currentNode.nodeType directly.
|
|
1007
|
+
element.nodeType !== getNodeType(element) || // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
|
|
1008
|
+
// "childNodes" shadows the prototype getter. Direct reads of
|
|
1009
|
+
// form.childNodes from a clobbered form return the named child
|
|
1010
|
+
// instead of the real NodeList, so any walk that reads it directly
|
|
1011
|
+
// skips the form's real children. Compare the direct read to the
|
|
1012
|
+
// cached Node.prototype getter — when the form's named-property
|
|
1013
|
+
// getter intercepts the read, the two values differ and we flag
|
|
1014
|
+
// the form. This catches every clobbering child type (input,
|
|
1015
|
+
// select, etc.) regardless of whether the named child happens to
|
|
1016
|
+
// carry a numeric .length, which a typeof-based probe would miss
|
|
1017
|
+
// (e.g. HTMLSelectElement.length is a defined unsigned-long).
|
|
1018
|
+
element.childNodes !== getChildNodes(element);
|
|
1019
|
+
};
|
|
1020
|
+
const _isDocumentFragment = function _isDocumentFragment2(value) {
|
|
1021
|
+
if (!getNodeType || typeof value !== "object" || value === null) {
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
try {
|
|
1025
|
+
return getNodeType(value) === NODE_TYPE.documentFragment;
|
|
1026
|
+
} catch (_2) {
|
|
1027
|
+
return false;
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
const _isNode = function _isNode2(value) {
|
|
1031
|
+
if (!getNodeType || typeof value !== "object" || value === null) {
|
|
1032
|
+
return false;
|
|
1033
|
+
}
|
|
1034
|
+
try {
|
|
1035
|
+
return typeof getNodeType(value) === "number";
|
|
1036
|
+
} catch (_2) {
|
|
1037
|
+
return false;
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
function _executeHooks(hooks2, currentNode, data) {
|
|
1041
|
+
arrayForEach(hooks2, (hook) => {
|
|
1042
|
+
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
const _sanitizeElements = function _sanitizeElements2(currentNode) {
|
|
1046
|
+
let content = null;
|
|
1047
|
+
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
|
1048
|
+
if (_isClobbered(currentNode)) {
|
|
1049
|
+
_forceRemove(currentNode);
|
|
1050
|
+
return true;
|
|
1051
|
+
}
|
|
1052
|
+
const tagName = transformCaseFunc(currentNode.nodeName);
|
|
1053
|
+
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
|
1054
|
+
tagName,
|
|
1055
|
+
allowedTags: ALLOWED_TAGS2
|
|
1056
|
+
});
|
|
1057
|
+
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
1058
|
+
_forceRemove(currentNode);
|
|
1059
|
+
return true;
|
|
1060
|
+
}
|
|
1061
|
+
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
|
|
1062
|
+
_forceRemove(currentNode);
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1065
|
+
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
1066
|
+
_forceRemove(currentNode);
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
1069
|
+
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
|
1070
|
+
_forceRemove(currentNode);
|
|
1071
|
+
return true;
|
|
1072
|
+
}
|
|
1073
|
+
if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS2[tagName]) {
|
|
1074
|
+
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
1075
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
1076
|
+
return false;
|
|
1077
|
+
}
|
|
1078
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
|
|
1079
|
+
return false;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
1083
|
+
const parentNode = getParentNode(currentNode);
|
|
1084
|
+
const childNodes = getChildNodes(currentNode);
|
|
1085
|
+
if (childNodes && parentNode) {
|
|
1086
|
+
const childCount = childNodes.length;
|
|
1087
|
+
for (let i = childCount - 1; i >= 0; --i) {
|
|
1088
|
+
const childClone = cloneNode(childNodes[i], true);
|
|
1089
|
+
parentNode.insertBefore(childClone, getNextSibling(currentNode));
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
_forceRemove(currentNode);
|
|
1094
|
+
return true;
|
|
1095
|
+
}
|
|
1096
|
+
const nt2 = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
|
|
1097
|
+
if (nt2 === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
|
|
1098
|
+
_forceRemove(currentNode);
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1101
|
+
if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
|
|
1102
|
+
_forceRemove(currentNode);
|
|
1103
|
+
return true;
|
|
1104
|
+
}
|
|
1105
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
|
1106
|
+
content = currentNode.textContent;
|
|
1107
|
+
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
|
1108
|
+
content = stringReplace(content, expr, " ");
|
|
1109
|
+
});
|
|
1110
|
+
if (currentNode.textContent !== content) {
|
|
1111
|
+
arrayPush(DOMPurify.removed, {
|
|
1112
|
+
element: currentNode.cloneNode()
|
|
1113
|
+
});
|
|
1114
|
+
currentNode.textContent = content;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
_executeHooks(hooks.afterSanitizeElements, currentNode, null);
|
|
1118
|
+
return false;
|
|
1119
|
+
};
|
|
1120
|
+
const _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value) {
|
|
1121
|
+
if (FORBID_ATTR[lcName]) {
|
|
1122
|
+
return false;
|
|
1123
|
+
}
|
|
1124
|
+
if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
const nameIsPermitted = ALLOWED_ATTR2[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
|
|
1128
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ;
|
|
1129
|
+
else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;
|
|
1130
|
+
else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
|
|
1131
|
+
if (
|
|
1132
|
+
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1133
|
+
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1134
|
+
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1135
|
+
_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
|
|
1136
|
+
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1137
|
+
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))
|
|
1138
|
+
) ;
|
|
1139
|
+
else {
|
|
1140
|
+
return false;
|
|
1141
|
+
}
|
|
1142
|
+
} else if (URI_SAFE_ATTRIBUTES[lcName]) ;
|
|
1143
|
+
else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ;
|
|
1144
|
+
else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) ;
|
|
1145
|
+
else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ;
|
|
1146
|
+
else if (value) {
|
|
1147
|
+
return false;
|
|
1148
|
+
} else ;
|
|
1149
|
+
return true;
|
|
1150
|
+
};
|
|
1151
|
+
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"]);
|
|
1152
|
+
const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
|
|
1153
|
+
return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
|
|
1154
|
+
};
|
|
1155
|
+
const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
|
|
1156
|
+
_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
|
|
1157
|
+
const attributes = currentNode.attributes;
|
|
1158
|
+
if (!attributes || _isClobbered(currentNode)) {
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
const hookEvent = {
|
|
1162
|
+
attrName: "",
|
|
1163
|
+
attrValue: "",
|
|
1164
|
+
keepAttr: true,
|
|
1165
|
+
allowedAttributes: ALLOWED_ATTR2,
|
|
1166
|
+
forceKeepAttr: void 0
|
|
1167
|
+
};
|
|
1168
|
+
let l3 = attributes.length;
|
|
1169
|
+
while (l3--) {
|
|
1170
|
+
const attr = attributes[l3];
|
|
1171
|
+
const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
|
|
1172
|
+
const lcName = transformCaseFunc(name);
|
|
1173
|
+
const initValue = attrValue;
|
|
1174
|
+
let value = name === "value" ? initValue : stringTrim(initValue);
|
|
1175
|
+
hookEvent.attrName = lcName;
|
|
1176
|
+
hookEvent.attrValue = value;
|
|
1177
|
+
hookEvent.keepAttr = true;
|
|
1178
|
+
hookEvent.forceKeepAttr = void 0;
|
|
1179
|
+
_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
|
|
1180
|
+
value = hookEvent.attrValue;
|
|
1181
|
+
if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
|
|
1182
|
+
_removeAttribute(name, currentNode);
|
|
1183
|
+
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
1184
|
+
}
|
|
1185
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
1186
|
+
_removeAttribute(name, currentNode);
|
|
1187
|
+
continue;
|
|
1188
|
+
}
|
|
1189
|
+
if (lcName === "attributename" && stringMatch(value, "href")) {
|
|
1190
|
+
_removeAttribute(name, currentNode);
|
|
1191
|
+
continue;
|
|
1192
|
+
}
|
|
1193
|
+
if (hookEvent.forceKeepAttr) {
|
|
1194
|
+
continue;
|
|
1195
|
+
}
|
|
1196
|
+
if (!hookEvent.keepAttr) {
|
|
1197
|
+
_removeAttribute(name, currentNode);
|
|
1198
|
+
continue;
|
|
1199
|
+
}
|
|
1200
|
+
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
|
|
1201
|
+
_removeAttribute(name, currentNode);
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1205
|
+
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
|
1206
|
+
value = stringReplace(value, expr, " ");
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
const lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1210
|
+
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1211
|
+
_removeAttribute(name, currentNode);
|
|
1212
|
+
continue;
|
|
1213
|
+
}
|
|
1214
|
+
if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function") {
|
|
1215
|
+
if (namespaceURI) ;
|
|
1216
|
+
else {
|
|
1217
|
+
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
|
1218
|
+
case "TrustedHTML": {
|
|
1219
|
+
value = trustedTypesPolicy.createHTML(value);
|
|
1220
|
+
break;
|
|
1221
|
+
}
|
|
1222
|
+
case "TrustedScriptURL": {
|
|
1223
|
+
value = trustedTypesPolicy.createScriptURL(value);
|
|
1224
|
+
break;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
if (value !== initValue) {
|
|
1230
|
+
try {
|
|
1231
|
+
if (namespaceURI) {
|
|
1232
|
+
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
1233
|
+
} else {
|
|
1234
|
+
currentNode.setAttribute(name, value);
|
|
1235
|
+
}
|
|
1236
|
+
if (_isClobbered(currentNode)) {
|
|
1237
|
+
_forceRemove(currentNode);
|
|
1238
|
+
} else {
|
|
1239
|
+
arrayPop(DOMPurify.removed);
|
|
1240
|
+
}
|
|
1241
|
+
} catch (_2) {
|
|
1242
|
+
_removeAttribute(name, currentNode);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|
|
1247
|
+
};
|
|
1248
|
+
const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
|
|
1249
|
+
let shadowNode = null;
|
|
1250
|
+
const shadowIterator = _createNodeIterator(fragment);
|
|
1251
|
+
_executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
|
|
1252
|
+
while (shadowNode = shadowIterator.nextNode()) {
|
|
1253
|
+
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
|
|
1254
|
+
_sanitizeElements(shadowNode);
|
|
1255
|
+
_sanitizeAttributes(shadowNode);
|
|
1256
|
+
if (_isDocumentFragment(shadowNode.content)) {
|
|
1257
|
+
_sanitizeShadowDOM2(shadowNode.content);
|
|
1258
|
+
}
|
|
1259
|
+
const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
|
|
1260
|
+
if (shadowNodeType === NODE_TYPE.element) {
|
|
1261
|
+
const innerSr = getShadowRoot ? getShadowRoot(shadowNode) : shadowNode.shadowRoot;
|
|
1262
|
+
if (_isDocumentFragment(innerSr)) {
|
|
1263
|
+
_sanitizeAttachedShadowRoots2(innerSr);
|
|
1264
|
+
_sanitizeShadowDOM2(innerSr);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
|
|
1269
|
+
};
|
|
1270
|
+
const _sanitizeAttachedShadowRoots2 = function _sanitizeAttachedShadowRoots(root) {
|
|
1271
|
+
const nodeType = getNodeType ? getNodeType(root) : root.nodeType;
|
|
1272
|
+
if (nodeType === NODE_TYPE.element) {
|
|
1273
|
+
const sr = getShadowRoot ? getShadowRoot(root) : root.shadowRoot;
|
|
1274
|
+
if (_isDocumentFragment(sr)) {
|
|
1275
|
+
_sanitizeAttachedShadowRoots2(sr);
|
|
1276
|
+
_sanitizeShadowDOM2(sr);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
const childNodes = getChildNodes ? getChildNodes(root) : root.childNodes;
|
|
1280
|
+
if (!childNodes) {
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1283
|
+
const snapshot = [];
|
|
1284
|
+
arrayForEach(childNodes, (child) => {
|
|
1285
|
+
arrayPush(snapshot, child);
|
|
1286
|
+
});
|
|
1287
|
+
for (const child of snapshot) {
|
|
1288
|
+
_sanitizeAttachedShadowRoots2(child);
|
|
1289
|
+
}
|
|
1290
|
+
if (nodeType === NODE_TYPE.element) {
|
|
1291
|
+
const rootName = getNodeName ? getNodeName(root) : null;
|
|
1292
|
+
if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
|
|
1293
|
+
const content = root.content;
|
|
1294
|
+
if (_isDocumentFragment(content)) {
|
|
1295
|
+
_sanitizeAttachedShadowRoots2(content);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
DOMPurify.sanitize = function(dirty) {
|
|
1301
|
+
let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
1302
|
+
let body = null;
|
|
1303
|
+
let importedNode = null;
|
|
1304
|
+
let currentNode = null;
|
|
1305
|
+
let returnNode = null;
|
|
1306
|
+
IS_EMPTY_INPUT = !dirty;
|
|
1307
|
+
if (IS_EMPTY_INPUT) {
|
|
1308
|
+
dirty = "<!-->";
|
|
1309
|
+
}
|
|
1310
|
+
if (typeof dirty !== "string" && !_isNode(dirty)) {
|
|
1311
|
+
dirty = stringifyValue(dirty);
|
|
1312
|
+
if (typeof dirty !== "string") {
|
|
1313
|
+
throw typeErrorCreate("dirty is not a string, aborting");
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
if (!DOMPurify.isSupported) {
|
|
1317
|
+
return dirty;
|
|
1318
|
+
}
|
|
1319
|
+
if (!SET_CONFIG) {
|
|
1320
|
+
_parseConfig(cfg);
|
|
1321
|
+
}
|
|
1322
|
+
DOMPurify.removed = [];
|
|
1323
|
+
if (typeof dirty === "string") {
|
|
1324
|
+
IN_PLACE = false;
|
|
1325
|
+
}
|
|
1326
|
+
if (IN_PLACE) {
|
|
1327
|
+
const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
|
|
1328
|
+
if (typeof nn === "string") {
|
|
1329
|
+
const tagName = transformCaseFunc(nn);
|
|
1330
|
+
if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
|
|
1331
|
+
throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
if (_isClobbered(dirty)) {
|
|
1335
|
+
throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
|
|
1336
|
+
}
|
|
1337
|
+
_sanitizeAttachedShadowRoots2(dirty);
|
|
1338
|
+
} else if (_isNode(dirty)) {
|
|
1339
|
+
body = _initDocument("<!---->");
|
|
1340
|
+
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1341
|
+
if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") {
|
|
1342
|
+
body = importedNode;
|
|
1343
|
+
} else if (importedNode.nodeName === "HTML") {
|
|
1344
|
+
body = importedNode;
|
|
1345
|
+
} else {
|
|
1346
|
+
body.appendChild(importedNode);
|
|
1347
|
+
}
|
|
1348
|
+
_sanitizeAttachedShadowRoots2(importedNode);
|
|
1349
|
+
} else {
|
|
1350
|
+
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
|
|
1351
|
+
dirty.indexOf("<") === -1) {
|
|
1352
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1353
|
+
}
|
|
1354
|
+
body = _initDocument(dirty);
|
|
1355
|
+
if (!body) {
|
|
1356
|
+
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
if (body && FORCE_BODY) {
|
|
1360
|
+
_forceRemove(body.firstChild);
|
|
1361
|
+
}
|
|
1362
|
+
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
|
|
1363
|
+
while (currentNode = nodeIterator.nextNode()) {
|
|
1364
|
+
_sanitizeElements(currentNode);
|
|
1365
|
+
_sanitizeAttributes(currentNode);
|
|
1366
|
+
if (_isDocumentFragment(currentNode.content)) {
|
|
1367
|
+
_sanitizeShadowDOM2(currentNode.content);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (IN_PLACE) {
|
|
1371
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1372
|
+
_scrubTemplateExpressions(dirty);
|
|
1373
|
+
}
|
|
1374
|
+
return dirty;
|
|
1375
|
+
}
|
|
1376
|
+
if (RETURN_DOM) {
|
|
1377
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1378
|
+
_scrubTemplateExpressions(body);
|
|
1379
|
+
}
|
|
1380
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
1381
|
+
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
1382
|
+
while (body.firstChild) {
|
|
1383
|
+
returnNode.appendChild(body.firstChild);
|
|
1384
|
+
}
|
|
1385
|
+
} else {
|
|
1386
|
+
returnNode = body;
|
|
1387
|
+
}
|
|
1388
|
+
if (ALLOWED_ATTR2.shadowroot || ALLOWED_ATTR2.shadowrootmode) {
|
|
1389
|
+
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
1390
|
+
}
|
|
1391
|
+
return returnNode;
|
|
1392
|
+
}
|
|
1393
|
+
let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
1394
|
+
if (WHOLE_DOCUMENT && ALLOWED_TAGS2["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
|
1395
|
+
serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
|
|
1396
|
+
}
|
|
1397
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1398
|
+
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
|
1399
|
+
serializedHTML = stringReplace(serializedHTML, expr, " ");
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
1403
|
+
};
|
|
1404
|
+
DOMPurify.setConfig = function() {
|
|
1405
|
+
let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
|
1406
|
+
_parseConfig(cfg);
|
|
1407
|
+
SET_CONFIG = true;
|
|
1408
|
+
};
|
|
1409
|
+
DOMPurify.clearConfig = function() {
|
|
1410
|
+
CONFIG = null;
|
|
1411
|
+
SET_CONFIG = false;
|
|
1412
|
+
};
|
|
1413
|
+
DOMPurify.isValidAttribute = function(tag, attr, value) {
|
|
1414
|
+
if (!CONFIG) {
|
|
1415
|
+
_parseConfig({});
|
|
1416
|
+
}
|
|
1417
|
+
const lcTag = transformCaseFunc(tag);
|
|
1418
|
+
const lcName = transformCaseFunc(attr);
|
|
1419
|
+
return _isValidAttribute(lcTag, lcName, value);
|
|
1420
|
+
};
|
|
1421
|
+
DOMPurify.addHook = function(entryPoint, hookFunction) {
|
|
1422
|
+
if (typeof hookFunction !== "function") {
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
arrayPush(hooks[entryPoint], hookFunction);
|
|
1426
|
+
};
|
|
1427
|
+
DOMPurify.removeHook = function(entryPoint, hookFunction) {
|
|
1428
|
+
if (hookFunction !== void 0) {
|
|
1429
|
+
const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
|
|
1430
|
+
return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
|
|
1431
|
+
}
|
|
1432
|
+
return arrayPop(hooks[entryPoint]);
|
|
1433
|
+
};
|
|
1434
|
+
DOMPurify.removeHooks = function(entryPoint) {
|
|
1435
|
+
hooks[entryPoint] = [];
|
|
1436
|
+
};
|
|
1437
|
+
DOMPurify.removeAllHooks = function() {
|
|
1438
|
+
hooks = _createHooksMap();
|
|
1439
|
+
};
|
|
1440
|
+
return DOMPurify;
|
|
1441
|
+
}
|
|
1442
|
+
var purify = createDOMPurify();
|
|
1443
|
+
|
|
1444
|
+
// node_modules/.pnpm/marked@18.0.4/node_modules/marked/lib/marked.esm.js
|
|
1445
|
+
function M() {
|
|
1446
|
+
return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
|
|
1447
|
+
}
|
|
1448
|
+
var T = M();
|
|
1449
|
+
function N(l3) {
|
|
1450
|
+
T = l3;
|
|
1451
|
+
}
|
|
1452
|
+
var _ = { exec: () => null };
|
|
1453
|
+
function E(l3) {
|
|
1454
|
+
let e = [];
|
|
1455
|
+
return (t) => {
|
|
1456
|
+
let n = Math.max(0, Math.min(3, t - 1)), s = e[n];
|
|
1457
|
+
return s || (s = l3(n), e[n] = s), s;
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
function d(l3, e = "") {
|
|
1461
|
+
let t = typeof l3 == "string" ? l3 : l3.source, n = { replace: (s, r) => {
|
|
1462
|
+
let i = typeof r == "string" ? r : r.source;
|
|
1463
|
+
return i = i.replace(m.caret, "$1"), t = t.replace(s, i), n;
|
|
1464
|
+
}, getRegex: () => new RegExp(t, e) };
|
|
1465
|
+
return n;
|
|
1466
|
+
}
|
|
1467
|
+
var Te = ((l3 = "") => {
|
|
1468
|
+
try {
|
|
1469
|
+
return !!new RegExp("(?<=1)(?<!1)" + l3);
|
|
1470
|
+
} catch {
|
|
1471
|
+
return false;
|
|
1472
|
+
}
|
|
1473
|
+
})();
|
|
1474
|
+
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, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (l3) => new RegExp(`^( {0,3}${l3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: E((l3) => new RegExp(`^ {0,${l3}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)), hrRegex: E((l3) => new RegExp(`^ {0,${l3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}(?:\`\`\`|~~~)`)), headingBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}#`)), htmlBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}>`)) };
|
|
1475
|
+
var Oe = /^(?:[ \t]*(?:\n|$))+/;
|
|
1476
|
+
var we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
|
|
1477
|
+
var ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
|
|
1478
|
+
var B = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
|
1479
|
+
var Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
|
|
1480
|
+
var j = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
|
|
1481
|
+
var oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
|
|
1482
|
+
var ae = d(oe).replace(/bull/g, j).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();
|
|
1483
|
+
var Se = d(oe).replace(/bull/g, j).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();
|
|
1484
|
+
var F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
|
|
1485
|
+
var $e = /^[^\n]+/;
|
|
1486
|
+
var U = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
|
|
1487
|
+
var Le = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", U).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
|
|
1488
|
+
var _e = d(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, j).getRegex();
|
|
1489
|
+
var H = "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";
|
|
1490
|
+
var K = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
|
|
1491
|
+
var ze = 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", K).replace("tag", H).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
|
|
1492
|
+
var le = d(F).replace("hr", B).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[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex();
|
|
1493
|
+
var Me = d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", le).getRegex();
|
|
1494
|
+
var W = { blockquote: Me, code: we, def: Le, fences: ye, heading: Pe, hr: B, html: ze, lheading: ae, list: _e, newline: Oe, paragraph: le, table: _, text: $e };
|
|
1495
|
+
var se = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", B).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[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex();
|
|
1496
|
+
var Ee = { ...W, lheading: Se, table: se, paragraph: d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex() };
|
|
1497
|
+
var Ie = { ...W, html: d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", K).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: _, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: d(F).replace("hr", B).replace("heading", ` *#{1,6} *[^
|
|
1498
|
+
]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
|
|
1499
|
+
var Ae = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
|
|
1500
|
+
var Ce = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
|
|
1501
|
+
var ue = /^( {2,}|\\)\n(?!\s*$)/;
|
|
1502
|
+
var Be = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
|
|
1503
|
+
var I = /[\p{P}\p{S}]/u;
|
|
1504
|
+
var Z = /[\s\p{P}\p{S}]/u;
|
|
1505
|
+
var X = /[^\s\p{P}\p{S}]/u;
|
|
1506
|
+
var De = d(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, Z).getRegex();
|
|
1507
|
+
var pe = /(?!~)[\p{P}\p{S}]/u;
|
|
1508
|
+
var qe = /(?!~)[\s\p{P}\p{S}]/u;
|
|
1509
|
+
var ve = /(?:[^\s\p{P}\p{S}]|~)/u;
|
|
1510
|
+
var He = d(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
|
|
1511
|
+
var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
|
|
1512
|
+
var Ze = d(ce, "u").replace(/punct/g, I).getRegex();
|
|
1513
|
+
var Ge = d(ce, "u").replace(/punct/g, pe).getRegex();
|
|
1514
|
+
var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
|
|
1515
|
+
var Ne = d(he, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex();
|
|
1516
|
+
var Qe = d(he, "gu").replace(/notPunctSpace/g, ve).replace(/punctSpace/g, qe).replace(/punct/g, pe).getRegex();
|
|
1517
|
+
var je = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex();
|
|
1518
|
+
var Fe = d(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, I).getRegex();
|
|
1519
|
+
var Ue = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)";
|
|
1520
|
+
var Ke = d(Ue, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex();
|
|
1521
|
+
var We = d(/\\(punct)/, "gu").replace(/punct/g, I).getRegex();
|
|
1522
|
+
var Xe = 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();
|
|
1523
|
+
var Je = d(K).replace("(?:-->|$)", "-->").getRegex();
|
|
1524
|
+
var Ve = 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", Je).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
|
|
1525
|
+
var v = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
|
|
1526
|
+
var Ye = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", v).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
|
|
1527
|
+
var ke = d(/^!?\[(label)\]\[(ref)\]/).replace("label", v).replace("ref", U).getRegex();
|
|
1528
|
+
var de = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", U).getRegex();
|
|
1529
|
+
var et = d("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
|
|
1530
|
+
var ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
|
|
1531
|
+
var J = { _backpedal: _, anyPunctuation: We, autolink: Xe, blockSkip: He, br: ue, code: Ce, del: _, delLDelim: _, delRDelim: _, emStrongLDelim: Ze, emStrongRDelimAst: Ne, emStrongRDelimUnd: je, escape: Ae, link: Ye, nolink: de, punctuation: De, reflink: ke, reflinkSearch: et, tag: Ve, text: Be, url: _ };
|
|
1532
|
+
var tt = { ...J, link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", v).getRegex(), reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", v).getRegex() };
|
|
1533
|
+
var Q = { ...J, emStrongRDelimAst: Qe, emStrongLDelim: Ge, delLDelim: Fe, delRDelim: Ke, url: d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).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", ie).getRegex() };
|
|
1534
|
+
var nt = { ...Q, br: d(ue).replace("{2,}", "*").getRegex(), text: d(Q.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
|
|
1535
|
+
var D = { normal: W, gfm: Ee, pedantic: Ie };
|
|
1536
|
+
var A = { normal: J, gfm: Q, breaks: nt, pedantic: tt };
|
|
1537
|
+
var rt = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
1538
|
+
var ge = (l3) => rt[l3];
|
|
1539
|
+
function O(l3, e) {
|
|
1540
|
+
if (e) {
|
|
1541
|
+
if (m.escapeTest.test(l3)) return l3.replace(m.escapeReplace, ge);
|
|
1542
|
+
} else if (m.escapeTestNoEncode.test(l3)) return l3.replace(m.escapeReplaceNoEncode, ge);
|
|
1543
|
+
return l3;
|
|
1544
|
+
}
|
|
1545
|
+
function V(l3) {
|
|
1546
|
+
try {
|
|
1547
|
+
l3 = encodeURI(l3).replace(m.percentDecode, "%");
|
|
1548
|
+
} catch {
|
|
1549
|
+
return null;
|
|
1550
|
+
}
|
|
1551
|
+
return l3;
|
|
1552
|
+
}
|
|
1553
|
+
function Y(l3, e) {
|
|
1554
|
+
let t = l3.replace(m.findPipe, (r, i, o) => {
|
|
1555
|
+
let u = false, a = i;
|
|
1556
|
+
for (; --a >= 0 && o[a] === "\\"; ) u = !u;
|
|
1557
|
+
return u ? "|" : " |";
|
|
1558
|
+
}), n = t.split(m.splitPipe), s = 0;
|
|
1559
|
+
if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
|
|
1560
|
+
else for (; n.length < e; ) n.push("");
|
|
1561
|
+
for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|");
|
|
1562
|
+
return n;
|
|
1563
|
+
}
|
|
1564
|
+
function $(l3, e, t) {
|
|
1565
|
+
let n = l3.length;
|
|
1566
|
+
if (n === 0) return "";
|
|
1567
|
+
let s = 0;
|
|
1568
|
+
for (; s < n; ) {
|
|
1569
|
+
let r = l3.charAt(n - s - 1);
|
|
1570
|
+
if (r === e && !t) s++;
|
|
1571
|
+
else if (r !== e && t) s++;
|
|
1572
|
+
else break;
|
|
1573
|
+
}
|
|
1574
|
+
return l3.slice(0, n - s);
|
|
1575
|
+
}
|
|
1576
|
+
function ee(l3) {
|
|
1577
|
+
let e = l3.split(`
|
|
1578
|
+
`), t = e.length - 1;
|
|
1579
|
+
for (; t >= 0 && m.blankLine.test(e[t]); ) t--;
|
|
1580
|
+
return e.length - t <= 2 ? l3 : e.slice(0, t + 1).join(`
|
|
1581
|
+
`);
|
|
1582
|
+
}
|
|
1583
|
+
function fe(l3, e) {
|
|
1584
|
+
if (l3.indexOf(e[1]) === -1) return -1;
|
|
1585
|
+
let t = 0;
|
|
1586
|
+
for (let n = 0; n < l3.length; n++) if (l3[n] === "\\") n++;
|
|
1587
|
+
else if (l3[n] === e[0]) t++;
|
|
1588
|
+
else if (l3[n] === e[1] && (t--, t < 0)) return n;
|
|
1589
|
+
return t > 0 ? -2 : -1;
|
|
1590
|
+
}
|
|
1591
|
+
function me(l3, e = 0) {
|
|
1592
|
+
let t = e, n = "";
|
|
1593
|
+
for (let s of l3) if (s === " ") {
|
|
1594
|
+
let r = 4 - t % 4;
|
|
1595
|
+
n += " ".repeat(r), t += r;
|
|
1596
|
+
} else n += s, t++;
|
|
1597
|
+
return n;
|
|
1598
|
+
}
|
|
1599
|
+
function xe(l3, e, t, n, s) {
|
|
1600
|
+
let r = e.href, i = e.title || null, o = l3[1].replace(s.other.outputLinkReplace, "$1");
|
|
1601
|
+
n.state.inLink = true;
|
|
1602
|
+
let u = { type: l3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: r, title: i, text: o, tokens: n.inlineTokens(o) };
|
|
1603
|
+
return n.state.inLink = false, u;
|
|
1604
|
+
}
|
|
1605
|
+
function st(l3, e, t) {
|
|
1606
|
+
let n = l3.match(t.other.indentCodeCompensation);
|
|
1607
|
+
if (n === null) return e;
|
|
1608
|
+
let s = n[1];
|
|
1609
|
+
return e.split(`
|
|
1610
|
+
`).map((r) => {
|
|
1611
|
+
let i = r.match(t.other.beginningSpace);
|
|
1612
|
+
if (i === null) return r;
|
|
1613
|
+
let [o] = i;
|
|
1614
|
+
return o.length >= s.length ? r.slice(s.length) : r;
|
|
1615
|
+
}).join(`
|
|
1616
|
+
`);
|
|
1617
|
+
}
|
|
1618
|
+
var w = class {
|
|
1619
|
+
options;
|
|
1620
|
+
rules;
|
|
1621
|
+
lexer;
|
|
1622
|
+
constructor(e) {
|
|
1623
|
+
this.options = e || T;
|
|
1624
|
+
}
|
|
1625
|
+
space(e) {
|
|
1626
|
+
let t = this.rules.block.newline.exec(e);
|
|
1627
|
+
if (t && t[0].length > 0) return { type: "space", raw: t[0] };
|
|
1628
|
+
}
|
|
1629
|
+
code(e) {
|
|
1630
|
+
let t = this.rules.block.code.exec(e);
|
|
1631
|
+
if (t) {
|
|
1632
|
+
let n = this.options.pedantic ? t[0] : ee(t[0]), s = n.replace(this.rules.other.codeRemoveIndent, "");
|
|
1633
|
+
return { type: "code", raw: n, codeBlockStyle: "indented", text: s };
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
fences(e) {
|
|
1637
|
+
let t = this.rules.block.fences.exec(e);
|
|
1638
|
+
if (t) {
|
|
1639
|
+
let n = t[0], s = st(n, t[3] || "", this.rules);
|
|
1640
|
+
return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s };
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
heading(e) {
|
|
1644
|
+
let t = this.rules.block.heading.exec(e);
|
|
1645
|
+
if (t) {
|
|
1646
|
+
let n = t[2].trim();
|
|
1647
|
+
if (this.rules.other.endingHash.test(n)) {
|
|
1648
|
+
let s = $(n, "#");
|
|
1649
|
+
(this.options.pedantic || !s || this.rules.other.endingSpaceChar.test(s)) && (n = s.trim());
|
|
1650
|
+
}
|
|
1651
|
+
return { type: "heading", raw: $(t[0], `
|
|
1652
|
+
`), depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
hr(e) {
|
|
1656
|
+
let t = this.rules.block.hr.exec(e);
|
|
1657
|
+
if (t) return { type: "hr", raw: $(t[0], `
|
|
1658
|
+
`) };
|
|
1659
|
+
}
|
|
1660
|
+
blockquote(e) {
|
|
1661
|
+
let t = this.rules.block.blockquote.exec(e);
|
|
1662
|
+
if (t) {
|
|
1663
|
+
let n = $(t[0], `
|
|
1664
|
+
`).split(`
|
|
1665
|
+
`), s = "", r = "", i = [];
|
|
1666
|
+
for (; n.length > 0; ) {
|
|
1667
|
+
let o = false, u = [], a;
|
|
1668
|
+
for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a])) u.push(n[a]), o = true;
|
|
1669
|
+
else if (!o) u.push(n[a]);
|
|
1670
|
+
else break;
|
|
1671
|
+
n = n.slice(a);
|
|
1672
|
+
let c = u.join(`
|
|
1673
|
+
`), p = c.replace(this.rules.other.blockquoteSetextReplace, `
|
|
1674
|
+
$1`).replace(this.rules.other.blockquoteSetextReplace2, "");
|
|
1675
|
+
s = s ? `${s}
|
|
1676
|
+
${c}` : c, r = r ? `${r}
|
|
1677
|
+
${p}` : p;
|
|
1678
|
+
let k = this.lexer.state.top;
|
|
1679
|
+
if (this.lexer.state.top = true, this.lexer.blockTokens(p, i, true), this.lexer.state.top = k, n.length === 0) break;
|
|
1680
|
+
let h = i.at(-1);
|
|
1681
|
+
if (h?.type === "code") break;
|
|
1682
|
+
if (h?.type === "blockquote") {
|
|
1683
|
+
let R = h, f = R.raw + `
|
|
1684
|
+
` + n.join(`
|
|
1685
|
+
`), S = this.blockquote(f);
|
|
1686
|
+
i[i.length - 1] = S, s = s.substring(0, s.length - R.raw.length) + S.raw, r = r.substring(0, r.length - R.text.length) + S.text;
|
|
1687
|
+
break;
|
|
1688
|
+
} else if (h?.type === "list") {
|
|
1689
|
+
let R = h, f = R.raw + `
|
|
1690
|
+
` + n.join(`
|
|
1691
|
+
`), S = this.list(f);
|
|
1692
|
+
i[i.length - 1] = S, s = s.substring(0, s.length - h.raw.length) + S.raw, r = r.substring(0, r.length - R.raw.length) + S.raw, n = f.substring(i.at(-1).raw.length).split(`
|
|
1693
|
+
`);
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
return { type: "blockquote", raw: s, tokens: i, text: r };
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
list(e) {
|
|
1701
|
+
let t = this.rules.block.list.exec(e);
|
|
1702
|
+
if (t) {
|
|
1703
|
+
let n = t[1].trim(), s = n.length > 1, r = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] };
|
|
1704
|
+
n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
|
|
1705
|
+
let i = this.rules.other.listItemRegex(n), o = false;
|
|
1706
|
+
for (; e; ) {
|
|
1707
|
+
let a = false, c = "", p = "";
|
|
1708
|
+
if (!(t = i.exec(e)) || this.rules.block.hr.test(e)) break;
|
|
1709
|
+
c = t[0], e = e.substring(c.length);
|
|
1710
|
+
let k = me(t[2].split(`
|
|
1711
|
+
`, 1)[0], t[1].length), h = e.split(`
|
|
1712
|
+
`, 1)[0], R = !k.trim(), f = 0;
|
|
1713
|
+
if (this.options.pedantic ? (f = 2, p = k.trimStart()) : R ? f = t[1].length + 1 : (f = k.search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, p = k.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h) && (c += h + `
|
|
1714
|
+
`, e = e.substring(h.length + 1), a = true), !a) {
|
|
1715
|
+
let S = this.rules.other.nextBulletRegex(f), te = this.rules.other.hrRegex(f), ne = this.rules.other.fencesBeginRegex(f), re = this.rules.other.headingBeginRegex(f), be = this.rules.other.htmlBeginRegex(f), Re = this.rules.other.blockquoteBeginRegex(f);
|
|
1716
|
+
for (; e; ) {
|
|
1717
|
+
let G = e.split(`
|
|
1718
|
+
`, 1)[0], C;
|
|
1719
|
+
if (h = G, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), C = h) : C = h.replace(this.rules.other.tabCharGlobal, " "), ne.test(h) || re.test(h) || be.test(h) || Re.test(h) || S.test(h) || te.test(h)) break;
|
|
1720
|
+
if (C.search(this.rules.other.nonSpaceChar) >= f || !h.trim()) p += `
|
|
1721
|
+
` + C.slice(f);
|
|
1722
|
+
else {
|
|
1723
|
+
if (R || k.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(k) || re.test(k) || te.test(k)) break;
|
|
1724
|
+
p += `
|
|
1725
|
+
` + h;
|
|
1726
|
+
}
|
|
1727
|
+
R = !h.trim(), c += G + `
|
|
1728
|
+
`, e = e.substring(G.length + 1), k = C.slice(f);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
r.loose || (o ? r.loose = true : this.rules.other.doubleBlankLine.test(c) && (o = true)), r.items.push({ type: "list_item", raw: c, task: !!this.options.gfm && this.rules.other.listIsTask.test(p), loose: false, text: p, tokens: [] }), r.raw += c;
|
|
1732
|
+
}
|
|
1733
|
+
let u = r.items.at(-1);
|
|
1734
|
+
if (u) u.raw = u.raw.trimEnd(), u.text = u.text.trimEnd();
|
|
1735
|
+
else return;
|
|
1736
|
+
r.raw = r.raw.trimEnd();
|
|
1737
|
+
for (let a of r.items) {
|
|
1738
|
+
this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []);
|
|
1739
|
+
let c = a.tokens[0];
|
|
1740
|
+
if (a.task && (c?.type === "text" || c?.type === "paragraph")) {
|
|
1741
|
+
a.text = a.text.replace(this.rules.other.listReplaceTask, ""), c.raw = c.raw.replace(this.rules.other.listReplaceTask, ""), c.text = c.text.replace(this.rules.other.listReplaceTask, "");
|
|
1742
|
+
for (let k = this.lexer.inlineQueue.length - 1; k >= 0; k--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[k].src)) {
|
|
1743
|
+
this.lexer.inlineQueue[k].src = this.lexer.inlineQueue[k].src.replace(this.rules.other.listReplaceTask, "");
|
|
1744
|
+
break;
|
|
1745
|
+
}
|
|
1746
|
+
let p = this.rules.other.listTaskCheckbox.exec(a.raw);
|
|
1747
|
+
if (p) {
|
|
1748
|
+
let k = { type: "checkbox", raw: p[0] + " ", checked: p[0] !== "[ ]" };
|
|
1749
|
+
a.checked = k.checked, r.loose ? a.tokens[0] && ["paragraph", "text"].includes(a.tokens[0].type) && "tokens" in a.tokens[0] && a.tokens[0].tokens ? (a.tokens[0].raw = k.raw + a.tokens[0].raw, a.tokens[0].text = k.raw + a.tokens[0].text, a.tokens[0].tokens.unshift(k)) : a.tokens.unshift({ type: "paragraph", raw: k.raw, text: k.raw, tokens: [k] }) : a.tokens.unshift(k);
|
|
1750
|
+
}
|
|
1751
|
+
} else a.task && (a.task = false);
|
|
1752
|
+
if (!r.loose) {
|
|
1753
|
+
let p = a.tokens.filter((h) => h.type === "space"), k = p.length > 0 && p.some((h) => this.rules.other.anyLine.test(h.raw));
|
|
1754
|
+
r.loose = k;
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
if (r.loose) for (let a of r.items) {
|
|
1758
|
+
a.loose = true;
|
|
1759
|
+
for (let c of a.tokens) c.type === "text" && (c.type = "paragraph");
|
|
1760
|
+
}
|
|
1761
|
+
return r;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
html(e) {
|
|
1765
|
+
let t = this.rules.block.html.exec(e);
|
|
1766
|
+
if (t) {
|
|
1767
|
+
let n = ee(t[0]);
|
|
1768
|
+
return { type: "html", block: true, raw: n, pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: n };
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
def(e) {
|
|
1772
|
+
let t = this.rules.block.def.exec(e);
|
|
1773
|
+
if (t) {
|
|
1774
|
+
let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", r = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
|
|
1775
|
+
return { type: "def", tag: n, raw: $(t[0], `
|
|
1776
|
+
`), href: s, title: r };
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
table(e) {
|
|
1780
|
+
let t = this.rules.block.table.exec(e);
|
|
1781
|
+
if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
|
|
1782
|
+
let n = Y(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), r = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
|
|
1783
|
+
`) : [], i = { type: "table", raw: $(t[0], `
|
|
1784
|
+
`), header: [], align: [], rows: [] };
|
|
1785
|
+
if (n.length === s.length) {
|
|
1786
|
+
for (let o of s) this.rules.other.tableAlignRight.test(o) ? i.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? i.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? i.align.push("left") : i.align.push(null);
|
|
1787
|
+
for (let o = 0; o < n.length; o++) i.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: i.align[o] });
|
|
1788
|
+
for (let o of r) i.rows.push(Y(o, i.header.length).map((u, a) => ({ text: u, tokens: this.lexer.inline(u), header: false, align: i.align[a] })));
|
|
1789
|
+
return i;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
lheading(e) {
|
|
1793
|
+
let t = this.rules.block.lheading.exec(e);
|
|
1794
|
+
if (t) {
|
|
1795
|
+
let n = t[1].trim();
|
|
1796
|
+
return { type: "heading", raw: $(t[0], `
|
|
1797
|
+
`), depth: t[2].charAt(0) === "=" ? 1 : 2, text: n, tokens: this.lexer.inline(n) };
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
paragraph(e) {
|
|
1801
|
+
let t = this.rules.block.paragraph.exec(e);
|
|
1802
|
+
if (t) {
|
|
1803
|
+
let n = t[1].charAt(t[1].length - 1) === `
|
|
1804
|
+
` ? t[1].slice(0, -1) : t[1];
|
|
1805
|
+
return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
text(e) {
|
|
1809
|
+
let t = this.rules.block.text.exec(e);
|
|
1810
|
+
if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
|
|
1811
|
+
}
|
|
1812
|
+
escape(e) {
|
|
1813
|
+
let t = this.rules.inline.escape.exec(e);
|
|
1814
|
+
if (t) return { type: "escape", raw: t[0], text: t[1] };
|
|
1815
|
+
}
|
|
1816
|
+
tag(e) {
|
|
1817
|
+
let t = this.rules.inline.tag.exec(e);
|
|
1818
|
+
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] };
|
|
1819
|
+
}
|
|
1820
|
+
link(e) {
|
|
1821
|
+
let t = this.rules.inline.link.exec(e);
|
|
1822
|
+
if (t) {
|
|
1823
|
+
let n = t[2].trim();
|
|
1824
|
+
if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
|
|
1825
|
+
if (!this.rules.other.endAngleBracket.test(n)) return;
|
|
1826
|
+
let i = $(n.slice(0, -1), "\\");
|
|
1827
|
+
if ((n.length - i.length) % 2 === 0) return;
|
|
1828
|
+
} else {
|
|
1829
|
+
let i = fe(t[2], "()");
|
|
1830
|
+
if (i === -2) return;
|
|
1831
|
+
if (i > -1) {
|
|
1832
|
+
let u = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + i;
|
|
1833
|
+
t[2] = t[2].substring(0, i), t[0] = t[0].substring(0, u).trim(), t[3] = "";
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
let s = t[2], r = "";
|
|
1837
|
+
if (this.options.pedantic) {
|
|
1838
|
+
let i = this.rules.other.pedanticHrefTitle.exec(s);
|
|
1839
|
+
i && (s = i[1], r = i[3]);
|
|
1840
|
+
} else r = t[3] ? t[3].slice(1, -1) : "";
|
|
1841
|
+
return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), xe(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: r && r.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
reflink(e, t) {
|
|
1845
|
+
let n;
|
|
1846
|
+
if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
|
|
1847
|
+
let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), r = t[s.toLowerCase()];
|
|
1848
|
+
if (!r) {
|
|
1849
|
+
let i = n[0].charAt(0);
|
|
1850
|
+
return { type: "text", raw: i, text: i };
|
|
1851
|
+
}
|
|
1852
|
+
return xe(n, r, n[0], this.lexer, this.rules);
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
emStrong(e, t, n = "") {
|
|
1856
|
+
let s = this.rules.inline.emStrongLDelim.exec(e);
|
|
1857
|
+
if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
|
|
1858
|
+
if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
|
|
1859
|
+
let i = [...s[0]].length - 1, o, u, a = i, c = 0, p = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
|
|
1860
|
+
for (p.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = p.exec(t)) !== null; ) {
|
|
1861
|
+
if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue;
|
|
1862
|
+
if (u = [...o].length, s[3] || s[4]) {
|
|
1863
|
+
a += u;
|
|
1864
|
+
continue;
|
|
1865
|
+
} else if ((s[5] || s[6]) && i % 3 && !((i + u) % 3)) {
|
|
1866
|
+
c += u;
|
|
1867
|
+
continue;
|
|
1868
|
+
}
|
|
1869
|
+
if (a -= u, a > 0) continue;
|
|
1870
|
+
u = Math.min(u, u + a + c);
|
|
1871
|
+
let k = [...s[0]][0].length, h = e.slice(0, i + s.index + k + u);
|
|
1872
|
+
if (Math.min(i, u) % 2) {
|
|
1873
|
+
let f = h.slice(1, -1);
|
|
1874
|
+
return { type: "em", raw: h, text: f, tokens: this.lexer.inlineTokens(f) };
|
|
1875
|
+
}
|
|
1876
|
+
let R = h.slice(2, -2);
|
|
1877
|
+
return { type: "strong", raw: h, text: R, tokens: this.lexer.inlineTokens(R) };
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
codespan(e) {
|
|
1882
|
+
let t = this.rules.inline.code.exec(e);
|
|
1883
|
+
if (t) {
|
|
1884
|
+
let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), s = this.rules.other.nonSpaceChar.test(n), r = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
|
|
1885
|
+
return s && r && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
br(e) {
|
|
1889
|
+
let t = this.rules.inline.br.exec(e);
|
|
1890
|
+
if (t) return { type: "br", raw: t[0] };
|
|
1891
|
+
}
|
|
1892
|
+
del(e, t, n = "") {
|
|
1893
|
+
let s = this.rules.inline.delLDelim.exec(e);
|
|
1894
|
+
if (!s) return;
|
|
1895
|
+
if (!(s[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
|
|
1896
|
+
let i = [...s[0]].length - 1, o, u, a = i, c = this.rules.inline.delRDelim;
|
|
1897
|
+
for (c.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = c.exec(t)) !== null; ) {
|
|
1898
|
+
if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o || (u = [...o].length, u !== i)) continue;
|
|
1899
|
+
if (s[3] || s[4]) {
|
|
1900
|
+
a += u;
|
|
1901
|
+
continue;
|
|
1902
|
+
}
|
|
1903
|
+
if (a -= u, a > 0) continue;
|
|
1904
|
+
u = Math.min(u, u + a);
|
|
1905
|
+
let p = [...s[0]][0].length, k = e.slice(0, i + s.index + p + u), h = k.slice(i, -i);
|
|
1906
|
+
return { type: "del", raw: k, text: h, tokens: this.lexer.inlineTokens(h) };
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
autolink(e) {
|
|
1911
|
+
let t = this.rules.inline.autolink.exec(e);
|
|
1912
|
+
if (t) {
|
|
1913
|
+
let n, s;
|
|
1914
|
+
return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
url(e) {
|
|
1918
|
+
let t;
|
|
1919
|
+
if (t = this.rules.inline.url.exec(e)) {
|
|
1920
|
+
let n, s;
|
|
1921
|
+
if (t[2] === "@") n = t[0], s = "mailto:" + n;
|
|
1922
|
+
else {
|
|
1923
|
+
let r;
|
|
1924
|
+
do
|
|
1925
|
+
r = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
|
|
1926
|
+
while (r !== t[0]);
|
|
1927
|
+
n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0];
|
|
1928
|
+
}
|
|
1929
|
+
return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
inlineText(e) {
|
|
1933
|
+
let t = this.rules.inline.text.exec(e);
|
|
1934
|
+
if (t) {
|
|
1935
|
+
let n = this.lexer.state.inRawBlock;
|
|
1936
|
+
return { type: "text", raw: t[0], text: t[0], escaped: n };
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
};
|
|
1940
|
+
var x = class l {
|
|
1941
|
+
tokens;
|
|
1942
|
+
options;
|
|
1943
|
+
state;
|
|
1944
|
+
inlineQueue;
|
|
1945
|
+
tokenizer;
|
|
1946
|
+
constructor(e) {
|
|
1947
|
+
this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new w(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
|
|
1948
|
+
let t = { other: m, block: D.normal, inline: A.normal };
|
|
1949
|
+
this.options.pedantic ? (t.block = D.pedantic, t.inline = A.pedantic) : this.options.gfm && (t.block = D.gfm, this.options.breaks ? t.inline = A.breaks : t.inline = A.gfm), this.tokenizer.rules = t;
|
|
1950
|
+
}
|
|
1951
|
+
static get rules() {
|
|
1952
|
+
return { block: D, inline: A };
|
|
1953
|
+
}
|
|
1954
|
+
static lex(e, t) {
|
|
1955
|
+
return new l(t).lex(e);
|
|
1956
|
+
}
|
|
1957
|
+
static lexInline(e, t) {
|
|
1958
|
+
return new l(t).inlineTokens(e);
|
|
1959
|
+
}
|
|
1960
|
+
lex(e) {
|
|
1961
|
+
e = e.replace(m.carriageReturn, `
|
|
1962
|
+
`), this.blockTokens(e, this.tokens);
|
|
1963
|
+
for (let t = 0; t < this.inlineQueue.length; t++) {
|
|
1964
|
+
let n = this.inlineQueue[t];
|
|
1965
|
+
this.inlineTokens(n.src, n.tokens);
|
|
1966
|
+
}
|
|
1967
|
+
return this.inlineQueue = [], this.tokens;
|
|
1968
|
+
}
|
|
1969
|
+
blockTokens(e, t = [], n = false) {
|
|
1970
|
+
this.tokenizer.lexer = this, this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, ""));
|
|
1971
|
+
let s = 1 / 0;
|
|
1972
|
+
for (; e; ) {
|
|
1973
|
+
if (e.length < s) s = e.length;
|
|
1974
|
+
else {
|
|
1975
|
+
this.infiniteLoopError(e.charCodeAt(0));
|
|
1976
|
+
break;
|
|
1977
|
+
}
|
|
1978
|
+
let r;
|
|
1979
|
+
if (this.options.extensions?.block?.some((o) => (r = o.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
|
|
1980
|
+
if (r = this.tokenizer.space(e)) {
|
|
1981
|
+
e = e.substring(r.raw.length);
|
|
1982
|
+
let o = t.at(-1);
|
|
1983
|
+
r.raw.length === 1 && o !== void 0 ? o.raw += `
|
|
1984
|
+
` : t.push(r);
|
|
1985
|
+
continue;
|
|
1986
|
+
}
|
|
1987
|
+
if (r = this.tokenizer.code(e)) {
|
|
1988
|
+
e = e.substring(r.raw.length);
|
|
1989
|
+
let o = t.at(-1);
|
|
1990
|
+
o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(`
|
|
1991
|
+
`) ? "" : `
|
|
1992
|
+
`) + r.raw, o.text += `
|
|
1993
|
+
` + r.text, this.inlineQueue.at(-1).src = o.text) : t.push(r);
|
|
1994
|
+
continue;
|
|
1995
|
+
}
|
|
1996
|
+
if (r = this.tokenizer.fences(e)) {
|
|
1997
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
1998
|
+
continue;
|
|
1999
|
+
}
|
|
2000
|
+
if (r = this.tokenizer.heading(e)) {
|
|
2001
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2002
|
+
continue;
|
|
2003
|
+
}
|
|
2004
|
+
if (r = this.tokenizer.hr(e)) {
|
|
2005
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2006
|
+
continue;
|
|
2007
|
+
}
|
|
2008
|
+
if (r = this.tokenizer.blockquote(e)) {
|
|
2009
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2010
|
+
continue;
|
|
2011
|
+
}
|
|
2012
|
+
if (r = this.tokenizer.list(e)) {
|
|
2013
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2014
|
+
continue;
|
|
2015
|
+
}
|
|
2016
|
+
if (r = this.tokenizer.html(e)) {
|
|
2017
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2018
|
+
continue;
|
|
2019
|
+
}
|
|
2020
|
+
if (r = this.tokenizer.def(e)) {
|
|
2021
|
+
e = e.substring(r.raw.length);
|
|
2022
|
+
let o = t.at(-1);
|
|
2023
|
+
o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(`
|
|
2024
|
+
`) ? "" : `
|
|
2025
|
+
`) + r.raw, o.text += `
|
|
2026
|
+
` + r.raw, this.inlineQueue.at(-1).src = o.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
|
|
2027
|
+
continue;
|
|
2028
|
+
}
|
|
2029
|
+
if (r = this.tokenizer.table(e)) {
|
|
2030
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2031
|
+
continue;
|
|
2032
|
+
}
|
|
2033
|
+
if (r = this.tokenizer.lheading(e)) {
|
|
2034
|
+
e = e.substring(r.raw.length), t.push(r);
|
|
2035
|
+
continue;
|
|
2036
|
+
}
|
|
2037
|
+
let i = e;
|
|
2038
|
+
if (this.options.extensions?.startBlock) {
|
|
2039
|
+
let o = 1 / 0, u = e.slice(1), a;
|
|
2040
|
+
this.options.extensions.startBlock.forEach((c) => {
|
|
2041
|
+
a = c.call({ lexer: this }, u), typeof a == "number" && a >= 0 && (o = Math.min(o, a));
|
|
2042
|
+
}), o < 1 / 0 && o >= 0 && (i = e.substring(0, o + 1));
|
|
2043
|
+
}
|
|
2044
|
+
if (this.state.top && (r = this.tokenizer.paragraph(i))) {
|
|
2045
|
+
let o = t.at(-1);
|
|
2046
|
+
n && o?.type === "paragraph" ? (o.raw += (o.raw.endsWith(`
|
|
2047
|
+
`) ? "" : `
|
|
2048
|
+
`) + r.raw, o.text += `
|
|
2049
|
+
` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length);
|
|
2050
|
+
continue;
|
|
2051
|
+
}
|
|
2052
|
+
if (r = this.tokenizer.text(e)) {
|
|
2053
|
+
e = e.substring(r.raw.length);
|
|
2054
|
+
let o = t.at(-1);
|
|
2055
|
+
o?.type === "text" ? (o.raw += (o.raw.endsWith(`
|
|
2056
|
+
`) ? "" : `
|
|
2057
|
+
`) + r.raw, o.text += `
|
|
2058
|
+
` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t.push(r);
|
|
2059
|
+
continue;
|
|
2060
|
+
}
|
|
2061
|
+
if (e) {
|
|
2062
|
+
this.infiniteLoopError(e.charCodeAt(0));
|
|
2063
|
+
break;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
return this.state.top = true, t;
|
|
2067
|
+
}
|
|
2068
|
+
inline(e, t = []) {
|
|
2069
|
+
return this.inlineQueue.push({ src: e, tokens: t }), t;
|
|
2070
|
+
}
|
|
2071
|
+
inlineTokens(e, t = []) {
|
|
2072
|
+
this.tokenizer.lexer = this;
|
|
2073
|
+
let n = e, s = null;
|
|
2074
|
+
if (this.tokens.links) {
|
|
2075
|
+
let a = Object.keys(this.tokens.links);
|
|
2076
|
+
if (a.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(n)) !== null; ) a.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
|
|
2077
|
+
}
|
|
2078
|
+
for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(n)) !== null; ) n = n.slice(0, s.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
|
|
2079
|
+
let r;
|
|
2080
|
+
for (; (s = this.tokenizer.rules.inline.blockSkip.exec(n)) !== null; ) r = s[2] ? s[2].length : 0, n = n.slice(0, s.index + r) + "[" + "a".repeat(s[0].length - r - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
|
2081
|
+
n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
|
|
2082
|
+
let i = false, o = "", u = 1 / 0;
|
|
2083
|
+
for (; e; ) {
|
|
2084
|
+
if (e.length < u) u = e.length;
|
|
2085
|
+
else {
|
|
2086
|
+
this.infiniteLoopError(e.charCodeAt(0));
|
|
2087
|
+
break;
|
|
2088
|
+
}
|
|
2089
|
+
i || (o = ""), i = false;
|
|
2090
|
+
let a;
|
|
2091
|
+
if (this.options.extensions?.inline?.some((p) => (a = p.call({ lexer: this }, e, t)) ? (e = e.substring(a.raw.length), t.push(a), true) : false)) continue;
|
|
2092
|
+
if (a = this.tokenizer.escape(e)) {
|
|
2093
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
if (a = this.tokenizer.tag(e)) {
|
|
2097
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2098
|
+
continue;
|
|
2099
|
+
}
|
|
2100
|
+
if (a = this.tokenizer.link(e)) {
|
|
2101
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2102
|
+
continue;
|
|
2103
|
+
}
|
|
2104
|
+
if (a = this.tokenizer.reflink(e, this.tokens.links)) {
|
|
2105
|
+
e = e.substring(a.raw.length);
|
|
2106
|
+
let p = t.at(-1);
|
|
2107
|
+
a.type === "text" && p?.type === "text" ? (p.raw += a.raw, p.text += a.text) : t.push(a);
|
|
2108
|
+
continue;
|
|
2109
|
+
}
|
|
2110
|
+
if (a = this.tokenizer.emStrong(e, n, o)) {
|
|
2111
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2112
|
+
continue;
|
|
2113
|
+
}
|
|
2114
|
+
if (a = this.tokenizer.codespan(e)) {
|
|
2115
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2116
|
+
continue;
|
|
2117
|
+
}
|
|
2118
|
+
if (a = this.tokenizer.br(e)) {
|
|
2119
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
2122
|
+
if (a = this.tokenizer.del(e, n, o)) {
|
|
2123
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2124
|
+
continue;
|
|
2125
|
+
}
|
|
2126
|
+
if (a = this.tokenizer.autolink(e)) {
|
|
2127
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2128
|
+
continue;
|
|
2129
|
+
}
|
|
2130
|
+
if (!this.state.inLink && (a = this.tokenizer.url(e))) {
|
|
2131
|
+
e = e.substring(a.raw.length), t.push(a);
|
|
2132
|
+
continue;
|
|
2133
|
+
}
|
|
2134
|
+
let c = e;
|
|
2135
|
+
if (this.options.extensions?.startInline) {
|
|
2136
|
+
let p = 1 / 0, k = e.slice(1), h;
|
|
2137
|
+
this.options.extensions.startInline.forEach((R) => {
|
|
2138
|
+
h = R.call({ lexer: this }, k), typeof h == "number" && h >= 0 && (p = Math.min(p, h));
|
|
2139
|
+
}), p < 1 / 0 && p >= 0 && (c = e.substring(0, p + 1));
|
|
2140
|
+
}
|
|
2141
|
+
if (a = this.tokenizer.inlineText(c)) {
|
|
2142
|
+
e = e.substring(a.raw.length), a.raw.slice(-1) !== "_" && (o = a.raw.slice(-1)), i = true;
|
|
2143
|
+
let p = t.at(-1);
|
|
2144
|
+
p?.type === "text" ? (p.raw += a.raw, p.text += a.text) : t.push(a);
|
|
2145
|
+
continue;
|
|
2146
|
+
}
|
|
2147
|
+
if (e) {
|
|
2148
|
+
this.infiniteLoopError(e.charCodeAt(0));
|
|
2149
|
+
break;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return t;
|
|
2153
|
+
}
|
|
2154
|
+
infiniteLoopError(e) {
|
|
2155
|
+
let t = "Infinite loop on byte: " + e;
|
|
2156
|
+
if (this.options.silent) console.error(t);
|
|
2157
|
+
else throw new Error(t);
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
var y = class {
|
|
2161
|
+
options;
|
|
2162
|
+
parser;
|
|
2163
|
+
constructor(e) {
|
|
2164
|
+
this.options = e || T;
|
|
2165
|
+
}
|
|
2166
|
+
space(e) {
|
|
2167
|
+
return "";
|
|
2168
|
+
}
|
|
2169
|
+
code({ text: e, lang: t, escaped: n }) {
|
|
2170
|
+
let s = (t || "").match(m.notSpaceStart)?.[0], r = e.replace(m.endingNewline, "") + `
|
|
2171
|
+
`;
|
|
2172
|
+
return s ? '<pre><code class="language-' + O(s) + '">' + (n ? r : O(r, true)) + `</code></pre>
|
|
2173
|
+
` : "<pre><code>" + (n ? r : O(r, true)) + `</code></pre>
|
|
2174
|
+
`;
|
|
2175
|
+
}
|
|
2176
|
+
blockquote({ tokens: e }) {
|
|
2177
|
+
return `<blockquote>
|
|
2178
|
+
${this.parser.parse(e)}</blockquote>
|
|
2179
|
+
`;
|
|
2180
|
+
}
|
|
2181
|
+
html({ text: e }) {
|
|
2182
|
+
return e;
|
|
2183
|
+
}
|
|
2184
|
+
def(e) {
|
|
2185
|
+
return "";
|
|
2186
|
+
}
|
|
2187
|
+
heading({ tokens: e, depth: t }) {
|
|
2188
|
+
return `<h${t}>${this.parser.parseInline(e)}</h${t}>
|
|
2189
|
+
`;
|
|
2190
|
+
}
|
|
2191
|
+
hr(e) {
|
|
2192
|
+
return `<hr>
|
|
2193
|
+
`;
|
|
2194
|
+
}
|
|
2195
|
+
list(e) {
|
|
2196
|
+
let t = e.ordered, n = e.start, s = "";
|
|
2197
|
+
for (let o = 0; o < e.items.length; o++) {
|
|
2198
|
+
let u = e.items[o];
|
|
2199
|
+
s += this.listitem(u);
|
|
2200
|
+
}
|
|
2201
|
+
let r = t ? "ol" : "ul", i = t && n !== 1 ? ' start="' + n + '"' : "";
|
|
2202
|
+
return "<" + r + i + `>
|
|
2203
|
+
` + s + "</" + r + `>
|
|
2204
|
+
`;
|
|
2205
|
+
}
|
|
2206
|
+
listitem(e) {
|
|
2207
|
+
return `<li>${this.parser.parse(e.tokens)}</li>
|
|
2208
|
+
`;
|
|
2209
|
+
}
|
|
2210
|
+
checkbox({ checked: e }) {
|
|
2211
|
+
return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"> ';
|
|
2212
|
+
}
|
|
2213
|
+
paragraph({ tokens: e }) {
|
|
2214
|
+
return `<p>${this.parser.parseInline(e)}</p>
|
|
2215
|
+
`;
|
|
2216
|
+
}
|
|
2217
|
+
table(e) {
|
|
2218
|
+
let t = "", n = "";
|
|
2219
|
+
for (let r = 0; r < e.header.length; r++) n += this.tablecell(e.header[r]);
|
|
2220
|
+
t += this.tablerow({ text: n });
|
|
2221
|
+
let s = "";
|
|
2222
|
+
for (let r = 0; r < e.rows.length; r++) {
|
|
2223
|
+
let i = e.rows[r];
|
|
2224
|
+
n = "";
|
|
2225
|
+
for (let o = 0; o < i.length; o++) n += this.tablecell(i[o]);
|
|
2226
|
+
s += this.tablerow({ text: n });
|
|
2227
|
+
}
|
|
2228
|
+
return s && (s = `<tbody>${s}</tbody>`), `<table>
|
|
2229
|
+
<thead>
|
|
2230
|
+
` + t + `</thead>
|
|
2231
|
+
` + s + `</table>
|
|
2232
|
+
`;
|
|
2233
|
+
}
|
|
2234
|
+
tablerow({ text: e }) {
|
|
2235
|
+
return `<tr>
|
|
2236
|
+
${e}</tr>
|
|
2237
|
+
`;
|
|
2238
|
+
}
|
|
2239
|
+
tablecell(e) {
|
|
2240
|
+
let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
|
|
2241
|
+
return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
|
|
2242
|
+
`;
|
|
2243
|
+
}
|
|
2244
|
+
strong({ tokens: e }) {
|
|
2245
|
+
return `<strong>${this.parser.parseInline(e)}</strong>`;
|
|
2246
|
+
}
|
|
2247
|
+
em({ tokens: e }) {
|
|
2248
|
+
return `<em>${this.parser.parseInline(e)}</em>`;
|
|
2249
|
+
}
|
|
2250
|
+
codespan({ text: e }) {
|
|
2251
|
+
return `<code>${O(e, true)}</code>`;
|
|
2252
|
+
}
|
|
2253
|
+
br(e) {
|
|
2254
|
+
return "<br>";
|
|
2255
|
+
}
|
|
2256
|
+
del({ tokens: e }) {
|
|
2257
|
+
return `<del>${this.parser.parseInline(e)}</del>`;
|
|
2258
|
+
}
|
|
2259
|
+
link({ href: e, title: t, tokens: n }) {
|
|
2260
|
+
let s = this.parser.parseInline(n), r = V(e);
|
|
2261
|
+
if (r === null) return s;
|
|
2262
|
+
e = r;
|
|
2263
|
+
let i = '<a href="' + e + '"';
|
|
2264
|
+
return t && (i += ' title="' + O(t) + '"'), i += ">" + s + "</a>", i;
|
|
2265
|
+
}
|
|
2266
|
+
image({ href: e, title: t, text: n, tokens: s }) {
|
|
2267
|
+
s && (n = this.parser.parseInline(s, this.parser.textRenderer));
|
|
2268
|
+
let r = V(e);
|
|
2269
|
+
if (r === null) return O(n);
|
|
2270
|
+
e = r;
|
|
2271
|
+
let i = `<img src="${e}" alt="${O(n)}"`;
|
|
2272
|
+
return t && (i += ` title="${O(t)}"`), i += ">", i;
|
|
2273
|
+
}
|
|
2274
|
+
text(e) {
|
|
2275
|
+
return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : O(e.text);
|
|
2276
|
+
}
|
|
2277
|
+
};
|
|
2278
|
+
var L = class {
|
|
2279
|
+
strong({ text: e }) {
|
|
2280
|
+
return e;
|
|
2281
|
+
}
|
|
2282
|
+
em({ text: e }) {
|
|
2283
|
+
return e;
|
|
2284
|
+
}
|
|
2285
|
+
codespan({ text: e }) {
|
|
2286
|
+
return e;
|
|
2287
|
+
}
|
|
2288
|
+
del({ text: e }) {
|
|
2289
|
+
return e;
|
|
2290
|
+
}
|
|
2291
|
+
html({ text: e }) {
|
|
2292
|
+
return e;
|
|
2293
|
+
}
|
|
2294
|
+
text({ text: e }) {
|
|
2295
|
+
return e;
|
|
2296
|
+
}
|
|
2297
|
+
link({ text: e }) {
|
|
2298
|
+
return "" + e;
|
|
2299
|
+
}
|
|
2300
|
+
image({ text: e }) {
|
|
2301
|
+
return "" + e;
|
|
2302
|
+
}
|
|
2303
|
+
br() {
|
|
2304
|
+
return "";
|
|
2305
|
+
}
|
|
2306
|
+
checkbox({ raw: e }) {
|
|
2307
|
+
return e;
|
|
2308
|
+
}
|
|
2309
|
+
};
|
|
2310
|
+
var b = class l2 {
|
|
2311
|
+
options;
|
|
2312
|
+
renderer;
|
|
2313
|
+
textRenderer;
|
|
2314
|
+
constructor(e) {
|
|
2315
|
+
this.options = e || T, this.options.renderer = this.options.renderer || new y(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new L();
|
|
2316
|
+
}
|
|
2317
|
+
static parse(e, t) {
|
|
2318
|
+
return new l2(t).parse(e);
|
|
2319
|
+
}
|
|
2320
|
+
static parseInline(e, t) {
|
|
2321
|
+
return new l2(t).parseInline(e);
|
|
2322
|
+
}
|
|
2323
|
+
parse(e) {
|
|
2324
|
+
this.renderer.parser = this;
|
|
2325
|
+
let t = "";
|
|
2326
|
+
for (let n = 0; n < e.length; n++) {
|
|
2327
|
+
let s = e[n];
|
|
2328
|
+
if (this.options.extensions?.renderers?.[s.type]) {
|
|
2329
|
+
let i = s, o = this.options.extensions.renderers[i.type].call({ parser: this }, i);
|
|
2330
|
+
if (o !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(i.type)) {
|
|
2331
|
+
t += o || "";
|
|
2332
|
+
continue;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
let r = s;
|
|
2336
|
+
switch (r.type) {
|
|
2337
|
+
case "space": {
|
|
2338
|
+
t += this.renderer.space(r);
|
|
2339
|
+
break;
|
|
2340
|
+
}
|
|
2341
|
+
case "hr": {
|
|
2342
|
+
t += this.renderer.hr(r);
|
|
2343
|
+
break;
|
|
2344
|
+
}
|
|
2345
|
+
case "heading": {
|
|
2346
|
+
t += this.renderer.heading(r);
|
|
2347
|
+
break;
|
|
2348
|
+
}
|
|
2349
|
+
case "code": {
|
|
2350
|
+
t += this.renderer.code(r);
|
|
2351
|
+
break;
|
|
2352
|
+
}
|
|
2353
|
+
case "table": {
|
|
2354
|
+
t += this.renderer.table(r);
|
|
2355
|
+
break;
|
|
2356
|
+
}
|
|
2357
|
+
case "blockquote": {
|
|
2358
|
+
t += this.renderer.blockquote(r);
|
|
2359
|
+
break;
|
|
2360
|
+
}
|
|
2361
|
+
case "list": {
|
|
2362
|
+
t += this.renderer.list(r);
|
|
2363
|
+
break;
|
|
2364
|
+
}
|
|
2365
|
+
case "checkbox": {
|
|
2366
|
+
t += this.renderer.checkbox(r);
|
|
2367
|
+
break;
|
|
2368
|
+
}
|
|
2369
|
+
case "html": {
|
|
2370
|
+
t += this.renderer.html(r);
|
|
2371
|
+
break;
|
|
2372
|
+
}
|
|
2373
|
+
case "def": {
|
|
2374
|
+
t += this.renderer.def(r);
|
|
2375
|
+
break;
|
|
2376
|
+
}
|
|
2377
|
+
case "paragraph": {
|
|
2378
|
+
t += this.renderer.paragraph(r);
|
|
2379
|
+
break;
|
|
2380
|
+
}
|
|
2381
|
+
case "text": {
|
|
2382
|
+
t += this.renderer.text(r);
|
|
2383
|
+
break;
|
|
2384
|
+
}
|
|
2385
|
+
default: {
|
|
2386
|
+
let i = 'Token with "' + r.type + '" type was not found.';
|
|
2387
|
+
if (this.options.silent) return console.error(i), "";
|
|
2388
|
+
throw new Error(i);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
return t;
|
|
2393
|
+
}
|
|
2394
|
+
parseInline(e, t = this.renderer) {
|
|
2395
|
+
this.renderer.parser = this;
|
|
2396
|
+
let n = "";
|
|
2397
|
+
for (let s = 0; s < e.length; s++) {
|
|
2398
|
+
let r = e[s];
|
|
2399
|
+
if (this.options.extensions?.renderers?.[r.type]) {
|
|
2400
|
+
let o = this.options.extensions.renderers[r.type].call({ parser: this }, r);
|
|
2401
|
+
if (o !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(r.type)) {
|
|
2402
|
+
n += o || "";
|
|
2403
|
+
continue;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
let i = r;
|
|
2407
|
+
switch (i.type) {
|
|
2408
|
+
case "escape": {
|
|
2409
|
+
n += t.text(i);
|
|
2410
|
+
break;
|
|
2411
|
+
}
|
|
2412
|
+
case "html": {
|
|
2413
|
+
n += t.html(i);
|
|
2414
|
+
break;
|
|
2415
|
+
}
|
|
2416
|
+
case "link": {
|
|
2417
|
+
n += t.link(i);
|
|
2418
|
+
break;
|
|
2419
|
+
}
|
|
2420
|
+
case "image": {
|
|
2421
|
+
n += t.image(i);
|
|
2422
|
+
break;
|
|
2423
|
+
}
|
|
2424
|
+
case "checkbox": {
|
|
2425
|
+
n += t.checkbox(i);
|
|
2426
|
+
break;
|
|
2427
|
+
}
|
|
2428
|
+
case "strong": {
|
|
2429
|
+
n += t.strong(i);
|
|
2430
|
+
break;
|
|
2431
|
+
}
|
|
2432
|
+
case "em": {
|
|
2433
|
+
n += t.em(i);
|
|
2434
|
+
break;
|
|
2435
|
+
}
|
|
2436
|
+
case "codespan": {
|
|
2437
|
+
n += t.codespan(i);
|
|
2438
|
+
break;
|
|
2439
|
+
}
|
|
2440
|
+
case "br": {
|
|
2441
|
+
n += t.br(i);
|
|
2442
|
+
break;
|
|
2443
|
+
}
|
|
2444
|
+
case "del": {
|
|
2445
|
+
n += t.del(i);
|
|
2446
|
+
break;
|
|
2447
|
+
}
|
|
2448
|
+
case "text": {
|
|
2449
|
+
n += t.text(i);
|
|
2450
|
+
break;
|
|
2451
|
+
}
|
|
2452
|
+
default: {
|
|
2453
|
+
let o = 'Token with "' + i.type + '" type was not found.';
|
|
2454
|
+
if (this.options.silent) return console.error(o), "";
|
|
2455
|
+
throw new Error(o);
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
return n;
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2462
|
+
var P = class {
|
|
2463
|
+
options;
|
|
2464
|
+
block;
|
|
2465
|
+
constructor(e) {
|
|
2466
|
+
this.options = e || T;
|
|
2467
|
+
}
|
|
2468
|
+
static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
|
|
2469
|
+
static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
|
|
2470
|
+
preprocess(e) {
|
|
2471
|
+
return e;
|
|
2472
|
+
}
|
|
2473
|
+
postprocess(e) {
|
|
2474
|
+
return e;
|
|
2475
|
+
}
|
|
2476
|
+
processAllTokens(e) {
|
|
2477
|
+
return e;
|
|
2478
|
+
}
|
|
2479
|
+
emStrongMask(e) {
|
|
2480
|
+
return e;
|
|
2481
|
+
}
|
|
2482
|
+
provideLexer(e = this.block) {
|
|
2483
|
+
return e ? x.lex : x.lexInline;
|
|
2484
|
+
}
|
|
2485
|
+
provideParser(e = this.block) {
|
|
2486
|
+
return e ? b.parse : b.parseInline;
|
|
2487
|
+
}
|
|
2488
|
+
};
|
|
2489
|
+
var q = class {
|
|
2490
|
+
defaults = M();
|
|
2491
|
+
options = this.setOptions;
|
|
2492
|
+
parse = this.parseMarkdown(true);
|
|
2493
|
+
parseInline = this.parseMarkdown(false);
|
|
2494
|
+
Parser = b;
|
|
2495
|
+
Renderer = y;
|
|
2496
|
+
TextRenderer = L;
|
|
2497
|
+
Lexer = x;
|
|
2498
|
+
Tokenizer = w;
|
|
2499
|
+
Hooks = P;
|
|
2500
|
+
constructor(...e) {
|
|
2501
|
+
this.use(...e);
|
|
2502
|
+
}
|
|
2503
|
+
walkTokens(e, t) {
|
|
2504
|
+
let n = [];
|
|
2505
|
+
for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) {
|
|
2506
|
+
case "table": {
|
|
2507
|
+
let r = s;
|
|
2508
|
+
for (let i of r.header) n = n.concat(this.walkTokens(i.tokens, t));
|
|
2509
|
+
for (let i of r.rows) for (let o of i) n = n.concat(this.walkTokens(o.tokens, t));
|
|
2510
|
+
break;
|
|
2511
|
+
}
|
|
2512
|
+
case "list": {
|
|
2513
|
+
let r = s;
|
|
2514
|
+
n = n.concat(this.walkTokens(r.items, t));
|
|
2515
|
+
break;
|
|
2516
|
+
}
|
|
2517
|
+
default: {
|
|
2518
|
+
let r = s;
|
|
2519
|
+
this.defaults.extensions?.childTokens?.[r.type] ? this.defaults.extensions.childTokens[r.type].forEach((i) => {
|
|
2520
|
+
let o = r[i].flat(1 / 0);
|
|
2521
|
+
n = n.concat(this.walkTokens(o, t));
|
|
2522
|
+
}) : r.tokens && (n = n.concat(this.walkTokens(r.tokens, t)));
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
return n;
|
|
2526
|
+
}
|
|
2527
|
+
use(...e) {
|
|
2528
|
+
let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
|
|
2529
|
+
return e.forEach((n) => {
|
|
2530
|
+
let s = { ...n };
|
|
2531
|
+
if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((r) => {
|
|
2532
|
+
if (!r.name) throw new Error("extension name required");
|
|
2533
|
+
if ("renderer" in r) {
|
|
2534
|
+
let i = t.renderers[r.name];
|
|
2535
|
+
i ? t.renderers[r.name] = function(...o) {
|
|
2536
|
+
let u = r.renderer.apply(this, o);
|
|
2537
|
+
return u === false && (u = i.apply(this, o)), u;
|
|
2538
|
+
} : t.renderers[r.name] = r.renderer;
|
|
2539
|
+
}
|
|
2540
|
+
if ("tokenizer" in r) {
|
|
2541
|
+
if (!r.level || r.level !== "block" && r.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
|
|
2542
|
+
let i = t[r.level];
|
|
2543
|
+
i ? i.unshift(r.tokenizer) : t[r.level] = [r.tokenizer], r.start && (r.level === "block" ? t.startBlock ? t.startBlock.push(r.start) : t.startBlock = [r.start] : r.level === "inline" && (t.startInline ? t.startInline.push(r.start) : t.startInline = [r.start]));
|
|
2544
|
+
}
|
|
2545
|
+
"childTokens" in r && r.childTokens && (t.childTokens[r.name] = r.childTokens);
|
|
2546
|
+
}), s.extensions = t), n.renderer) {
|
|
2547
|
+
let r = this.defaults.renderer || new y(this.defaults);
|
|
2548
|
+
for (let i in n.renderer) {
|
|
2549
|
+
if (!(i in r)) throw new Error(`renderer '${i}' does not exist`);
|
|
2550
|
+
if (["options", "parser"].includes(i)) continue;
|
|
2551
|
+
let o = i, u = n.renderer[o], a = r[o];
|
|
2552
|
+
r[o] = (...c) => {
|
|
2553
|
+
let p = u.apply(r, c);
|
|
2554
|
+
return p === false && (p = a.apply(r, c)), p || "";
|
|
2555
|
+
};
|
|
2556
|
+
}
|
|
2557
|
+
s.renderer = r;
|
|
2558
|
+
}
|
|
2559
|
+
if (n.tokenizer) {
|
|
2560
|
+
let r = this.defaults.tokenizer || new w(this.defaults);
|
|
2561
|
+
for (let i in n.tokenizer) {
|
|
2562
|
+
if (!(i in r)) throw new Error(`tokenizer '${i}' does not exist`);
|
|
2563
|
+
if (["options", "rules", "lexer"].includes(i)) continue;
|
|
2564
|
+
let o = i, u = n.tokenizer[o], a = r[o];
|
|
2565
|
+
r[o] = (...c) => {
|
|
2566
|
+
let p = u.apply(r, c);
|
|
2567
|
+
return p === false && (p = a.apply(r, c)), p;
|
|
2568
|
+
};
|
|
2569
|
+
}
|
|
2570
|
+
s.tokenizer = r;
|
|
2571
|
+
}
|
|
2572
|
+
if (n.hooks) {
|
|
2573
|
+
let r = this.defaults.hooks || new P();
|
|
2574
|
+
for (let i in n.hooks) {
|
|
2575
|
+
if (!(i in r)) throw new Error(`hook '${i}' does not exist`);
|
|
2576
|
+
if (["options", "block"].includes(i)) continue;
|
|
2577
|
+
let o = i, u = n.hooks[o], a = r[o];
|
|
2578
|
+
P.passThroughHooks.has(i) ? r[o] = (c) => {
|
|
2579
|
+
if (this.defaults.async && P.passThroughHooksRespectAsync.has(i)) return (async () => {
|
|
2580
|
+
let k = await u.call(r, c);
|
|
2581
|
+
return a.call(r, k);
|
|
2582
|
+
})();
|
|
2583
|
+
let p = u.call(r, c);
|
|
2584
|
+
return a.call(r, p);
|
|
2585
|
+
} : r[o] = (...c) => {
|
|
2586
|
+
if (this.defaults.async) return (async () => {
|
|
2587
|
+
let k = await u.apply(r, c);
|
|
2588
|
+
return k === false && (k = await a.apply(r, c)), k;
|
|
2589
|
+
})();
|
|
2590
|
+
let p = u.apply(r, c);
|
|
2591
|
+
return p === false && (p = a.apply(r, c)), p;
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
s.hooks = r;
|
|
2595
|
+
}
|
|
2596
|
+
if (n.walkTokens) {
|
|
2597
|
+
let r = this.defaults.walkTokens, i = n.walkTokens;
|
|
2598
|
+
s.walkTokens = function(o) {
|
|
2599
|
+
let u = [];
|
|
2600
|
+
return u.push(i.call(this, o)), r && (u = u.concat(r.call(this, o))), u;
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
this.defaults = { ...this.defaults, ...s };
|
|
2604
|
+
}), this;
|
|
2605
|
+
}
|
|
2606
|
+
setOptions(e) {
|
|
2607
|
+
return this.defaults = { ...this.defaults, ...e }, this;
|
|
2608
|
+
}
|
|
2609
|
+
lexer(e, t) {
|
|
2610
|
+
return x.lex(e, t ?? this.defaults);
|
|
2611
|
+
}
|
|
2612
|
+
parser(e, t) {
|
|
2613
|
+
return b.parse(e, t ?? this.defaults);
|
|
2614
|
+
}
|
|
2615
|
+
parseMarkdown(e) {
|
|
2616
|
+
return (n, s) => {
|
|
2617
|
+
let r = { ...s }, i = { ...this.defaults, ...r }, o = this.onError(!!i.silent, !!i.async);
|
|
2618
|
+
if (this.defaults.async === true && r.async === false) return o(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."));
|
|
2619
|
+
if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null"));
|
|
2620
|
+
if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
|
|
2621
|
+
if (i.hooks && (i.hooks.options = i, i.hooks.block = e), i.async) return (async () => {
|
|
2622
|
+
let u = i.hooks ? await i.hooks.preprocess(n) : n, c = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(u, i), p = i.hooks ? await i.hooks.processAllTokens(c) : c;
|
|
2623
|
+
i.walkTokens && await Promise.all(this.walkTokens(p, i.walkTokens));
|
|
2624
|
+
let h = await (i.hooks ? await i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(p, i);
|
|
2625
|
+
return i.hooks ? await i.hooks.postprocess(h) : h;
|
|
2626
|
+
})().catch(o);
|
|
2627
|
+
try {
|
|
2628
|
+
i.hooks && (n = i.hooks.preprocess(n));
|
|
2629
|
+
let a = (i.hooks ? i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, i);
|
|
2630
|
+
i.hooks && (a = i.hooks.processAllTokens(a)), i.walkTokens && this.walkTokens(a, i.walkTokens);
|
|
2631
|
+
let p = (i.hooks ? i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, i);
|
|
2632
|
+
return i.hooks && (p = i.hooks.postprocess(p)), p;
|
|
2633
|
+
} catch (u) {
|
|
2634
|
+
return o(u);
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
onError(e, t) {
|
|
2639
|
+
return (n) => {
|
|
2640
|
+
if (n.message += `
|
|
2641
|
+
Please report this to https://github.com/markedjs/marked.`, e) {
|
|
2642
|
+
let s = "<p>An error occurred:</p><pre>" + O(n.message + "", true) + "</pre>";
|
|
2643
|
+
return t ? Promise.resolve(s) : s;
|
|
2644
|
+
}
|
|
2645
|
+
if (t) return Promise.reject(n);
|
|
2646
|
+
throw n;
|
|
2647
|
+
};
|
|
2648
|
+
}
|
|
2649
|
+
};
|
|
2650
|
+
var z = new q();
|
|
2651
|
+
function g(l3, e) {
|
|
2652
|
+
return z.parse(l3, e);
|
|
2653
|
+
}
|
|
2654
|
+
g.options = g.setOptions = function(l3) {
|
|
2655
|
+
return z.setOptions(l3), g.defaults = z.defaults, N(g.defaults), g;
|
|
2656
|
+
};
|
|
2657
|
+
g.getDefaults = M;
|
|
2658
|
+
g.defaults = T;
|
|
2659
|
+
g.use = function(...l3) {
|
|
2660
|
+
return z.use(...l3), g.defaults = z.defaults, N(g.defaults), g;
|
|
2661
|
+
};
|
|
2662
|
+
g.walkTokens = function(l3, e) {
|
|
2663
|
+
return z.walkTokens(l3, e);
|
|
2664
|
+
};
|
|
2665
|
+
g.parseInline = z.parseInline;
|
|
2666
|
+
g.Parser = b;
|
|
2667
|
+
g.parser = b.parse;
|
|
2668
|
+
g.Renderer = y;
|
|
2669
|
+
g.TextRenderer = L;
|
|
2670
|
+
g.Lexer = x;
|
|
2671
|
+
g.lexer = x.lex;
|
|
2672
|
+
g.Tokenizer = w;
|
|
2673
|
+
g.Hooks = P;
|
|
2674
|
+
g.parse = g;
|
|
2675
|
+
var Ft = g.options;
|
|
2676
|
+
var Ut = g.setOptions;
|
|
2677
|
+
var Kt = g.use;
|
|
2678
|
+
var Wt = g.walkTokens;
|
|
2679
|
+
var Xt = g.parseInline;
|
|
2680
|
+
var Vt = b.parse;
|
|
2681
|
+
var Yt = x.lex;
|
|
2682
|
+
|
|
2683
|
+
// src/ui/render_markdown.ts
|
|
2684
|
+
g.setOptions({ gfm: true, breaks: true });
|
|
2685
|
+
var ALLOWED_TAGS = [
|
|
2686
|
+
"a",
|
|
2687
|
+
"p",
|
|
2688
|
+
"br",
|
|
2689
|
+
"strong",
|
|
2690
|
+
"em",
|
|
2691
|
+
"b",
|
|
2692
|
+
"i",
|
|
2693
|
+
"u",
|
|
2694
|
+
"s",
|
|
2695
|
+
"del",
|
|
2696
|
+
"code",
|
|
2697
|
+
"pre",
|
|
2698
|
+
"ul",
|
|
2699
|
+
"ol",
|
|
2700
|
+
"li",
|
|
2701
|
+
"blockquote",
|
|
2702
|
+
"h1",
|
|
2703
|
+
"h2",
|
|
2704
|
+
"h3",
|
|
2705
|
+
"h4",
|
|
2706
|
+
"h5",
|
|
2707
|
+
"h6",
|
|
2708
|
+
"hr",
|
|
2709
|
+
"span",
|
|
2710
|
+
"table",
|
|
2711
|
+
"thead",
|
|
2712
|
+
"tbody",
|
|
2713
|
+
"tr",
|
|
2714
|
+
"th",
|
|
2715
|
+
"td",
|
|
2716
|
+
"img"
|
|
2717
|
+
];
|
|
2718
|
+
var ALLOWED_ATTR = ["href", "title", "class", "src", "alt", "width", "height"];
|
|
2719
|
+
function renderMarkdown(text2) {
|
|
2720
|
+
const rendered = g.parse(text2, { async: false });
|
|
2721
|
+
const clean = purify.sanitize(rendered, { ALLOWED_TAGS, ALLOWED_ATTR });
|
|
2722
|
+
const template = document.createElement("template");
|
|
2723
|
+
template.innerHTML = clean;
|
|
2724
|
+
for (const anchor of template.content.querySelectorAll("a[href]")) {
|
|
2725
|
+
anchor.setAttribute("target", "_blank");
|
|
2726
|
+
anchor.setAttribute("rel", "noopener noreferrer");
|
|
2727
|
+
}
|
|
2728
|
+
return template.innerHTML.trim();
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
// src/ui/reveal_words.ts
|
|
2732
|
+
function collectTextNodes(root, out) {
|
|
2733
|
+
for (const child of Array.from(root.childNodes)) {
|
|
2734
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
2735
|
+
out.push({ node: child, parent: root });
|
|
2736
|
+
} else {
|
|
2737
|
+
collectTextNodes(child, out);
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
function wrapWords(root) {
|
|
2742
|
+
const texts = [];
|
|
2743
|
+
collectTextNodes(root, texts);
|
|
2744
|
+
let index = 0;
|
|
2745
|
+
for (const { node, parent } of texts) {
|
|
2746
|
+
const fragment = document.createDocumentFragment();
|
|
2747
|
+
for (const part of node.data.split(/(\s+)/)) {
|
|
2748
|
+
if (part === "") {
|
|
2749
|
+
continue;
|
|
2750
|
+
}
|
|
2751
|
+
if (/\s/.test(part)) {
|
|
2752
|
+
fragment.appendChild(document.createTextNode(part));
|
|
2753
|
+
continue;
|
|
2754
|
+
}
|
|
2755
|
+
const span = document.createElement("span");
|
|
2756
|
+
span.className = "word";
|
|
2757
|
+
span.style.setProperty("--ag-ui-word-index", String(index));
|
|
2758
|
+
span.textContent = part;
|
|
2759
|
+
fragment.appendChild(span);
|
|
2760
|
+
index += 1;
|
|
2761
|
+
}
|
|
2762
|
+
parent.replaceChild(fragment, node);
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
// src/ui/skills_menu.ts
|
|
2767
|
+
var SkillsMenu = class {
|
|
2768
|
+
/** Chips row — append above the input. Hidden unless chips are enabled and present. */
|
|
2769
|
+
chips;
|
|
2770
|
+
/** The `/`-command dropdown — append in the input area. Hidden until opened. */
|
|
2771
|
+
palette;
|
|
2772
|
+
#onPick;
|
|
2773
|
+
#skills = [];
|
|
2774
|
+
#chipsEnabled = false;
|
|
2775
|
+
#slashEnabled = false;
|
|
2776
|
+
#filtered = [];
|
|
2777
|
+
#activeIndex = 0;
|
|
2778
|
+
constructor(onPick) {
|
|
2779
|
+
this.#onPick = onPick;
|
|
2780
|
+
this.chips = document.createElement("div");
|
|
2781
|
+
this.chips.className = "skill-chips";
|
|
2782
|
+
this.chips.hidden = true;
|
|
2783
|
+
this.palette = document.createElement("div");
|
|
2784
|
+
this.palette.className = "skill-palette";
|
|
2785
|
+
this.palette.setAttribute("role", "listbox");
|
|
2786
|
+
this.palette.hidden = true;
|
|
2787
|
+
}
|
|
2788
|
+
/** Replace the catalog (both surfaces re-derive from it). */
|
|
2789
|
+
setSkills(skills) {
|
|
2790
|
+
this.#skills = skills;
|
|
2791
|
+
this.#renderChips();
|
|
2792
|
+
}
|
|
2793
|
+
enableChips(enabled) {
|
|
2794
|
+
this.#chipsEnabled = enabled;
|
|
2795
|
+
this.#renderChips();
|
|
2796
|
+
}
|
|
2797
|
+
enableSlash(enabled) {
|
|
2798
|
+
this.#slashEnabled = enabled;
|
|
2799
|
+
}
|
|
2800
|
+
/** Whether the palette is currently open. */
|
|
2801
|
+
isOpen() {
|
|
2802
|
+
return !this.palette.hidden;
|
|
2803
|
+
}
|
|
2804
|
+
/**
|
|
2805
|
+
* React to an input value change: open + filter the palette when slash mode
|
|
2806
|
+
* is on and the value starts with `/`, otherwise close it.
|
|
2807
|
+
*/
|
|
2808
|
+
onInput(value) {
|
|
2809
|
+
if (this.#slashEnabled && value.startsWith("/")) {
|
|
2810
|
+
this.#open(value.slice(1));
|
|
2811
|
+
} else {
|
|
2812
|
+
this.close();
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
/**
|
|
2816
|
+
* Handle a keydown while the palette is open. Returns ``true`` when consumed
|
|
2817
|
+
* (the host should `preventDefault` and skip its own handling).
|
|
2818
|
+
*/
|
|
2819
|
+
onKeydown(event) {
|
|
2820
|
+
if (!this.isOpen()) {
|
|
2821
|
+
return false;
|
|
2822
|
+
}
|
|
2823
|
+
if (event.key === "ArrowDown") {
|
|
2824
|
+
this.#move(1);
|
|
2825
|
+
return true;
|
|
2826
|
+
}
|
|
2827
|
+
if (event.key === "ArrowUp") {
|
|
2828
|
+
this.#move(-1);
|
|
2829
|
+
return true;
|
|
2830
|
+
}
|
|
2831
|
+
if (event.key === "Escape") {
|
|
2832
|
+
this.close();
|
|
2833
|
+
return true;
|
|
2834
|
+
}
|
|
2835
|
+
if (event.key === "Enter") {
|
|
2836
|
+
this.#filtered.slice(this.#activeIndex, this.#activeIndex + 1).forEach((skill) => {
|
|
2837
|
+
this.#pick(skill);
|
|
2838
|
+
});
|
|
2839
|
+
return true;
|
|
2840
|
+
}
|
|
2841
|
+
return false;
|
|
2842
|
+
}
|
|
2843
|
+
/** Close the palette. */
|
|
2844
|
+
close() {
|
|
2845
|
+
this.palette.hidden = true;
|
|
2846
|
+
this.palette.replaceChildren();
|
|
2847
|
+
}
|
|
2848
|
+
#open(query) {
|
|
2849
|
+
const needle = query.trim().toLowerCase();
|
|
2850
|
+
const matches = this.#skills.filter(
|
|
2851
|
+
(skill) => skill.name.toLowerCase().includes(needle) || skill.title.toLowerCase().includes(needle)
|
|
2852
|
+
);
|
|
2853
|
+
if (matches.length === 0) {
|
|
2854
|
+
this.close();
|
|
2855
|
+
return;
|
|
2856
|
+
}
|
|
2857
|
+
this.#filtered = matches;
|
|
2858
|
+
this.#activeIndex = 0;
|
|
2859
|
+
this.#renderPalette();
|
|
2860
|
+
this.palette.hidden = false;
|
|
2861
|
+
}
|
|
2862
|
+
#move(delta) {
|
|
2863
|
+
const count = this.#filtered.length;
|
|
2864
|
+
this.#activeIndex = (this.#activeIndex + delta + count) % count;
|
|
2865
|
+
this.#renderPalette();
|
|
2866
|
+
}
|
|
2867
|
+
#pick(skill) {
|
|
2868
|
+
this.close();
|
|
2869
|
+
this.#onPick(skill);
|
|
2870
|
+
}
|
|
2871
|
+
#renderChips() {
|
|
2872
|
+
this.chips.replaceChildren();
|
|
2873
|
+
const chipSkills = this.#chipsEnabled ? this.#skills.filter((skill) => skill.chip === true) : [];
|
|
2874
|
+
this.chips.hidden = chipSkills.length === 0;
|
|
2875
|
+
for (const skill of chipSkills) {
|
|
2876
|
+
const button = document.createElement("button");
|
|
2877
|
+
button.type = "button";
|
|
2878
|
+
button.className = "skill-chip";
|
|
2879
|
+
button.textContent = skill.title;
|
|
2880
|
+
button.addEventListener("click", () => this.#pick(skill));
|
|
2881
|
+
this.chips.appendChild(button);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
#renderPalette() {
|
|
2885
|
+
this.palette.replaceChildren();
|
|
2886
|
+
this.#filtered.forEach((skill, index) => {
|
|
2887
|
+
const item = document.createElement("button");
|
|
2888
|
+
item.type = "button";
|
|
2889
|
+
item.className = "skill-item";
|
|
2890
|
+
item.setAttribute("role", "option");
|
|
2891
|
+
item.setAttribute("aria-selected", index === this.#activeIndex ? "true" : "false");
|
|
2892
|
+
const title = document.createElement("span");
|
|
2893
|
+
title.className = "skill-item-title";
|
|
2894
|
+
title.textContent = skill.title;
|
|
2895
|
+
item.appendChild(title);
|
|
2896
|
+
if (skill.description !== void 0) {
|
|
2897
|
+
const desc = document.createElement("span");
|
|
2898
|
+
desc.className = "skill-item-desc";
|
|
2899
|
+
desc.textContent = skill.description;
|
|
2900
|
+
item.appendChild(desc);
|
|
2901
|
+
}
|
|
2902
|
+
item.addEventListener("click", () => this.#pick(skill));
|
|
2903
|
+
this.palette.appendChild(item);
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
};
|
|
2907
|
+
|
|
2908
|
+
// src/ui/styles.ts
|
|
2909
|
+
var STYLES = `
|
|
2910
|
+
:host {
|
|
2911
|
+
/* Colors */
|
|
2912
|
+
--ag-ui-bg: #ffffff;
|
|
2913
|
+
--ag-ui-fg: #1a1a2e;
|
|
2914
|
+
--ag-ui-accent: #4f46e5;
|
|
2915
|
+
--ag-ui-user-bg: #4f46e5;
|
|
2916
|
+
--ag-ui-user-fg: #ffffff;
|
|
2917
|
+
--ag-ui-assistant-bg: #f1f1f6;
|
|
2918
|
+
--ag-ui-input-bg: var(--ag-ui-bg);
|
|
2919
|
+
--ag-ui-tool-bg: var(--ag-ui-assistant-bg);
|
|
2920
|
+
--ag-ui-tool-fg: var(--ag-ui-accent);
|
|
2921
|
+
--ag-ui-header-bg: var(--ag-ui-accent);
|
|
2922
|
+
--ag-ui-header-fg: #ffffff;
|
|
2923
|
+
--ag-ui-border: #e2e2ec;
|
|
2924
|
+
--ag-ui-radius: 12px;
|
|
2925
|
+
|
|
2926
|
+
/* Status accents for tool-call cards. */
|
|
2927
|
+
--ag-ui-success: #15803d;
|
|
2928
|
+
--ag-ui-danger: #b91c1c;
|
|
400
2929
|
--ag-ui-muted: #6b7280;
|
|
401
2930
|
|
|
402
2931
|
/* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */
|
|
403
2932
|
--ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);
|
|
404
2933
|
--ag-ui-font: inherit;
|
|
405
2934
|
--ag-ui-font-size: 14px;
|
|
2935
|
+
--ag-ui-code-font: ui-monospace, "SF Mono", Menlo, monospace;
|
|
2936
|
+
|
|
2937
|
+
/* Spacing \u2014 the density preset overrides these. */
|
|
2938
|
+
--ag-ui-space: 10px;
|
|
2939
|
+
--ag-ui-pad: 16px;
|
|
2940
|
+
--ag-ui-msg-pad: 8px 12px;
|
|
2941
|
+
--ag-ui-msg-radius: 14px;
|
|
406
2942
|
|
|
407
2943
|
/* Layout \u2014 override from outside to dock the widget anywhere.
|
|
408
2944
|
Set --ag-ui-position: static (and place this element in your own
|
|
@@ -428,6 +2964,91 @@ var STYLES = `
|
|
|
428
2964
|
color: var(--ag-ui-fg);
|
|
429
2965
|
}
|
|
430
2966
|
|
|
2967
|
+
/* \u2500\u2500 Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2968
|
+
Themes only re-set the colour variables; layout/spacing are unaffected.
|
|
2969
|
+
theme="auto" follows the OS via prefers-color-scheme. */
|
|
2970
|
+
:host([theme="dark"]) {
|
|
2971
|
+
--ag-ui-bg: #15151f;
|
|
2972
|
+
--ag-ui-fg: #e8e8f2;
|
|
2973
|
+
--ag-ui-assistant-bg: #25253a;
|
|
2974
|
+
--ag-ui-header-bg: #1f1f30;
|
|
2975
|
+
--ag-ui-header-fg: #e8e8f2;
|
|
2976
|
+
--ag-ui-border: #33334a;
|
|
2977
|
+
--ag-ui-muted: #9aa0b4;
|
|
2978
|
+
--ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
@media (prefers-color-scheme: dark) {
|
|
2982
|
+
:host([theme="auto"]) {
|
|
2983
|
+
--ag-ui-bg: #15151f;
|
|
2984
|
+
--ag-ui-fg: #e8e8f2;
|
|
2985
|
+
--ag-ui-assistant-bg: #25253a;
|
|
2986
|
+
--ag-ui-header-bg: #1f1f30;
|
|
2987
|
+
--ag-ui-header-fg: #e8e8f2;
|
|
2988
|
+
--ag-ui-border: #33334a;
|
|
2989
|
+
--ag-ui-muted: #9aa0b4;
|
|
2990
|
+
--ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
/* A terminal-flavoured "code" theme: dark, monospace, green accent. */
|
|
2995
|
+
:host([theme="code"]) {
|
|
2996
|
+
--ag-ui-bg: #0d1117;
|
|
2997
|
+
--ag-ui-fg: #c9d1d9;
|
|
2998
|
+
--ag-ui-accent: #3fb950;
|
|
2999
|
+
--ag-ui-user-bg: #238636;
|
|
3000
|
+
--ag-ui-assistant-bg: #161b22;
|
|
3001
|
+
--ag-ui-header-bg: #010409;
|
|
3002
|
+
--ag-ui-header-fg: #c9d1d9;
|
|
3003
|
+
--ag-ui-border: #30363d;
|
|
3004
|
+
--ag-ui-muted: #8b949e;
|
|
3005
|
+
--ag-ui-font: var(--ag-ui-code-font);
|
|
3006
|
+
--ag-ui-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
/* \u2500\u2500 Density \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3010
|
+
:host([density="compact"]) {
|
|
3011
|
+
--ag-ui-font-size: 13px;
|
|
3012
|
+
--ag-ui-space: 6px;
|
|
3013
|
+
--ag-ui-pad: 10px;
|
|
3014
|
+
--ag-ui-msg-pad: 5px 9px;
|
|
3015
|
+
--ag-ui-msg-radius: 10px;
|
|
3016
|
+
}
|
|
3017
|
+
|
|
3018
|
+
/* \u2500\u2500 Placement presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3019
|
+
:host([placement="bottom-left"]) {
|
|
3020
|
+
--ag-ui-inset: auto auto 24px 24px;
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
:host([placement="side"]) {
|
|
3024
|
+
--ag-ui-inset: 0 0 0 auto;
|
|
3025
|
+
--ag-ui-width: 420px;
|
|
3026
|
+
--ag-ui-height: 100vh;
|
|
3027
|
+
--ag-ui-max-height: 100vh;
|
|
3028
|
+
--ag-ui-radius: 0;
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
:host([placement="full"]) {
|
|
3032
|
+
--ag-ui-inset: 0;
|
|
3033
|
+
--ag-ui-width: 100vw;
|
|
3034
|
+
--ag-ui-height: 100vh;
|
|
3035
|
+
--ag-ui-max-width: 100vw;
|
|
3036
|
+
--ag-ui-max-height: 100vh;
|
|
3037
|
+
--ag-ui-radius: 0;
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
/* Embedded: drop the floating chrome and the high z-index stacking context so
|
|
3041
|
+
the widget lives in the host's own layout (fixes overlay/z-index clashes). */
|
|
3042
|
+
:host([placement="embedded"]) {
|
|
3043
|
+
--ag-ui-position: static;
|
|
3044
|
+
--ag-ui-width: 100%;
|
|
3045
|
+
--ag-ui-height: 100%;
|
|
3046
|
+
--ag-ui-max-width: 100%;
|
|
3047
|
+
--ag-ui-max-height: 100%;
|
|
3048
|
+
--ag-ui-shadow: none;
|
|
3049
|
+
--ag-ui-z-index: auto;
|
|
3050
|
+
}
|
|
3051
|
+
|
|
431
3052
|
.chat {
|
|
432
3053
|
position: relative;
|
|
433
3054
|
display: flex;
|
|
@@ -442,31 +3063,114 @@ var STYLES = `
|
|
|
442
3063
|
}
|
|
443
3064
|
|
|
444
3065
|
.header {
|
|
445
|
-
|
|
446
|
-
|
|
3066
|
+
display: flex;
|
|
3067
|
+
align-items: center;
|
|
3068
|
+
justify-content: space-between;
|
|
3069
|
+
gap: 8px;
|
|
3070
|
+
padding: 10px 14px;
|
|
447
3071
|
border-bottom: 1px solid var(--ag-ui-border);
|
|
448
3072
|
background: var(--ag-ui-header-bg);
|
|
449
3073
|
color: var(--ag-ui-header-fg);
|
|
450
3074
|
}
|
|
451
3075
|
|
|
3076
|
+
.header-title {
|
|
3077
|
+
font-weight: 600;
|
|
3078
|
+
overflow: hidden;
|
|
3079
|
+
text-overflow: ellipsis;
|
|
3080
|
+
white-space: nowrap;
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
.header-controls {
|
|
3084
|
+
display: flex;
|
|
3085
|
+
gap: 2px;
|
|
3086
|
+
flex: none;
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3089
|
+
.header-btn {
|
|
3090
|
+
border: none;
|
|
3091
|
+
background: transparent;
|
|
3092
|
+
color: inherit;
|
|
3093
|
+
font: inherit;
|
|
3094
|
+
line-height: 1;
|
|
3095
|
+
padding: 4px 7px;
|
|
3096
|
+
border-radius: 6px;
|
|
3097
|
+
cursor: pointer;
|
|
3098
|
+
opacity: 0.85;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
.header-btn:hover {
|
|
3102
|
+
opacity: 1;
|
|
3103
|
+
background: rgba(255, 255, 255, 0.18);
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
/* Collapsed: keep just the header bar \u2014 hide the whole body, and let the host
|
|
3107
|
+
shrink to the header. (A host can also fully hide the element itself.) */
|
|
3108
|
+
:host([collapsed]) {
|
|
3109
|
+
height: auto;
|
|
3110
|
+
max-height: none;
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3113
|
+
:host([collapsed]) .messages,
|
|
3114
|
+
:host([collapsed]) .input-row,
|
|
3115
|
+
:host([collapsed]) .skill-chips,
|
|
3116
|
+
:host([collapsed]) .skill-palette,
|
|
3117
|
+
:host([collapsed]) .skill-hint {
|
|
3118
|
+
display: none;
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
/* Edge-docked placements pin top *and* bottom, which would otherwise keep the
|
|
3122
|
+
panel full-height when collapsed; unpin the bottom so it shrinks to the
|
|
3123
|
+
header. (Floating/bottom-left pin only the bottom, so they already shrink.) */
|
|
3124
|
+
:host([collapsed][placement="side"]),
|
|
3125
|
+
:host([collapsed][placement="full"]) {
|
|
3126
|
+
bottom: auto;
|
|
3127
|
+
}
|
|
3128
|
+
|
|
452
3129
|
.messages {
|
|
453
3130
|
flex: 1;
|
|
454
3131
|
overflow-y: auto;
|
|
455
|
-
padding:
|
|
3132
|
+
padding: var(--ag-ui-pad);
|
|
456
3133
|
display: flex;
|
|
457
3134
|
flex-direction: column;
|
|
458
|
-
gap:
|
|
3135
|
+
gap: var(--ag-ui-space);
|
|
459
3136
|
}
|
|
460
3137
|
|
|
461
3138
|
.message {
|
|
462
3139
|
max-width: 80%;
|
|
463
|
-
padding:
|
|
464
|
-
border-radius:
|
|
3140
|
+
padding: var(--ag-ui-msg-pad);
|
|
3141
|
+
border-radius: var(--ag-ui-msg-radius);
|
|
465
3142
|
line-height: 1.4;
|
|
466
3143
|
white-space: pre-wrap;
|
|
467
3144
|
word-break: break-word;
|
|
468
3145
|
}
|
|
469
3146
|
|
|
3147
|
+
/* \u2500\u2500 Incoming-text animations (data-text-animation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
3148
|
+
:host([data-text-animation="fade"]) .message--assistant {
|
|
3149
|
+
animation: ag-ui-msg-fade 0.25s ease both;
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
@keyframes ag-ui-msg-fade {
|
|
3153
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
3154
|
+
to { opacity: 1; transform: none; }
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3157
|
+
.message--assistant .word {
|
|
3158
|
+
animation: ag-ui-word-in 0.3s ease both;
|
|
3159
|
+
animation-delay: calc(var(--ag-ui-word-index, 0) * 35ms);
|
|
3160
|
+
}
|
|
3161
|
+
|
|
3162
|
+
@keyframes ag-ui-word-in {
|
|
3163
|
+
from { opacity: 0; }
|
|
3164
|
+
to { opacity: 1; }
|
|
3165
|
+
}
|
|
3166
|
+
|
|
3167
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3168
|
+
:host([data-text-animation="fade"]) .message--assistant,
|
|
3169
|
+
.message--assistant .word {
|
|
3170
|
+
animation: none;
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
|
|
470
3174
|
.message--user {
|
|
471
3175
|
align-self: flex-end;
|
|
472
3176
|
background: var(--ag-ui-user-bg);
|
|
@@ -478,6 +3182,102 @@ var STYLES = `
|
|
|
478
3182
|
align-self: flex-start;
|
|
479
3183
|
background: var(--ag-ui-assistant-bg);
|
|
480
3184
|
border-bottom-left-radius: 4px;
|
|
3185
|
+
/* Assistant bubbles hold rendered markdown/HTML, so collapse the source
|
|
3186
|
+
whitespace the renderer leaves between block tags. */
|
|
3187
|
+
white-space: normal;
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
/* Rendered-markdown elements inside an assistant bubble. */
|
|
3191
|
+
.message--assistant > :first-child {
|
|
3192
|
+
margin-top: 0;
|
|
3193
|
+
}
|
|
3194
|
+
|
|
3195
|
+
.message--assistant > :last-child {
|
|
3196
|
+
margin-bottom: 0;
|
|
3197
|
+
}
|
|
3198
|
+
|
|
3199
|
+
.message--assistant p,
|
|
3200
|
+
.message--assistant ul,
|
|
3201
|
+
.message--assistant ol,
|
|
3202
|
+
.message--assistant blockquote,
|
|
3203
|
+
.message--assistant pre {
|
|
3204
|
+
margin: 0.5em 0;
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
.message--assistant ul,
|
|
3208
|
+
.message--assistant ol {
|
|
3209
|
+
padding-left: 1.3em;
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
.message--assistant a {
|
|
3213
|
+
color: var(--ag-ui-accent);
|
|
3214
|
+
text-decoration: underline;
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
.message--assistant code {
|
|
3218
|
+
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
3219
|
+
font-size: 0.92em;
|
|
3220
|
+
background: rgba(127, 127, 127, 0.16);
|
|
3221
|
+
padding: 1px 4px;
|
|
3222
|
+
border-radius: 4px;
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
.message--assistant pre {
|
|
3226
|
+
padding: 8px 10px;
|
|
3227
|
+
overflow: auto;
|
|
3228
|
+
background: var(--ag-ui-bg);
|
|
3229
|
+
border: 1px solid var(--ag-ui-border);
|
|
3230
|
+
border-radius: 6px;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
.message--assistant pre code {
|
|
3234
|
+
background: none;
|
|
3235
|
+
padding: 0;
|
|
3236
|
+
}
|
|
3237
|
+
|
|
3238
|
+
.message--assistant blockquote {
|
|
3239
|
+
padding-left: 10px;
|
|
3240
|
+
border-left: 3px solid var(--ag-ui-border);
|
|
3241
|
+
color: var(--ag-ui-muted);
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
.pending {
|
|
3245
|
+
align-self: flex-start;
|
|
3246
|
+
display: inline-flex;
|
|
3247
|
+
gap: 4px;
|
|
3248
|
+
align-items: center;
|
|
3249
|
+
padding: 12px 14px;
|
|
3250
|
+
background: var(--ag-ui-assistant-bg);
|
|
3251
|
+
border-radius: 14px;
|
|
3252
|
+
border-bottom-left-radius: 4px;
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3255
|
+
.pending-dot {
|
|
3256
|
+
width: 6px;
|
|
3257
|
+
height: 6px;
|
|
3258
|
+
border-radius: 50%;
|
|
3259
|
+
background: var(--ag-ui-muted);
|
|
3260
|
+
animation: ag-ui-pending 1.2s infinite ease-in-out both;
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
.pending-dot:nth-child(2) {
|
|
3264
|
+
animation-delay: 0.16s;
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
.pending-dot:nth-child(3) {
|
|
3268
|
+
animation-delay: 0.32s;
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
@keyframes ag-ui-pending {
|
|
3272
|
+
0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
|
|
3273
|
+
40% { opacity: 1; transform: translateY(-3px); }
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3276
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3277
|
+
.pending-dot {
|
|
3278
|
+
animation: none;
|
|
3279
|
+
opacity: 0.6;
|
|
3280
|
+
}
|
|
481
3281
|
}
|
|
482
3282
|
|
|
483
3283
|
.tool-call {
|
|
@@ -602,38 +3402,30 @@ var STYLES = `
|
|
|
602
3402
|
cursor: default;
|
|
603
3403
|
}
|
|
604
3404
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
3405
|
+
/* Inline confirmation card \u2014 lives in the transcript, no focus-stealing overlay. */
|
|
3406
|
+
.confirm {
|
|
3407
|
+
align-self: stretch;
|
|
3408
|
+
box-sizing: border-box;
|
|
608
3409
|
display: flex;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
padding:
|
|
612
|
-
background: rgba(20, 20, 50, 0.4);
|
|
613
|
-
backdrop-filter: blur(2px);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
.modal {
|
|
617
|
-
width: 100%;
|
|
618
|
-
max-width: 320px;
|
|
3410
|
+
flex-direction: column;
|
|
3411
|
+
gap: 8px;
|
|
3412
|
+
padding: 12px;
|
|
619
3413
|
background: var(--ag-ui-bg);
|
|
620
|
-
border
|
|
621
|
-
|
|
622
|
-
overflow: hidden;
|
|
3414
|
+
border: 1px solid var(--ag-ui-accent);
|
|
3415
|
+
border-radius: 10px;
|
|
623
3416
|
}
|
|
624
3417
|
|
|
625
|
-
.
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
border-bottom: 1px solid var(--ag-ui-border);
|
|
3418
|
+
.confirm[data-resolved] {
|
|
3419
|
+
opacity: 0.7;
|
|
3420
|
+
border-color: var(--ag-ui-border);
|
|
629
3421
|
}
|
|
630
3422
|
|
|
631
|
-
.
|
|
632
|
-
|
|
3423
|
+
.confirm-body {
|
|
3424
|
+
font-weight: 600;
|
|
633
3425
|
}
|
|
634
3426
|
|
|
635
|
-
.
|
|
636
|
-
margin: 0
|
|
3427
|
+
.confirm-args {
|
|
3428
|
+
margin: 0;
|
|
637
3429
|
padding: 8px 10px;
|
|
638
3430
|
max-height: 140px;
|
|
639
3431
|
overflow: auto;
|
|
@@ -645,14 +3437,13 @@ var STYLES = `
|
|
|
645
3437
|
word-break: break-word;
|
|
646
3438
|
}
|
|
647
3439
|
|
|
648
|
-
.
|
|
3440
|
+
.confirm-actions {
|
|
649
3441
|
display: flex;
|
|
650
3442
|
gap: 8px;
|
|
651
|
-
padding: 0 16px 16px;
|
|
652
3443
|
justify-content: flex-end;
|
|
653
3444
|
}
|
|
654
3445
|
|
|
655
|
-
.
|
|
3446
|
+
.confirm-btn {
|
|
656
3447
|
border: 1px solid var(--ag-ui-border);
|
|
657
3448
|
border-radius: 8px;
|
|
658
3449
|
padding: 8px 14px;
|
|
@@ -663,14 +3454,87 @@ var STYLES = `
|
|
|
663
3454
|
color: var(--ag-ui-fg);
|
|
664
3455
|
}
|
|
665
3456
|
|
|
666
|
-
.
|
|
3457
|
+
.confirm-btn:disabled {
|
|
3458
|
+
cursor: default;
|
|
3459
|
+
opacity: 0.6;
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3462
|
+
.confirm-btn--confirm {
|
|
667
3463
|
border-color: var(--ag-ui-accent);
|
|
668
3464
|
background: var(--ag-ui-accent);
|
|
669
3465
|
color: #ffffff;
|
|
670
3466
|
}
|
|
3467
|
+
|
|
3468
|
+
/* Skills \u2014 chips row + the /-command palette, above the input. */
|
|
3469
|
+
.skill-chips {
|
|
3470
|
+
display: flex;
|
|
3471
|
+
flex-wrap: wrap;
|
|
3472
|
+
gap: 6px;
|
|
3473
|
+
padding: 10px 12px;
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
.skill-chip {
|
|
3477
|
+
border: 1px solid var(--ag-ui-border);
|
|
3478
|
+
border-radius: 999px;
|
|
3479
|
+
padding: 4px 12px;
|
|
3480
|
+
font: inherit;
|
|
3481
|
+
font-size: 0.9em;
|
|
3482
|
+
cursor: pointer;
|
|
3483
|
+
background: var(--ag-ui-assistant-bg);
|
|
3484
|
+
color: var(--ag-ui-fg);
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
.skill-chip:hover {
|
|
3488
|
+
border-color: var(--ag-ui-accent);
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3491
|
+
.skill-palette {
|
|
3492
|
+
margin: 8px 12px 0;
|
|
3493
|
+
display: flex;
|
|
3494
|
+
flex-direction: column;
|
|
3495
|
+
max-height: 220px;
|
|
3496
|
+
overflow: auto;
|
|
3497
|
+
background: var(--ag-ui-bg);
|
|
3498
|
+
border: 1px solid var(--ag-ui-border);
|
|
3499
|
+
border-radius: 8px;
|
|
3500
|
+
box-shadow: 0 8px 24px rgba(20, 20, 50, 0.16);
|
|
3501
|
+
}
|
|
3502
|
+
|
|
3503
|
+
.skill-item {
|
|
3504
|
+
display: flex;
|
|
3505
|
+
flex-direction: column;
|
|
3506
|
+
gap: 2px;
|
|
3507
|
+
align-items: flex-start;
|
|
3508
|
+
padding: 8px 12px;
|
|
3509
|
+
border: none;
|
|
3510
|
+
background: none;
|
|
3511
|
+
font: inherit;
|
|
3512
|
+
text-align: left;
|
|
3513
|
+
cursor: pointer;
|
|
3514
|
+
color: var(--ag-ui-fg);
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3517
|
+
.skill-item[aria-selected="true"] {
|
|
3518
|
+
background: var(--ag-ui-assistant-bg);
|
|
3519
|
+
}
|
|
3520
|
+
|
|
3521
|
+
.skill-item-title {
|
|
3522
|
+
font-weight: 600;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
.skill-item-desc {
|
|
3526
|
+
font-size: 0.85em;
|
|
3527
|
+
color: var(--ag-ui-muted);
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
.skill-hint {
|
|
3531
|
+
margin: 8px 12px 0;
|
|
3532
|
+
font-size: 0.85em;
|
|
3533
|
+
color: var(--ag-ui-danger);
|
|
3534
|
+
}
|
|
671
3535
|
`;
|
|
672
3536
|
|
|
673
|
-
// src/tool_call_card.ts
|
|
3537
|
+
// src/ui/tool_call_card.ts
|
|
674
3538
|
var STATUS_LABEL = {
|
|
675
3539
|
[TOOL_CALL_STATUS.PENDING]: "running\u2026",
|
|
676
3540
|
[TOOL_CALL_STATUS.DONE]: "\u2713 done",
|
|
@@ -686,52 +3550,268 @@ var ToolCallCard = class {
|
|
|
686
3550
|
/** The card's root element; append this into the message list. */
|
|
687
3551
|
element;
|
|
688
3552
|
#status;
|
|
689
|
-
|
|
3553
|
+
#mode;
|
|
3554
|
+
#args;
|
|
3555
|
+
constructor(name, args, mode = TOOL_DISPLAY.FULL, summary) {
|
|
3556
|
+
this.#mode = mode;
|
|
3557
|
+
this.#args = args;
|
|
690
3558
|
this.element = document.createElement("div");
|
|
691
3559
|
this.element.className = "tool-call";
|
|
692
3560
|
this.element.setAttribute("data-tool-name", name);
|
|
693
3561
|
this.element.setAttribute("data-status", TOOL_CALL_STATUS.PENDING);
|
|
3562
|
+
this.element.setAttribute("data-display", mode);
|
|
694
3563
|
const head = document.createElement("div");
|
|
695
3564
|
head.className = "tool-call-head";
|
|
696
3565
|
const label = document.createElement("span");
|
|
697
3566
|
label.className = "tool-call-name";
|
|
698
|
-
label.textContent = `\u{1F527} ${name}`;
|
|
3567
|
+
label.textContent = `\u{1F527} ${summary ?? name}`;
|
|
699
3568
|
this.#status = document.createElement("span");
|
|
700
3569
|
this.#status.className = "tool-call-status";
|
|
701
3570
|
this.#status.textContent = STATUS_LABEL[TOOL_CALL_STATUS.PENDING];
|
|
702
3571
|
head.append(label, this.#status);
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
3572
|
+
this.element.append(head);
|
|
3573
|
+
if (mode === TOOL_DISPLAY.FULL) {
|
|
3574
|
+
const argsEl = document.createElement("pre");
|
|
3575
|
+
argsEl.className = "tool-call-args";
|
|
3576
|
+
argsEl.textContent = JSON.stringify(args, null, 2);
|
|
3577
|
+
this.element.append(argsEl);
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
/**
|
|
3581
|
+
* Flip the status pill to ``status`` and, unless in `minimal` mode, append a
|
|
3582
|
+
* collapsed body behind a click-to-expand toggle: the result alone (`full`),
|
|
3583
|
+
* or the args + result together (`compact`).
|
|
3584
|
+
*/
|
|
3585
|
+
settle(status, text2) {
|
|
3586
|
+
this.element.setAttribute("data-status", status);
|
|
3587
|
+
this.#status.textContent = STATUS_LABEL[status];
|
|
3588
|
+
if (this.#mode === TOOL_DISPLAY.MINIMAL) {
|
|
3589
|
+
return;
|
|
3590
|
+
}
|
|
3591
|
+
const toggle = document.createElement("button");
|
|
3592
|
+
toggle.type = "button";
|
|
3593
|
+
toggle.className = "tool-call-toggle";
|
|
3594
|
+
toggle.setAttribute("aria-expanded", "false");
|
|
3595
|
+
const output = document.createElement("pre");
|
|
3596
|
+
output.className = "tool-call-result";
|
|
3597
|
+
output.hidden = true;
|
|
3598
|
+
if (this.#mode === TOOL_DISPLAY.COMPACT) {
|
|
3599
|
+
toggle.textContent = "Details";
|
|
3600
|
+
output.textContent = `args: ${JSON.stringify(this.#args)}
|
|
3601
|
+
|
|
3602
|
+
${text2}`;
|
|
3603
|
+
} else {
|
|
3604
|
+
toggle.textContent = RESULT_LABEL[status];
|
|
3605
|
+
output.textContent = text2;
|
|
3606
|
+
}
|
|
3607
|
+
toggle.addEventListener("click", () => {
|
|
3608
|
+
const expand = output.hidden;
|
|
3609
|
+
output.hidden = !expand;
|
|
3610
|
+
toggle.setAttribute("aria-expanded", String(expand));
|
|
3611
|
+
});
|
|
3612
|
+
this.element.append(toggle, output);
|
|
3613
|
+
}
|
|
3614
|
+
};
|
|
3615
|
+
|
|
3616
|
+
// src/core/agui_client.ts
|
|
3617
|
+
import { randomUUID } from "@ag-ui/client";
|
|
3618
|
+
var AgUiClient = class {
|
|
3619
|
+
#agent;
|
|
3620
|
+
#handlers;
|
|
3621
|
+
#getTools;
|
|
3622
|
+
#getContext;
|
|
3623
|
+
#executeTool;
|
|
3624
|
+
#onPersist;
|
|
3625
|
+
constructor(config) {
|
|
3626
|
+
this.#agent = config.agent;
|
|
3627
|
+
this.#handlers = config.handlers;
|
|
3628
|
+
this.#getTools = config.getTools ?? (() => []);
|
|
3629
|
+
this.#getContext = config.getContext ?? (() => []);
|
|
3630
|
+
this.#executeTool = config.executeTool ?? null;
|
|
3631
|
+
this.#onPersist = config.onPersist ?? (() => {
|
|
3632
|
+
});
|
|
3633
|
+
}
|
|
3634
|
+
/** Whether a run is currently in flight. */
|
|
3635
|
+
get running() {
|
|
3636
|
+
return this.#agent.isRunning;
|
|
3637
|
+
}
|
|
3638
|
+
/** The current conversation history (for persistence / rehydration). */
|
|
3639
|
+
get messages() {
|
|
3640
|
+
return this.#agent.messages;
|
|
3641
|
+
}
|
|
3642
|
+
/**
|
|
3643
|
+
* Append a user message and run the agent to completion.
|
|
3644
|
+
*
|
|
3645
|
+
* When the agent calls frontend tools, this executes them and re-runs the
|
|
3646
|
+
* agent with the results, looping until the agent stops calling frontend
|
|
3647
|
+
* tools (bounded by {@link MAX_TOOL_ROUNDS}).
|
|
3648
|
+
*/
|
|
3649
|
+
async send(content) {
|
|
3650
|
+
this.#agent.addMessage({ id: randomUUID(), role: "user", content });
|
|
3651
|
+
this.#onPersist(this.#agent.messages);
|
|
3652
|
+
await this.#run();
|
|
3653
|
+
}
|
|
3654
|
+
/**
|
|
3655
|
+
* Resume the run loop after a navigating tool's result was supplied
|
|
3656
|
+
* post-reload (via {@link addToolResult}). Unlike {@link send}, adds no user
|
|
3657
|
+
* message — it simply continues the conversation already in history.
|
|
3658
|
+
*/
|
|
3659
|
+
async resume() {
|
|
3660
|
+
await this.#run();
|
|
3661
|
+
}
|
|
3662
|
+
/** Append a frontend tool result to history (used by the resume path). */
|
|
3663
|
+
addToolResult(toolCallId, content) {
|
|
3664
|
+
this.#agent.addMessage({ id: randomUUID(), role: "tool", content, toolCallId });
|
|
3665
|
+
this.#onPersist(this.#agent.messages);
|
|
3666
|
+
}
|
|
3667
|
+
async #run() {
|
|
3668
|
+
try {
|
|
3669
|
+
await this.#runLoop();
|
|
3670
|
+
} catch (error) {
|
|
3671
|
+
this.#handlers.onError(error instanceof Error ? error.message : String(error));
|
|
3672
|
+
} finally {
|
|
3673
|
+
this.#handlers.onSettled();
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
async #runLoop() {
|
|
3677
|
+
for (let round = 0; round < MAX_TOOL_ROUNDS; round += 1) {
|
|
3678
|
+
const pending = [];
|
|
3679
|
+
await this.#agent.runAgent(
|
|
3680
|
+
{ tools: this.#getTools(), context: this.#getContext() },
|
|
3681
|
+
this.#buildSubscriber(pending)
|
|
3682
|
+
);
|
|
3683
|
+
this.#onPersist(this.#agent.messages);
|
|
3684
|
+
if (this.#executeTool === null || pending.length === 0) {
|
|
3685
|
+
return;
|
|
3686
|
+
}
|
|
3687
|
+
let executed = false;
|
|
3688
|
+
for (const call of pending) {
|
|
3689
|
+
const result = await this.#executeTool(call);
|
|
3690
|
+
if (result === null) {
|
|
3691
|
+
continue;
|
|
3692
|
+
}
|
|
3693
|
+
if (result.halt === true) {
|
|
3694
|
+
return;
|
|
3695
|
+
}
|
|
3696
|
+
this.#agent.addMessage({
|
|
3697
|
+
id: randomUUID(),
|
|
3698
|
+
role: "tool",
|
|
3699
|
+
content: result.content,
|
|
3700
|
+
toolCallId: call.id
|
|
3701
|
+
});
|
|
3702
|
+
this.#onPersist(this.#agent.messages);
|
|
3703
|
+
executed = true;
|
|
3704
|
+
}
|
|
3705
|
+
if (!executed) {
|
|
3706
|
+
return;
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
#buildSubscriber(pending) {
|
|
3711
|
+
const h = this.#handlers;
|
|
3712
|
+
return {
|
|
3713
|
+
onRunInitialized() {
|
|
3714
|
+
h.onRunStart();
|
|
3715
|
+
},
|
|
3716
|
+
onTextMessageContentEvent({ textMessageBuffer }) {
|
|
3717
|
+
h.onTextDelta(textMessageBuffer);
|
|
3718
|
+
},
|
|
3719
|
+
onTextMessageEndEvent({ textMessageBuffer }) {
|
|
3720
|
+
h.onTextEnd(textMessageBuffer);
|
|
3721
|
+
},
|
|
3722
|
+
onToolCallEndEvent({ event, toolCallName, toolCallArgs }) {
|
|
3723
|
+
const call = {
|
|
3724
|
+
id: event.toolCallId,
|
|
3725
|
+
name: toolCallName,
|
|
3726
|
+
args: toolCallArgs
|
|
3727
|
+
};
|
|
3728
|
+
pending.push(call);
|
|
3729
|
+
h.onToolCall(call);
|
|
3730
|
+
},
|
|
3731
|
+
onToolCallResultEvent({ event }) {
|
|
3732
|
+
h.onToolResult(event.toolCallId, event.content);
|
|
3733
|
+
},
|
|
3734
|
+
onRunErrorEvent({ event }) {
|
|
3735
|
+
h.onError(event.message);
|
|
3736
|
+
},
|
|
3737
|
+
onRunFinalized() {
|
|
3738
|
+
h.onRunEnd();
|
|
3739
|
+
}
|
|
3740
|
+
};
|
|
707
3741
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
3742
|
+
};
|
|
3743
|
+
|
|
3744
|
+
// src/core/conversation_store.ts
|
|
3745
|
+
import { randomUUID as randomUUID2 } from "@ag-ui/client";
|
|
3746
|
+
var THREAD_KEY = "ag-ui-chat:thread";
|
|
3747
|
+
var MESSAGES_PREFIX = "ag-ui-chat:messages:";
|
|
3748
|
+
var CHECKPOINT_PREFIX = "ag-ui-chat:checkpoint:";
|
|
3749
|
+
var SessionStorageStore = class {
|
|
3750
|
+
threadId() {
|
|
3751
|
+
const existing = sessionStorage.getItem(THREAD_KEY);
|
|
3752
|
+
if (existing !== null) {
|
|
3753
|
+
return existing;
|
|
3754
|
+
}
|
|
3755
|
+
const id = randomUUID2();
|
|
3756
|
+
sessionStorage.setItem(THREAD_KEY, id);
|
|
3757
|
+
return id;
|
|
3758
|
+
}
|
|
3759
|
+
loadMessages(threadId) {
|
|
3760
|
+
return Promise.resolve(this.#readJson(MESSAGES_PREFIX + threadId));
|
|
3761
|
+
}
|
|
3762
|
+
saveMessages(threadId, messages) {
|
|
3763
|
+
sessionStorage.setItem(MESSAGES_PREFIX + threadId, JSON.stringify(messages));
|
|
3764
|
+
}
|
|
3765
|
+
loadCheckpoint(threadId) {
|
|
3766
|
+
return this.#readJson(CHECKPOINT_PREFIX + threadId);
|
|
3767
|
+
}
|
|
3768
|
+
saveCheckpoint(threadId, checkpoint) {
|
|
3769
|
+
const key = CHECKPOINT_PREFIX + threadId;
|
|
3770
|
+
if (checkpoint === null) {
|
|
3771
|
+
sessionStorage.removeItem(key);
|
|
3772
|
+
return;
|
|
3773
|
+
}
|
|
3774
|
+
sessionStorage.setItem(key, JSON.stringify(checkpoint));
|
|
3775
|
+
}
|
|
3776
|
+
clear(threadId) {
|
|
3777
|
+
sessionStorage.removeItem(MESSAGES_PREFIX + threadId);
|
|
3778
|
+
sessionStorage.removeItem(CHECKPOINT_PREFIX + threadId);
|
|
3779
|
+
sessionStorage.removeItem(THREAD_KEY);
|
|
3780
|
+
}
|
|
3781
|
+
/** Parse a stored JSON value, returning `null` when absent or corrupt. */
|
|
3782
|
+
#readJson(key) {
|
|
3783
|
+
const raw = sessionStorage.getItem(key);
|
|
3784
|
+
if (raw === null) {
|
|
3785
|
+
return null;
|
|
3786
|
+
}
|
|
3787
|
+
try {
|
|
3788
|
+
return JSON.parse(raw);
|
|
3789
|
+
} catch {
|
|
3790
|
+
return null;
|
|
3791
|
+
}
|
|
731
3792
|
}
|
|
732
3793
|
};
|
|
733
3794
|
|
|
734
|
-
// src/
|
|
3795
|
+
// src/core/create_http_agent.ts
|
|
3796
|
+
import { HttpAgent } from "@ag-ui/client";
|
|
3797
|
+
function createHttpAgent(options) {
|
|
3798
|
+
return new HttpAgent({
|
|
3799
|
+
url: options.endpoint,
|
|
3800
|
+
headers: options.headers ?? {},
|
|
3801
|
+
// HttpAgent invokes its configured fetch as a method (`this.fetch(...)`),
|
|
3802
|
+
// which would rebind the global `fetch` to the agent instance and trigger
|
|
3803
|
+
// "Illegal invocation" in browsers. Wrap it so `fetch` is always called as
|
|
3804
|
+
// a free function with the correct receiver.
|
|
3805
|
+
fetch: (url, init) => fetch(url, init),
|
|
3806
|
+
// Spread conditionally: under `exactOptionalPropertyTypes` an explicit
|
|
3807
|
+
// `undefined` is not assignable to these optional config fields.
|
|
3808
|
+
...options.threadId !== void 0 ? { threadId: options.threadId } : {},
|
|
3809
|
+
...options.initialMessages !== void 0 ? { initialMessages: [...options.initialMessages] } : {}
|
|
3810
|
+
});
|
|
3811
|
+
}
|
|
3812
|
+
|
|
3813
|
+
// src/core/ag_ui_chat.ts
|
|
3814
|
+
var COLLAPSED_KEY = "ag-ui-chat:collapsed";
|
|
735
3815
|
var AgUiChat = class extends HTMLElement {
|
|
736
3816
|
/** Agent factory; override to inject a custom or fake agent (tests). */
|
|
737
3817
|
agentFactory = createHttpAgent;
|
|
@@ -739,6 +3819,14 @@ var AgUiChat = class extends HTMLElement {
|
|
|
739
3819
|
headers = {};
|
|
740
3820
|
/** When true, destructive tools execute without a confirmation modal. */
|
|
741
3821
|
autoConfirm = false;
|
|
3822
|
+
/**
|
|
3823
|
+
* Optional per-call confirmation predicate. When set, it is authoritative:
|
|
3824
|
+
* given a tool name + args it decides whether *this* call needs confirmation
|
|
3825
|
+
* (so one tool can be instant for some args and confirmed for others — what a
|
|
3826
|
+
* static `x-destructive` flag can't express). When unset, the `x-destructive`
|
|
3827
|
+
* schema flag is used. `autoConfirm` short-circuits both.
|
|
3828
|
+
*/
|
|
3829
|
+
confirmPredicate = null;
|
|
742
3830
|
/**
|
|
743
3831
|
* Per-run frontend tool catalog provider. Defaults to the built-in
|
|
744
3832
|
* `route.*` tools (when a {@link routeMap} is set) plus the tools registered
|
|
@@ -746,7 +3834,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
746
3834
|
* fully custom catalog.
|
|
747
3835
|
*/
|
|
748
3836
|
getTools = () => [
|
|
749
|
-
...this.#
|
|
3837
|
+
...this.#builtinTools().map((t) => ({
|
|
750
3838
|
name: t.name,
|
|
751
3839
|
description: t.description,
|
|
752
3840
|
parameters: t.parameters
|
|
@@ -788,18 +3876,38 @@ var AgUiChat = class extends HTMLElement {
|
|
|
788
3876
|
navigated: true,
|
|
789
3877
|
url: window.location.href
|
|
790
3878
|
});
|
|
3879
|
+
/**
|
|
3880
|
+
* Named values used to fill a skill prompt's `{placeholder}`s before send
|
|
3881
|
+
* (e.g. `{ model: "Order", selected_ids: "1,2" }`). A host (the admin) sets
|
|
3882
|
+
* this from the current page; a missing placeholder blocks the send.
|
|
3883
|
+
*/
|
|
3884
|
+
skillContext = () => ({});
|
|
791
3885
|
#toolRegistry = new ClientToolRegistry();
|
|
792
3886
|
/** Tool-call cards awaiting execution, keyed by call id. */
|
|
793
3887
|
#toolCards = /* @__PURE__ */ new Map();
|
|
3888
|
+
/**
|
|
3889
|
+
* Call ids whose card was already settled from a streamed server-side result
|
|
3890
|
+
* (`TOOL_CALL_RESULT`), so the post-run executeTool sweep doesn't overwrite
|
|
3891
|
+
* the real output with the generic "executed on the server" fallback.
|
|
3892
|
+
*/
|
|
3893
|
+
#serverSettled = /* @__PURE__ */ new Set();
|
|
794
3894
|
#root;
|
|
795
3895
|
#chat;
|
|
796
3896
|
#messages;
|
|
797
3897
|
#input;
|
|
798
3898
|
#send;
|
|
3899
|
+
#title;
|
|
3900
|
+
#skillsMenu;
|
|
3901
|
+
#skillHint;
|
|
799
3902
|
#client = null;
|
|
800
3903
|
#streamingBubble = null;
|
|
3904
|
+
#pending = null;
|
|
801
3905
|
#threadId = "";
|
|
802
3906
|
#initialMessages = [];
|
|
3907
|
+
// Skill catalog by source; merged backend → embed → client (later wins).
|
|
3908
|
+
#backendSkills = [];
|
|
3909
|
+
#embedSkills = [];
|
|
3910
|
+
#clientSkills = [];
|
|
803
3911
|
constructor() {
|
|
804
3912
|
super();
|
|
805
3913
|
this.#root = this.attachShadow({ mode: "open" });
|
|
@@ -807,6 +3915,16 @@ var AgUiChat = class extends HTMLElement {
|
|
|
807
3915
|
this.#messages = document.createElement("div");
|
|
808
3916
|
this.#input = document.createElement("textarea");
|
|
809
3917
|
this.#send = document.createElement("button");
|
|
3918
|
+
this.#title = document.createElement("span");
|
|
3919
|
+
this.#skillHint = document.createElement("div");
|
|
3920
|
+
this.#skillsMenu = new SkillsMenu((skill) => this.#applySkill(skill));
|
|
3921
|
+
}
|
|
3922
|
+
/** Attributes whose late changes must reflect in already-rendered chrome. */
|
|
3923
|
+
static get observedAttributes() {
|
|
3924
|
+
return ["title-text"];
|
|
3925
|
+
}
|
|
3926
|
+
attributeChangedCallback(_name, _previous, value) {
|
|
3927
|
+
this.#title.textContent = value ?? "Assistant";
|
|
810
3928
|
}
|
|
811
3929
|
/** Declare a frontend tool the agent may call. */
|
|
812
3930
|
registerTool(tool) {
|
|
@@ -828,11 +3946,34 @@ var AgUiChat = class extends HTMLElement {
|
|
|
828
3946
|
() => this.navigate
|
|
829
3947
|
);
|
|
830
3948
|
}
|
|
831
|
-
/**
|
|
3949
|
+
/**
|
|
3950
|
+
* The built-in `read_page` tool, present only when a {@link getPageMap}
|
|
3951
|
+
* provider is set. A *pull* the agent can call mid-turn to see the page after
|
|
3952
|
+
* it has acted (the auto-injected context is a send-time snapshot).
|
|
3953
|
+
*/
|
|
3954
|
+
#pageTools() {
|
|
3955
|
+
const getPageMap = this.getPageMap;
|
|
3956
|
+
if (getPageMap === null) {
|
|
3957
|
+
return [];
|
|
3958
|
+
}
|
|
3959
|
+
return [
|
|
3960
|
+
{
|
|
3961
|
+
name: "read_page",
|
|
3962
|
+
description: "Read the current page's structure (fields, buttons, route). Call after acting to observe the result within the same turn.",
|
|
3963
|
+
parameters: { type: "object", properties: {}, required: [] },
|
|
3964
|
+
handler: () => getPageMap()
|
|
3965
|
+
}
|
|
3966
|
+
];
|
|
3967
|
+
}
|
|
3968
|
+
/** All built-in (route + page) frontend tools. */
|
|
3969
|
+
#builtinTools() {
|
|
3970
|
+
return [...this.#routeTools(), ...this.#pageTools()];
|
|
3971
|
+
}
|
|
3972
|
+
/** Resolve a tool by name: built-in tools first, then the registry. */
|
|
832
3973
|
#resolveTool(name) {
|
|
833
|
-
const
|
|
834
|
-
if (
|
|
835
|
-
return
|
|
3974
|
+
const builtin = this.#builtinTools().find((t) => t.name === name);
|
|
3975
|
+
if (builtin !== void 0) {
|
|
3976
|
+
return builtin;
|
|
836
3977
|
}
|
|
837
3978
|
return this.#toolRegistry.has(name) ? this.#toolRegistry.get(name) : null;
|
|
838
3979
|
}
|
|
@@ -840,11 +3981,149 @@ var AgUiChat = class extends HTMLElement {
|
|
|
840
3981
|
get endpoint() {
|
|
841
3982
|
return this.getAttribute("endpoint") ?? "";
|
|
842
3983
|
}
|
|
3984
|
+
// Reflecting setter so frameworks (e.g. React 19) that assign matching
|
|
3985
|
+
// props as element *properties* don't hit a read-only property. Read at
|
|
3986
|
+
// use-time, so a runtime change applies to the next run.
|
|
3987
|
+
set endpoint(value) {
|
|
3988
|
+
this.setAttribute("endpoint", value);
|
|
3989
|
+
}
|
|
3990
|
+
/**
|
|
3991
|
+
* How much detail tool-call cards show, from the `data-tool-display`
|
|
3992
|
+
* attribute (`minimal` / `compact` / `full`). Defaults to `full`.
|
|
3993
|
+
*/
|
|
3994
|
+
get toolDisplay() {
|
|
3995
|
+
const attr = this.getAttribute("data-tool-display");
|
|
3996
|
+
if (attr === TOOL_DISPLAY.MINIMAL || attr === TOOL_DISPLAY.COMPACT) {
|
|
3997
|
+
return attr;
|
|
3998
|
+
}
|
|
3999
|
+
return TOOL_DISPLAY.FULL;
|
|
4000
|
+
}
|
|
4001
|
+
set toolDisplay(value) {
|
|
4002
|
+
this.setAttribute("data-tool-display", value);
|
|
4003
|
+
}
|
|
843
4004
|
connectedCallback() {
|
|
844
4005
|
this.#render();
|
|
4006
|
+
if (sessionStorage.getItem(COLLAPSED_KEY) === "1") {
|
|
4007
|
+
this.setAttribute("collapsed", "");
|
|
4008
|
+
}
|
|
4009
|
+
this.#initSkills();
|
|
845
4010
|
this.#threadId = this.conversationStore.threadId();
|
|
846
4011
|
void this.#rehydrate();
|
|
847
4012
|
}
|
|
4013
|
+
/**
|
|
4014
|
+
* Replace the host-supplied (client) skill catalog. Merged after the embedded
|
|
4015
|
+
* and fetched skills (so a client skill overrides a same-named server one).
|
|
4016
|
+
*/
|
|
4017
|
+
setSkills(skills) {
|
|
4018
|
+
this.#clientSkills = skills;
|
|
4019
|
+
this.#recomputeSkills();
|
|
4020
|
+
}
|
|
4021
|
+
/** Wire the skill surfaces: opt-in flags, embedded catalog, optional fetch. */
|
|
4022
|
+
#initSkills() {
|
|
4023
|
+
this.#skillsMenu.enableChips(this.getAttribute("data-prompt-chips") === "true");
|
|
4024
|
+
this.#skillsMenu.enableSlash(this.getAttribute("data-slash-commands") === "true");
|
|
4025
|
+
this.#embedSkills = this.#readEmbeddedSkills();
|
|
4026
|
+
this.#recomputeSkills();
|
|
4027
|
+
void this.#fetchSkills();
|
|
4028
|
+
}
|
|
4029
|
+
/** Parse the inline `data-skills` JSON catalog (empty when absent/malformed). */
|
|
4030
|
+
#readEmbeddedSkills() {
|
|
4031
|
+
const raw = this.getAttribute("data-skills");
|
|
4032
|
+
if (raw === null) {
|
|
4033
|
+
return [];
|
|
4034
|
+
}
|
|
4035
|
+
try {
|
|
4036
|
+
return parseSkills(JSON.parse(raw));
|
|
4037
|
+
} catch {
|
|
4038
|
+
return [];
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
/** Fetch the backend skills catalog from `data-skills-url`, if set. */
|
|
4042
|
+
async #fetchSkills() {
|
|
4043
|
+
const url = this.getAttribute("data-skills-url");
|
|
4044
|
+
if (url === null) {
|
|
4045
|
+
return;
|
|
4046
|
+
}
|
|
4047
|
+
try {
|
|
4048
|
+
const response = await fetch(url, { headers: this.headers });
|
|
4049
|
+
this.#backendSkills = parseSkills(await response.json());
|
|
4050
|
+
this.#recomputeSkills();
|
|
4051
|
+
} catch {
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
/** Merge the three sources (backend → embed → client; later wins by name). */
|
|
4055
|
+
#recomputeSkills() {
|
|
4056
|
+
const merged = /* @__PURE__ */ new Map();
|
|
4057
|
+
for (const skill of [...this.#backendSkills, ...this.#embedSkills, ...this.#clientSkills]) {
|
|
4058
|
+
merged.set(skill.name, skill);
|
|
4059
|
+
}
|
|
4060
|
+
this.#skillsMenu.setSkills([...merged.values()]);
|
|
4061
|
+
}
|
|
4062
|
+
/** Pre-fill (or send) a picked skill's prompt, filling its placeholders. */
|
|
4063
|
+
#applySkill(skill) {
|
|
4064
|
+
const { text: text2, missing } = fillTemplate(skill.prompt, this.skillContext());
|
|
4065
|
+
if (missing.length > 0) {
|
|
4066
|
+
this.#skillHint.textContent = `\u201C${skill.title}\u201D needs: ${missing.join(", ")}`;
|
|
4067
|
+
this.#skillHint.hidden = false;
|
|
4068
|
+
return;
|
|
4069
|
+
}
|
|
4070
|
+
this.#skillHint.hidden = true;
|
|
4071
|
+
this.#input.value = text2;
|
|
4072
|
+
if (skill.sendImmediately === true) {
|
|
4073
|
+
void this.#submit();
|
|
4074
|
+
} else {
|
|
4075
|
+
this.#input.focus();
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
/** Whether the widget is collapsed (reflected as the `collapsed` attribute). */
|
|
4079
|
+
get collapsed() {
|
|
4080
|
+
return this.hasAttribute("collapsed");
|
|
4081
|
+
}
|
|
4082
|
+
// Property setter (framework interop) — delegates to setCollapsed so a
|
|
4083
|
+
// `collapsed` prop assignment persists + emits the toggle event.
|
|
4084
|
+
set collapsed(value) {
|
|
4085
|
+
this.setCollapsed(value);
|
|
4086
|
+
}
|
|
4087
|
+
/**
|
|
4088
|
+
* Set the collapsed state: reflect the `collapsed` attribute, persist it
|
|
4089
|
+
* per-tab, and emit a {@link TOGGLE_EVENT} so a host can mirror the state in
|
|
4090
|
+
* its own chrome.
|
|
4091
|
+
*/
|
|
4092
|
+
setCollapsed(collapsed) {
|
|
4093
|
+
if (collapsed) {
|
|
4094
|
+
this.setAttribute("collapsed", "");
|
|
4095
|
+
} else {
|
|
4096
|
+
this.removeAttribute("collapsed");
|
|
4097
|
+
}
|
|
4098
|
+
sessionStorage.setItem(COLLAPSED_KEY, collapsed ? "1" : "0");
|
|
4099
|
+
this.dispatchEvent(
|
|
4100
|
+
new CustomEvent(TOGGLE_EVENT, {
|
|
4101
|
+
detail: { collapsed },
|
|
4102
|
+
bubbles: true,
|
|
4103
|
+
composed: true
|
|
4104
|
+
})
|
|
4105
|
+
);
|
|
4106
|
+
}
|
|
4107
|
+
/** Flip the collapsed state. Bound to the built-in header toggle. */
|
|
4108
|
+
toggleCollapsed() {
|
|
4109
|
+
this.setCollapsed(!this.collapsed);
|
|
4110
|
+
}
|
|
4111
|
+
/**
|
|
4112
|
+
* Start a fresh conversation: forget the persisted history, drop the
|
|
4113
|
+
* in-memory run state, clear the transcript, and mint a new thread id.
|
|
4114
|
+
*/
|
|
4115
|
+
newChat() {
|
|
4116
|
+
this.conversationStore.clear(this.#threadId);
|
|
4117
|
+
this.#client = null;
|
|
4118
|
+
this.#streamingBubble = null;
|
|
4119
|
+
this.#hidePending();
|
|
4120
|
+
this.#toolCards.clear();
|
|
4121
|
+
this.#serverSettled.clear();
|
|
4122
|
+
this.#initialMessages = [];
|
|
4123
|
+
this.#messages.replaceChildren();
|
|
4124
|
+
this.#threadId = this.conversationStore.threadId();
|
|
4125
|
+
this.#send.disabled = false;
|
|
4126
|
+
}
|
|
848
4127
|
/**
|
|
849
4128
|
* Restore the conversation from the store on mount, then — if a navigating
|
|
850
4129
|
* tool reloaded the page mid-run — resume the loop by supplying that tool's
|
|
@@ -863,15 +4142,61 @@ var AgUiChat = class extends HTMLElement {
|
|
|
863
4142
|
await this.#resumeFrom(checkpoint);
|
|
864
4143
|
}
|
|
865
4144
|
}
|
|
866
|
-
/**
|
|
4145
|
+
/**
|
|
4146
|
+
* Replay a restored message: text bubbles *and* tool activity. An assistant
|
|
4147
|
+
* turn may carry `toolCalls` (rendered as cards) and/or text; a `tool` turn
|
|
4148
|
+
* carries a result that settles the matching card. So a refreshed page shows
|
|
4149
|
+
* the full transcript — tool calls and their results — not just the prose.
|
|
4150
|
+
*/
|
|
867
4151
|
#renderHistoricMessage(message) {
|
|
868
|
-
|
|
4152
|
+
const text2 = typeof message.content === "string" ? message.content : "";
|
|
4153
|
+
if (message.role === MESSAGE_ROLE.USER) {
|
|
4154
|
+
if (text2 !== "") {
|
|
4155
|
+
this.appendMessage(MESSAGE_ROLE.USER, text2);
|
|
4156
|
+
}
|
|
869
4157
|
return;
|
|
870
4158
|
}
|
|
871
|
-
if (message.role === MESSAGE_ROLE.
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
4159
|
+
if (message.role === MESSAGE_ROLE.ASSISTANT) {
|
|
4160
|
+
if (text2 !== "") {
|
|
4161
|
+
this.#revealWords(this.appendMessage(MESSAGE_ROLE.ASSISTANT, text2));
|
|
4162
|
+
}
|
|
4163
|
+
const toolCalls = message.toolCalls;
|
|
4164
|
+
if (toolCalls !== void 0) {
|
|
4165
|
+
for (const call of toolCalls) {
|
|
4166
|
+
this.#cardFor({
|
|
4167
|
+
id: call.id,
|
|
4168
|
+
name: call.function.name,
|
|
4169
|
+
args: this.#parseArgs(call.function.arguments)
|
|
4170
|
+
});
|
|
4171
|
+
}
|
|
4172
|
+
}
|
|
4173
|
+
return;
|
|
4174
|
+
}
|
|
4175
|
+
if (message.role === "tool") {
|
|
4176
|
+
const card = this.#toolCards.get(message.toolCallId);
|
|
4177
|
+
if (card !== void 0) {
|
|
4178
|
+
card.settle(TOOL_CALL_STATUS.DONE, message.content);
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
/** Parse a tool call's JSON `arguments` string from history into an object. */
|
|
4183
|
+
#parseArgs(raw) {
|
|
4184
|
+
try {
|
|
4185
|
+
const parsed = JSON.parse(raw);
|
|
4186
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
4187
|
+
return parsed;
|
|
4188
|
+
}
|
|
4189
|
+
} catch {
|
|
4190
|
+
}
|
|
4191
|
+
return {};
|
|
4192
|
+
}
|
|
4193
|
+
/**
|
|
4194
|
+
* Word-by-word reveal for the `word` text-animation mode, applied to a
|
|
4195
|
+
* completed assistant bubble. `fade` is pure CSS (no JS); `none` is a no-op.
|
|
4196
|
+
*/
|
|
4197
|
+
#revealWords(bubble) {
|
|
4198
|
+
if (this.getAttribute("data-text-animation") === "word") {
|
|
4199
|
+
wrapWords(bubble);
|
|
875
4200
|
}
|
|
876
4201
|
}
|
|
877
4202
|
/** Complete the checkpointed navigating tool call and continue the run. */
|
|
@@ -881,11 +4206,21 @@ var AgUiChat = class extends HTMLElement {
|
|
|
881
4206
|
client.addToolResult(checkpoint.toolCallId, JSON.stringify(this.navigationResult(checkpoint)));
|
|
882
4207
|
await client.resume();
|
|
883
4208
|
}
|
|
884
|
-
/**
|
|
4209
|
+
/**
|
|
4210
|
+
* Append a message bubble and return it.
|
|
4211
|
+
*
|
|
4212
|
+
* Assistant content is rendered as sanitised markdown/HTML; user content
|
|
4213
|
+
* stays literal text (no need to parse what the user typed, and it avoids
|
|
4214
|
+
* rendering user-authored markup).
|
|
4215
|
+
*/
|
|
885
4216
|
appendMessage(role, content) {
|
|
886
4217
|
const bubble = document.createElement("div");
|
|
887
4218
|
bubble.className = `message message--${role}`;
|
|
888
|
-
|
|
4219
|
+
if (role === MESSAGE_ROLE.ASSISTANT) {
|
|
4220
|
+
bubble.innerHTML = renderMarkdown(content);
|
|
4221
|
+
} else {
|
|
4222
|
+
bubble.textContent = content;
|
|
4223
|
+
}
|
|
889
4224
|
this.#messages.appendChild(bubble);
|
|
890
4225
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
891
4226
|
return bubble;
|
|
@@ -896,25 +4231,68 @@ var AgUiChat = class extends HTMLElement {
|
|
|
896
4231
|
this.#chat.className = "chat";
|
|
897
4232
|
const header = document.createElement("div");
|
|
898
4233
|
header.className = "header";
|
|
899
|
-
|
|
4234
|
+
const title = this.#title;
|
|
4235
|
+
title.className = "header-title";
|
|
4236
|
+
title.textContent = this.getAttribute("title-text") ?? "Assistant";
|
|
4237
|
+
const controls = document.createElement("div");
|
|
4238
|
+
controls.className = "header-controls";
|
|
4239
|
+
const newChat = document.createElement("button");
|
|
4240
|
+
newChat.type = "button";
|
|
4241
|
+
newChat.className = "header-btn header-btn--new";
|
|
4242
|
+
newChat.title = "New chat";
|
|
4243
|
+
newChat.setAttribute("aria-label", "New chat");
|
|
4244
|
+
newChat.textContent = "\u271A";
|
|
4245
|
+
newChat.addEventListener("click", () => this.newChat());
|
|
4246
|
+
const collapse = document.createElement("button");
|
|
4247
|
+
collapse.type = "button";
|
|
4248
|
+
collapse.className = "header-btn header-btn--collapse";
|
|
4249
|
+
collapse.title = "Collapse";
|
|
4250
|
+
collapse.setAttribute("aria-label", "Collapse");
|
|
4251
|
+
collapse.textContent = "\u2014";
|
|
4252
|
+
collapse.addEventListener("click", () => this.toggleCollapsed());
|
|
4253
|
+
controls.append(newChat, collapse);
|
|
4254
|
+
header.append(title, controls);
|
|
900
4255
|
this.#messages.className = "messages";
|
|
4256
|
+
this.#messages.setAttribute("role", "log");
|
|
4257
|
+
this.#messages.setAttribute("aria-live", "polite");
|
|
4258
|
+
this.#messages.setAttribute("aria-label", "Conversation");
|
|
901
4259
|
const inputRow = document.createElement("div");
|
|
902
4260
|
inputRow.className = "input-row";
|
|
903
4261
|
this.#input.className = "input";
|
|
4262
|
+
this.#input.setAttribute("aria-label", "Message");
|
|
904
4263
|
this.#input.rows = 2;
|
|
905
4264
|
this.#input.placeholder = "Ask anything\u2026";
|
|
906
4265
|
this.#input.addEventListener("keydown", (event) => this.#onKeydown(event));
|
|
4266
|
+
this.#input.addEventListener("input", () => this.#onInput());
|
|
907
4267
|
this.#send.className = "send";
|
|
908
4268
|
this.#send.type = "button";
|
|
909
4269
|
this.#send.textContent = "Send";
|
|
910
4270
|
this.#send.addEventListener("click", () => {
|
|
911
4271
|
void this.#submit();
|
|
912
4272
|
});
|
|
4273
|
+
this.#skillHint.className = "skill-hint";
|
|
4274
|
+
this.#skillHint.hidden = true;
|
|
913
4275
|
inputRow.append(this.#input, this.#send);
|
|
914
|
-
this.#chat.append(
|
|
4276
|
+
this.#chat.append(
|
|
4277
|
+
header,
|
|
4278
|
+
this.#messages,
|
|
4279
|
+
this.#skillsMenu.palette,
|
|
4280
|
+
this.#skillsMenu.chips,
|
|
4281
|
+
this.#skillHint,
|
|
4282
|
+
inputRow
|
|
4283
|
+
);
|
|
915
4284
|
this.#root.append(style, this.#chat);
|
|
916
4285
|
}
|
|
4286
|
+
/** Forward input changes to the skills palette and clear any stale hint. */
|
|
4287
|
+
#onInput() {
|
|
4288
|
+
this.#skillsMenu.onInput(this.#input.value);
|
|
4289
|
+
this.#skillHint.hidden = true;
|
|
4290
|
+
}
|
|
917
4291
|
#onKeydown(event) {
|
|
4292
|
+
if (this.#skillsMenu.onKeydown(event)) {
|
|
4293
|
+
event.preventDefault();
|
|
4294
|
+
return;
|
|
4295
|
+
}
|
|
918
4296
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
919
4297
|
event.preventDefault();
|
|
920
4298
|
void this.#submit();
|
|
@@ -961,22 +4339,39 @@ var AgUiChat = class extends HTMLElement {
|
|
|
961
4339
|
}
|
|
962
4340
|
return this.#client;
|
|
963
4341
|
}
|
|
4342
|
+
/** Whether ``call`` should be gated behind the confirmation card. */
|
|
4343
|
+
async #needsConfirmation(call, tool) {
|
|
4344
|
+
if (this.autoConfirm) {
|
|
4345
|
+
return false;
|
|
4346
|
+
}
|
|
4347
|
+
if (this.confirmPredicate !== null) {
|
|
4348
|
+
return await this.confirmPredicate(call.name, call.args) === true;
|
|
4349
|
+
}
|
|
4350
|
+
return isDestructive(tool.parameters);
|
|
4351
|
+
}
|
|
964
4352
|
async #executeTool(call) {
|
|
965
4353
|
const card = this.#cardFor(call);
|
|
966
4354
|
this.#toolCards.delete(call.id);
|
|
967
4355
|
const tool = this.#resolveTool(call.name);
|
|
968
4356
|
if (tool === null) {
|
|
969
|
-
|
|
4357
|
+
if (!this.#serverSettled.has(call.id)) {
|
|
4358
|
+
card.settle(TOOL_CALL_STATUS.DONE, "Executed on the server.");
|
|
4359
|
+
}
|
|
970
4360
|
return null;
|
|
971
4361
|
}
|
|
972
|
-
if (
|
|
973
|
-
const
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
4362
|
+
if (await this.#needsConfirmation(call, tool)) {
|
|
4363
|
+
const request = { toolName: call.name, args: call.args };
|
|
4364
|
+
const confirmText = tool.parameters[X_CONFIRM_KEY];
|
|
4365
|
+
if (typeof confirmText === "string") {
|
|
4366
|
+
request.message = confirmText;
|
|
4367
|
+
}
|
|
4368
|
+
const decision = requestConfirmation(this.#messages, request);
|
|
4369
|
+
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
4370
|
+
const accepted = await decision;
|
|
977
4371
|
if (!accepted) {
|
|
978
4372
|
const message = "User declined the action.";
|
|
979
4373
|
card.settle(TOOL_CALL_STATUS.DECLINED, message);
|
|
4374
|
+
this.#showPending();
|
|
980
4375
|
return { content: message };
|
|
981
4376
|
}
|
|
982
4377
|
}
|
|
@@ -992,6 +4387,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
992
4387
|
}
|
|
993
4388
|
const content = JSON.stringify(result ?? null);
|
|
994
4389
|
card.settle(TOOL_CALL_STATUS.DONE, content);
|
|
4390
|
+
this.#showPending();
|
|
995
4391
|
return { content };
|
|
996
4392
|
} catch (error) {
|
|
997
4393
|
if (navigates) {
|
|
@@ -999,6 +4395,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
999
4395
|
}
|
|
1000
4396
|
const message = error instanceof Error ? error.message : String(error);
|
|
1001
4397
|
card.settle(TOOL_CALL_STATUS.ERROR, message);
|
|
4398
|
+
this.#showPending();
|
|
1002
4399
|
return { content: `Error: ${message}`, error: message };
|
|
1003
4400
|
}
|
|
1004
4401
|
}
|
|
@@ -1006,34 +4403,80 @@ var AgUiChat = class extends HTMLElement {
|
|
|
1006
4403
|
return {
|
|
1007
4404
|
onRunStart: () => {
|
|
1008
4405
|
this.#send.disabled = true;
|
|
4406
|
+
this.#showPending();
|
|
1009
4407
|
},
|
|
1010
4408
|
onTextDelta: (buffer) => {
|
|
4409
|
+
this.#hidePending();
|
|
1011
4410
|
this.#streamInto(buffer);
|
|
1012
4411
|
},
|
|
1013
4412
|
onTextEnd: (buffer) => {
|
|
1014
|
-
this.#streamInto(buffer);
|
|
4413
|
+
this.#revealWords(this.#streamInto(buffer));
|
|
1015
4414
|
this.#streamingBubble = null;
|
|
1016
4415
|
},
|
|
1017
4416
|
onToolCall: (call) => {
|
|
4417
|
+
this.#hidePending();
|
|
1018
4418
|
this.#cardFor(call);
|
|
1019
4419
|
},
|
|
4420
|
+
onToolResult: (toolCallId, content) => {
|
|
4421
|
+
const card = this.#toolCards.get(toolCallId);
|
|
4422
|
+
if (card === void 0) {
|
|
4423
|
+
return;
|
|
4424
|
+
}
|
|
4425
|
+
card.settle(TOOL_CALL_STATUS.DONE, content);
|
|
4426
|
+
this.#serverSettled.add(toolCallId);
|
|
4427
|
+
},
|
|
1020
4428
|
onRunEnd: () => {
|
|
4429
|
+
this.#hidePending();
|
|
1021
4430
|
this.#send.disabled = false;
|
|
1022
4431
|
this.#streamingBubble = null;
|
|
1023
4432
|
},
|
|
1024
4433
|
onError: (message) => {
|
|
1025
|
-
this
|
|
4434
|
+
this.#hidePending();
|
|
4435
|
+
this.#revealWords(this.appendMessage(MESSAGE_ROLE.ASSISTANT, `\u26A0\uFE0F ${message}`));
|
|
4436
|
+
this.#send.disabled = false;
|
|
4437
|
+
this.#streamingBubble = null;
|
|
4438
|
+
},
|
|
4439
|
+
onSettled: () => {
|
|
4440
|
+
this.#hidePending();
|
|
1026
4441
|
this.#send.disabled = false;
|
|
1027
4442
|
this.#streamingBubble = null;
|
|
1028
4443
|
}
|
|
1029
4444
|
};
|
|
1030
4445
|
}
|
|
4446
|
+
/**
|
|
4447
|
+
* Show a "thinking" indicator while the agent is being awaited — both the
|
|
4448
|
+
* silent stretch before the first token and the gap after a tool result
|
|
4449
|
+
* while the next round is requested. Idempotent.
|
|
4450
|
+
*/
|
|
4451
|
+
#showPending() {
|
|
4452
|
+
if (this.#pending !== null) {
|
|
4453
|
+
return;
|
|
4454
|
+
}
|
|
4455
|
+
const pending = document.createElement("div");
|
|
4456
|
+
pending.className = "pending";
|
|
4457
|
+
pending.setAttribute("role", "status");
|
|
4458
|
+
pending.setAttribute("aria-label", "Assistant is thinking\u2026");
|
|
4459
|
+
for (let i = 0; i < 3; i += 1) {
|
|
4460
|
+
const dot = document.createElement("span");
|
|
4461
|
+
dot.className = "pending-dot";
|
|
4462
|
+
pending.appendChild(dot);
|
|
4463
|
+
}
|
|
4464
|
+
this.#pending = pending;
|
|
4465
|
+
this.#messages.appendChild(pending);
|
|
4466
|
+
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
4467
|
+
}
|
|
4468
|
+
/** Remove the pending indicator if shown. */
|
|
4469
|
+
#hidePending() {
|
|
4470
|
+
this.#pending?.remove();
|
|
4471
|
+
this.#pending = null;
|
|
4472
|
+
}
|
|
1031
4473
|
#streamInto(buffer) {
|
|
1032
4474
|
if (this.#streamingBubble === null) {
|
|
1033
4475
|
this.#streamingBubble = this.appendMessage(MESSAGE_ROLE.ASSISTANT, "");
|
|
1034
4476
|
}
|
|
1035
|
-
this.#streamingBubble.
|
|
4477
|
+
this.#streamingBubble.innerHTML = renderMarkdown(buffer);
|
|
1036
4478
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
4479
|
+
return this.#streamingBubble;
|
|
1037
4480
|
}
|
|
1038
4481
|
/**
|
|
1039
4482
|
* The card for ``call``, creating and appending it on first sight.
|
|
@@ -1046,7 +4489,13 @@ var AgUiChat = class extends HTMLElement {
|
|
|
1046
4489
|
if (existing !== void 0) {
|
|
1047
4490
|
return existing;
|
|
1048
4491
|
}
|
|
1049
|
-
const
|
|
4492
|
+
const summary = this.#resolveTool(call.name)?.parameters[X_SUMMARY_KEY];
|
|
4493
|
+
const card = new ToolCallCard(
|
|
4494
|
+
call.name,
|
|
4495
|
+
call.args,
|
|
4496
|
+
this.toolDisplay,
|
|
4497
|
+
typeof summary === "string" ? summary : void 0
|
|
4498
|
+
);
|
|
1050
4499
|
this.#toolCards.set(call.id, card);
|
|
1051
4500
|
this.#messages.appendChild(card.element);
|
|
1052
4501
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
@@ -1054,7 +4503,36 @@ var AgUiChat = class extends HTMLElement {
|
|
|
1054
4503
|
}
|
|
1055
4504
|
};
|
|
1056
4505
|
|
|
1057
|
-
// src/
|
|
4506
|
+
// src/core/define_ag_ui_chat.ts
|
|
4507
|
+
function defineAgUiChat() {
|
|
4508
|
+
if (customElements.get(ELEMENT_TAG) === void 0) {
|
|
4509
|
+
customElements.define(ELEMENT_TAG, AgUiChat);
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
|
|
4513
|
+
// src/dom/native_setter.ts
|
|
4514
|
+
function prototypeSetter(proto, prop) {
|
|
4515
|
+
const setter = Object.getOwnPropertyDescriptor(proto, prop).set;
|
|
4516
|
+
return setter;
|
|
4517
|
+
}
|
|
4518
|
+
var setInputValue = prototypeSetter(HTMLInputElement.prototype, "value");
|
|
4519
|
+
var setTextareaValue = prototypeSetter(HTMLTextAreaElement.prototype, "value");
|
|
4520
|
+
var setSelectValue = prototypeSetter(HTMLSelectElement.prototype, "value");
|
|
4521
|
+
var setInputChecked = prototypeSetter(HTMLInputElement.prototype, "checked");
|
|
4522
|
+
function setNativeValue(el, value) {
|
|
4523
|
+
if (el instanceof HTMLTextAreaElement) {
|
|
4524
|
+
setTextareaValue.call(el, value);
|
|
4525
|
+
} else if (el instanceof HTMLSelectElement) {
|
|
4526
|
+
setSelectValue.call(el, value);
|
|
4527
|
+
} else {
|
|
4528
|
+
setInputValue.call(el, value);
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
function setNativeChecked(el, checked) {
|
|
4532
|
+
setInputChecked.call(el, checked);
|
|
4533
|
+
}
|
|
4534
|
+
|
|
4535
|
+
// src/dom/animations.ts
|
|
1058
4536
|
var ACCENT = "#4f46e5";
|
|
1059
4537
|
function delay(ms) {
|
|
1060
4538
|
return new Promise((resolve) => {
|
|
@@ -1063,10 +4541,10 @@ function delay(ms) {
|
|
|
1063
4541
|
}
|
|
1064
4542
|
async function typeInto(el, value, options = {}) {
|
|
1065
4543
|
const charDelayMs = options.charDelayMs ?? 35;
|
|
1066
|
-
el
|
|
4544
|
+
setNativeValue(el, "");
|
|
1067
4545
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1068
4546
|
for (const char of value) {
|
|
1069
|
-
el.value
|
|
4547
|
+
setNativeValue(el, el.value + char);
|
|
1070
4548
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1071
4549
|
if (charDelayMs > 0) {
|
|
1072
4550
|
await delay(charDelayMs);
|
|
@@ -1096,15 +4574,67 @@ async function focusWithFlash(el, options = {}) {
|
|
|
1096
4574
|
await delay(flashMs);
|
|
1097
4575
|
el.style.boxShadow = previousShadow;
|
|
1098
4576
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
4577
|
+
var RING = "0 0 0 3px rgba(79, 70, 229, 0.4)";
|
|
4578
|
+
function prefersReducedMotion() {
|
|
4579
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
4580
|
+
}
|
|
4581
|
+
function motionDelay(ms) {
|
|
4582
|
+
if (ms <= 0 || prefersReducedMotion()) {
|
|
4583
|
+
return Promise.resolve();
|
|
4584
|
+
}
|
|
4585
|
+
return delay(ms);
|
|
4586
|
+
}
|
|
4587
|
+
async function pressThenClick(el, options = {}) {
|
|
4588
|
+
const pressMs = options.pressMs ?? 140;
|
|
4589
|
+
const previousTransform = el.style.transform;
|
|
4590
|
+
const previousTransition = el.style.transition;
|
|
4591
|
+
const previousShadow = el.style.boxShadow;
|
|
4592
|
+
el.style.transition = "transform 80ms ease";
|
|
4593
|
+
el.style.transform = "scale(0.96)";
|
|
4594
|
+
el.style.boxShadow = RING;
|
|
4595
|
+
await motionDelay(pressMs);
|
|
4596
|
+
el.style.transform = previousTransform;
|
|
4597
|
+
el.style.transition = previousTransition;
|
|
4598
|
+
el.style.boxShadow = previousShadow;
|
|
4599
|
+
el.click();
|
|
4600
|
+
}
|
|
4601
|
+
function findOption(el, value) {
|
|
4602
|
+
for (const option of Array.from(el.options)) {
|
|
4603
|
+
if (option.value === value || option.text === value) {
|
|
4604
|
+
return option;
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
4607
|
+
return null;
|
|
4608
|
+
}
|
|
4609
|
+
async function selectOption(el, value, options = {}) {
|
|
4610
|
+
const option = findOption(el, value);
|
|
4611
|
+
if (option === null) {
|
|
4612
|
+
throw new Error(`no <option> matching "${value}"`);
|
|
1104
4613
|
}
|
|
4614
|
+
const highlightMs = options.highlightMs ?? 220;
|
|
4615
|
+
const previousOutline = el.style.outline;
|
|
4616
|
+
const previousOffset = el.style.outlineOffset;
|
|
4617
|
+
el.style.outline = `2px solid ${ACCENT}`;
|
|
4618
|
+
el.style.outlineOffset = "2px";
|
|
4619
|
+
await motionDelay(highlightMs);
|
|
4620
|
+
setNativeValue(el, option.value);
|
|
4621
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
4622
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
4623
|
+
el.style.outline = previousOutline;
|
|
4624
|
+
el.style.outlineOffset = previousOffset;
|
|
4625
|
+
}
|
|
4626
|
+
async function toggleControl(el, checked, options = {}) {
|
|
4627
|
+
const flashMs = options.flashMs ?? 200;
|
|
4628
|
+
const previousShadow = el.style.boxShadow;
|
|
4629
|
+
el.style.boxShadow = RING;
|
|
4630
|
+
await motionDelay(flashMs);
|
|
4631
|
+
setNativeChecked(el, checked);
|
|
4632
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
4633
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
4634
|
+
el.style.boxShadow = previousShadow;
|
|
1105
4635
|
}
|
|
1106
4636
|
|
|
1107
|
-
// src/dom_driver.ts
|
|
4637
|
+
// src/dom/dom_driver.ts
|
|
1108
4638
|
async function fillField(el, value, options = {}) {
|
|
1109
4639
|
scrollIntoCenterView(el);
|
|
1110
4640
|
await focusWithFlash(el, { flashMs: options.flashMs ?? 0 });
|
|
@@ -1114,18 +4644,30 @@ async function clickElement(el, options = {}) {
|
|
|
1114
4644
|
scrollIntoCenterView(el);
|
|
1115
4645
|
await highlightThenClick(el, options);
|
|
1116
4646
|
}
|
|
4647
|
+
async function pressButton(el, options = {}) {
|
|
4648
|
+
scrollIntoCenterView(el);
|
|
4649
|
+
await pressThenClick(el, options);
|
|
4650
|
+
}
|
|
4651
|
+
async function selectControl(el, value, options = {}) {
|
|
4652
|
+
scrollIntoCenterView(el);
|
|
4653
|
+
await selectOption(el, value, options);
|
|
4654
|
+
}
|
|
4655
|
+
async function toggleCheckbox(el, checked, options = {}) {
|
|
4656
|
+
scrollIntoCenterView(el);
|
|
4657
|
+
await toggleControl(el, checked, options);
|
|
4658
|
+
}
|
|
1117
4659
|
function setControlValue(el, value) {
|
|
1118
4660
|
if (el instanceof HTMLInputElement && el.type === "checkbox") {
|
|
1119
|
-
el
|
|
4661
|
+
setNativeChecked(el, Boolean(value));
|
|
1120
4662
|
} else {
|
|
1121
|
-
el
|
|
4663
|
+
setNativeValue(el, String(value));
|
|
1122
4664
|
}
|
|
1123
4665
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1124
4666
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
1125
4667
|
}
|
|
1126
4668
|
|
|
1127
4669
|
// src/version.ts
|
|
1128
|
-
var VERSION = "0.
|
|
4670
|
+
var VERSION = "0.2.1";
|
|
1129
4671
|
export {
|
|
1130
4672
|
AgUiChat,
|
|
1131
4673
|
AgUiClient,
|
|
@@ -1135,11 +4677,15 @@ export {
|
|
|
1135
4677
|
MESSAGE_ROLE,
|
|
1136
4678
|
SUBMIT_EVENT,
|
|
1137
4679
|
SessionStorageStore,
|
|
4680
|
+
TOGGLE_EVENT,
|
|
1138
4681
|
TOOL_CALL_STATUS,
|
|
4682
|
+
TOOL_DISPLAY,
|
|
1139
4683
|
ToolCallCard,
|
|
1140
4684
|
VERSION,
|
|
4685
|
+
X_CONFIRM_KEY,
|
|
1141
4686
|
X_DESTRUCTIVE_KEY,
|
|
1142
4687
|
X_NAVIGATES_KEY,
|
|
4688
|
+
X_SUMMARY_KEY,
|
|
1143
4689
|
clickElement,
|
|
1144
4690
|
createHttpAgent,
|
|
1145
4691
|
createPageMapContext,
|
|
@@ -1151,9 +4697,24 @@ export {
|
|
|
1151
4697
|
highlightThenClick,
|
|
1152
4698
|
isDestructive,
|
|
1153
4699
|
isNavigates,
|
|
4700
|
+
prefersReducedMotion,
|
|
4701
|
+
pressButton,
|
|
4702
|
+
pressThenClick,
|
|
4703
|
+
renderMarkdown,
|
|
1154
4704
|
requestConfirmation,
|
|
1155
4705
|
scrollIntoCenterView,
|
|
4706
|
+
selectControl,
|
|
4707
|
+
selectOption,
|
|
1156
4708
|
setControlValue,
|
|
4709
|
+
setNativeChecked,
|
|
4710
|
+
setNativeValue,
|
|
4711
|
+
toggleCheckbox,
|
|
4712
|
+
toggleControl,
|
|
1157
4713
|
typeInto
|
|
1158
4714
|
};
|
|
4715
|
+
/*! Bundled license information:
|
|
4716
|
+
|
|
4717
|
+
dompurify/dist/purify.es.mjs:
|
|
4718
|
+
(*! @license DOMPurify 3.4.7 | (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.7/LICENSE *)
|
|
4719
|
+
*/
|
|
1159
4720
|
//# sourceMappingURL=index.js.map
|