@changerawr/markdown 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2722 @@
1
+ "use strict";
2
+ var ChangerawrMarkdown = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __esm = (fn, res) => function __init() {
25
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
26
+ };
27
+ var __export = (target, all) => {
28
+ for (var name in all)
29
+ __defProp(target, name, { get: all[name], enumerable: true });
30
+ };
31
+ var __copyProps = (to, from, except, desc) => {
32
+ if (from && typeof from === "object" || typeof from === "function") {
33
+ for (let key of __getOwnPropNames(from))
34
+ if (!__hasOwnProp.call(to, key) && key !== except)
35
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
36
+ }
37
+ return to;
38
+ };
39
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
+
41
+ // node_modules/dompurify/dist/purify.es.mjs
42
+ var purify_es_exports = {};
43
+ __export(purify_es_exports, {
44
+ default: () => purify
45
+ });
46
+ function unapply(func) {
47
+ return function(thisArg) {
48
+ if (thisArg instanceof RegExp) {
49
+ thisArg.lastIndex = 0;
50
+ }
51
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
52
+ args[_key - 1] = arguments[_key];
53
+ }
54
+ return apply(func, thisArg, args);
55
+ };
56
+ }
57
+ function unconstruct(func) {
58
+ return function() {
59
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
60
+ args[_key2] = arguments[_key2];
61
+ }
62
+ return construct(func, args);
63
+ };
64
+ }
65
+ function addToSet(set, array) {
66
+ let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
67
+ if (setPrototypeOf) {
68
+ setPrototypeOf(set, null);
69
+ }
70
+ let l = array.length;
71
+ while (l--) {
72
+ let element = array[l];
73
+ if (typeof element === "string") {
74
+ const lcElement = transformCaseFunc(element);
75
+ if (lcElement !== element) {
76
+ if (!isFrozen(array)) {
77
+ array[l] = lcElement;
78
+ }
79
+ element = lcElement;
80
+ }
81
+ }
82
+ set[element] = true;
83
+ }
84
+ return set;
85
+ }
86
+ function cleanArray(array) {
87
+ for (let index = 0; index < array.length; index++) {
88
+ const isPropertyExist = objectHasOwnProperty(array, index);
89
+ if (!isPropertyExist) {
90
+ array[index] = null;
91
+ }
92
+ }
93
+ return array;
94
+ }
95
+ function clone(object) {
96
+ const newObject = create(null);
97
+ for (const [property, value] of entries(object)) {
98
+ const isPropertyExist = objectHasOwnProperty(object, property);
99
+ if (isPropertyExist) {
100
+ if (Array.isArray(value)) {
101
+ newObject[property] = cleanArray(value);
102
+ } else if (value && typeof value === "object" && value.constructor === Object) {
103
+ newObject[property] = clone(value);
104
+ } else {
105
+ newObject[property] = value;
106
+ }
107
+ }
108
+ }
109
+ return newObject;
110
+ }
111
+ function lookupGetter(object, prop) {
112
+ while (object !== null) {
113
+ const desc = getOwnPropertyDescriptor(object, prop);
114
+ if (desc) {
115
+ if (desc.get) {
116
+ return unapply(desc.get);
117
+ }
118
+ if (typeof desc.value === "function") {
119
+ return unapply(desc.value);
120
+ }
121
+ }
122
+ object = getPrototypeOf(object);
123
+ }
124
+ function fallbackValue() {
125
+ return null;
126
+ }
127
+ return fallbackValue;
128
+ }
129
+ function createDOMPurify() {
130
+ let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
131
+ const DOMPurify2 = (root) => createDOMPurify(root);
132
+ DOMPurify2.version = "3.2.6";
133
+ DOMPurify2.removed = [];
134
+ if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
135
+ DOMPurify2.isSupported = false;
136
+ return DOMPurify2;
137
+ }
138
+ let {
139
+ document: document2
140
+ } = window2;
141
+ const originalDocument = document2;
142
+ const currentScript = originalDocument.currentScript;
143
+ const {
144
+ DocumentFragment,
145
+ HTMLTemplateElement,
146
+ Node,
147
+ Element,
148
+ NodeFilter,
149
+ NamedNodeMap = window2.NamedNodeMap || window2.MozNamedAttrMap,
150
+ HTMLFormElement,
151
+ DOMParser,
152
+ trustedTypes
153
+ } = window2;
154
+ const ElementPrototype = Element.prototype;
155
+ const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
156
+ const remove = lookupGetter(ElementPrototype, "remove");
157
+ const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
158
+ const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
159
+ const getParentNode = lookupGetter(ElementPrototype, "parentNode");
160
+ if (typeof HTMLTemplateElement === "function") {
161
+ const template = document2.createElement("template");
162
+ if (template.content && template.content.ownerDocument) {
163
+ document2 = template.content.ownerDocument;
164
+ }
165
+ }
166
+ let trustedTypesPolicy;
167
+ let emptyHTML = "";
168
+ const {
169
+ implementation,
170
+ createNodeIterator,
171
+ createDocumentFragment,
172
+ getElementsByTagName
173
+ } = document2;
174
+ const {
175
+ importNode
176
+ } = originalDocument;
177
+ let hooks = _createHooksMap();
178
+ DOMPurify2.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
179
+ const {
180
+ MUSTACHE_EXPR: MUSTACHE_EXPR2,
181
+ ERB_EXPR: ERB_EXPR2,
182
+ TMPLIT_EXPR: TMPLIT_EXPR2,
183
+ DATA_ATTR: DATA_ATTR2,
184
+ ARIA_ATTR: ARIA_ATTR2,
185
+ IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA2,
186
+ ATTR_WHITESPACE: ATTR_WHITESPACE2,
187
+ CUSTOM_ELEMENT: CUSTOM_ELEMENT2
188
+ } = EXPRESSIONS;
189
+ let {
190
+ IS_ALLOWED_URI: IS_ALLOWED_URI$1
191
+ } = EXPRESSIONS;
192
+ let ALLOWED_TAGS2 = null;
193
+ const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
194
+ let ALLOWED_ATTR2 = null;
195
+ const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
196
+ let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
197
+ tagNameCheck: {
198
+ writable: true,
199
+ configurable: false,
200
+ enumerable: true,
201
+ value: null
202
+ },
203
+ attributeNameCheck: {
204
+ writable: true,
205
+ configurable: false,
206
+ enumerable: true,
207
+ value: null
208
+ },
209
+ allowCustomizedBuiltInElements: {
210
+ writable: true,
211
+ configurable: false,
212
+ enumerable: true,
213
+ value: false
214
+ }
215
+ }));
216
+ let FORBID_TAGS = null;
217
+ let FORBID_ATTR = null;
218
+ let ALLOW_ARIA_ATTR = true;
219
+ let ALLOW_DATA_ATTR = true;
220
+ let ALLOW_UNKNOWN_PROTOCOLS = false;
221
+ let ALLOW_SELF_CLOSE_IN_ATTR = true;
222
+ let SAFE_FOR_TEMPLATES = false;
223
+ let SAFE_FOR_XML = true;
224
+ let WHOLE_DOCUMENT = false;
225
+ let SET_CONFIG = false;
226
+ let FORCE_BODY = false;
227
+ let RETURN_DOM = false;
228
+ let RETURN_DOM_FRAGMENT = false;
229
+ let RETURN_TRUSTED_TYPE = false;
230
+ let SANITIZE_DOM = true;
231
+ let SANITIZE_NAMED_PROPS = false;
232
+ const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
233
+ let KEEP_CONTENT = true;
234
+ let IN_PLACE = false;
235
+ let USE_PROFILES = {};
236
+ let FORBID_CONTENTS = null;
237
+ 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"]);
238
+ let DATA_URI_TAGS = null;
239
+ const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
240
+ let URI_SAFE_ATTRIBUTES = null;
241
+ const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ["alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns"]);
242
+ const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
243
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
244
+ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
245
+ let NAMESPACE = HTML_NAMESPACE;
246
+ let IS_EMPTY_INPUT = false;
247
+ let ALLOWED_NAMESPACES = null;
248
+ const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
249
+ let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
250
+ let HTML_INTEGRATION_POINTS = addToSet({}, ["annotation-xml"]);
251
+ const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
252
+ let PARSER_MEDIA_TYPE = null;
253
+ const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
254
+ const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
255
+ let transformCaseFunc = null;
256
+ let CONFIG = null;
257
+ const formElement = document2.createElement("form");
258
+ const isRegexOrFunction = function isRegexOrFunction2(testValue) {
259
+ return testValue instanceof RegExp || testValue instanceof Function;
260
+ };
261
+ const _parseConfig = function _parseConfig2() {
262
+ let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
263
+ if (CONFIG && CONFIG === cfg) {
264
+ return;
265
+ }
266
+ if (!cfg || typeof cfg !== "object") {
267
+ cfg = {};
268
+ }
269
+ cfg = clone(cfg);
270
+ PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
271
+ SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
272
+ transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
273
+ ALLOWED_TAGS2 = objectHasOwnProperty(cfg, "ALLOWED_TAGS") ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
274
+ ALLOWED_ATTR2 = objectHasOwnProperty(cfg, "ALLOWED_ATTR") ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
275
+ ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, "ALLOWED_NAMESPACES") ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
276
+ URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
277
+ DATA_URI_TAGS = objectHasOwnProperty(cfg, "ADD_DATA_URI_TAGS") ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
278
+ FORBID_CONTENTS = objectHasOwnProperty(cfg, "FORBID_CONTENTS") ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
279
+ FORBID_TAGS = objectHasOwnProperty(cfg, "FORBID_TAGS") ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
280
+ FORBID_ATTR = objectHasOwnProperty(cfg, "FORBID_ATTR") ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
281
+ USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES : false;
282
+ ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
283
+ ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
284
+ ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
285
+ ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
286
+ SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
287
+ SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
288
+ WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
289
+ RETURN_DOM = cfg.RETURN_DOM || false;
290
+ RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
291
+ RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
292
+ FORCE_BODY = cfg.FORCE_BODY || false;
293
+ SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
294
+ SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
295
+ KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
296
+ IN_PLACE = cfg.IN_PLACE || false;
297
+ IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
298
+ NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
299
+ MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;
300
+ HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;
301
+ CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
302
+ if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
303
+ CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
304
+ }
305
+ if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
306
+ CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
307
+ }
308
+ if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === "boolean") {
309
+ CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
310
+ }
311
+ if (SAFE_FOR_TEMPLATES) {
312
+ ALLOW_DATA_ATTR = false;
313
+ }
314
+ if (RETURN_DOM_FRAGMENT) {
315
+ RETURN_DOM = true;
316
+ }
317
+ if (USE_PROFILES) {
318
+ ALLOWED_TAGS2 = addToSet({}, text);
319
+ ALLOWED_ATTR2 = [];
320
+ if (USE_PROFILES.html === true) {
321
+ addToSet(ALLOWED_TAGS2, html$1);
322
+ addToSet(ALLOWED_ATTR2, html);
323
+ }
324
+ if (USE_PROFILES.svg === true) {
325
+ addToSet(ALLOWED_TAGS2, svg$1);
326
+ addToSet(ALLOWED_ATTR2, svg);
327
+ addToSet(ALLOWED_ATTR2, xml);
328
+ }
329
+ if (USE_PROFILES.svgFilters === true) {
330
+ addToSet(ALLOWED_TAGS2, svgFilters);
331
+ addToSet(ALLOWED_ATTR2, svg);
332
+ addToSet(ALLOWED_ATTR2, xml);
333
+ }
334
+ if (USE_PROFILES.mathMl === true) {
335
+ addToSet(ALLOWED_TAGS2, mathMl$1);
336
+ addToSet(ALLOWED_ATTR2, mathMl);
337
+ addToSet(ALLOWED_ATTR2, xml);
338
+ }
339
+ }
340
+ if (cfg.ADD_TAGS) {
341
+ if (ALLOWED_TAGS2 === DEFAULT_ALLOWED_TAGS) {
342
+ ALLOWED_TAGS2 = clone(ALLOWED_TAGS2);
343
+ }
344
+ addToSet(ALLOWED_TAGS2, cfg.ADD_TAGS, transformCaseFunc);
345
+ }
346
+ if (cfg.ADD_ATTR) {
347
+ if (ALLOWED_ATTR2 === DEFAULT_ALLOWED_ATTR) {
348
+ ALLOWED_ATTR2 = clone(ALLOWED_ATTR2);
349
+ }
350
+ addToSet(ALLOWED_ATTR2, cfg.ADD_ATTR, transformCaseFunc);
351
+ }
352
+ if (cfg.ADD_URI_SAFE_ATTR) {
353
+ addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
354
+ }
355
+ if (cfg.FORBID_CONTENTS) {
356
+ if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
357
+ FORBID_CONTENTS = clone(FORBID_CONTENTS);
358
+ }
359
+ addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
360
+ }
361
+ if (KEEP_CONTENT) {
362
+ ALLOWED_TAGS2["#text"] = true;
363
+ }
364
+ if (WHOLE_DOCUMENT) {
365
+ addToSet(ALLOWED_TAGS2, ["html", "head", "body"]);
366
+ }
367
+ if (ALLOWED_TAGS2.table) {
368
+ addToSet(ALLOWED_TAGS2, ["tbody"]);
369
+ delete FORBID_TAGS.tbody;
370
+ }
371
+ if (cfg.TRUSTED_TYPES_POLICY) {
372
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") {
373
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
374
+ }
375
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
376
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
377
+ }
378
+ trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
379
+ emptyHTML = trustedTypesPolicy.createHTML("");
380
+ } else {
381
+ if (trustedTypesPolicy === void 0) {
382
+ trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
383
+ }
384
+ if (trustedTypesPolicy !== null && typeof emptyHTML === "string") {
385
+ emptyHTML = trustedTypesPolicy.createHTML("");
386
+ }
387
+ }
388
+ if (freeze) {
389
+ freeze(cfg);
390
+ }
391
+ CONFIG = cfg;
392
+ };
393
+ const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
394
+ const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
395
+ const _checkValidNamespace = function _checkValidNamespace2(element) {
396
+ let parent = getParentNode(element);
397
+ if (!parent || !parent.tagName) {
398
+ parent = {
399
+ namespaceURI: NAMESPACE,
400
+ tagName: "template"
401
+ };
402
+ }
403
+ const tagName = stringToLowerCase(element.tagName);
404
+ const parentTagName = stringToLowerCase(parent.tagName);
405
+ if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
406
+ return false;
407
+ }
408
+ if (element.namespaceURI === SVG_NAMESPACE) {
409
+ if (parent.namespaceURI === HTML_NAMESPACE) {
410
+ return tagName === "svg";
411
+ }
412
+ if (parent.namespaceURI === MATHML_NAMESPACE) {
413
+ return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
414
+ }
415
+ return Boolean(ALL_SVG_TAGS[tagName]);
416
+ }
417
+ if (element.namespaceURI === MATHML_NAMESPACE) {
418
+ if (parent.namespaceURI === HTML_NAMESPACE) {
419
+ return tagName === "math";
420
+ }
421
+ if (parent.namespaceURI === SVG_NAMESPACE) {
422
+ return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
423
+ }
424
+ return Boolean(ALL_MATHML_TAGS[tagName]);
425
+ }
426
+ if (element.namespaceURI === HTML_NAMESPACE) {
427
+ if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
428
+ return false;
429
+ }
430
+ if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
431
+ return false;
432
+ }
433
+ return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
434
+ }
435
+ if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
436
+ return true;
437
+ }
438
+ return false;
439
+ };
440
+ const _forceRemove = function _forceRemove2(node) {
441
+ arrayPush(DOMPurify2.removed, {
442
+ element: node
443
+ });
444
+ try {
445
+ getParentNode(node).removeChild(node);
446
+ } catch (_) {
447
+ remove(node);
448
+ }
449
+ };
450
+ const _removeAttribute = function _removeAttribute2(name, element) {
451
+ try {
452
+ arrayPush(DOMPurify2.removed, {
453
+ attribute: element.getAttributeNode(name),
454
+ from: element
455
+ });
456
+ } catch (_) {
457
+ arrayPush(DOMPurify2.removed, {
458
+ attribute: null,
459
+ from: element
460
+ });
461
+ }
462
+ element.removeAttribute(name);
463
+ if (name === "is") {
464
+ if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
465
+ try {
466
+ _forceRemove(element);
467
+ } catch (_) {
468
+ }
469
+ } else {
470
+ try {
471
+ element.setAttribute(name, "");
472
+ } catch (_) {
473
+ }
474
+ }
475
+ }
476
+ };
477
+ const _initDocument = function _initDocument2(dirty) {
478
+ let doc = null;
479
+ let leadingWhitespace = null;
480
+ if (FORCE_BODY) {
481
+ dirty = "<remove></remove>" + dirty;
482
+ } else {
483
+ const matches = stringMatch(dirty, /^[\r\n\t ]+/);
484
+ leadingWhitespace = matches && matches[0];
485
+ }
486
+ if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
487
+ dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
488
+ }
489
+ const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
490
+ if (NAMESPACE === HTML_NAMESPACE) {
491
+ try {
492
+ doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
493
+ } catch (_) {
494
+ }
495
+ }
496
+ if (!doc || !doc.documentElement) {
497
+ doc = implementation.createDocument(NAMESPACE, "template", null);
498
+ try {
499
+ doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
500
+ } catch (_) {
501
+ }
502
+ }
503
+ const body = doc.body || doc.documentElement;
504
+ if (dirty && leadingWhitespace) {
505
+ body.insertBefore(document2.createTextNode(leadingWhitespace), body.childNodes[0] || null);
506
+ }
507
+ if (NAMESPACE === HTML_NAMESPACE) {
508
+ return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
509
+ }
510
+ return WHOLE_DOCUMENT ? doc.documentElement : body;
511
+ };
512
+ const _createNodeIterator = function _createNodeIterator2(root) {
513
+ return createNodeIterator.call(
514
+ root.ownerDocument || root,
515
+ root,
516
+ // eslint-disable-next-line no-bitwise
517
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION,
518
+ null
519
+ );
520
+ };
521
+ const _isClobbered = function _isClobbered2(element) {
522
+ return element instanceof HTMLFormElement && (typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function");
523
+ };
524
+ const _isNode = function _isNode2(value) {
525
+ return typeof Node === "function" && value instanceof Node;
526
+ };
527
+ function _executeHooks(hooks2, currentNode, data) {
528
+ arrayForEach(hooks2, (hook) => {
529
+ hook.call(DOMPurify2, currentNode, data, CONFIG);
530
+ });
531
+ }
532
+ const _sanitizeElements = function _sanitizeElements2(currentNode) {
533
+ let content = null;
534
+ _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
535
+ if (_isClobbered(currentNode)) {
536
+ _forceRemove(currentNode);
537
+ return true;
538
+ }
539
+ const tagName = transformCaseFunc(currentNode.nodeName);
540
+ _executeHooks(hooks.uponSanitizeElement, currentNode, {
541
+ tagName,
542
+ allowedTags: ALLOWED_TAGS2
543
+ });
544
+ if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
545
+ _forceRemove(currentNode);
546
+ return true;
547
+ }
548
+ if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
549
+ _forceRemove(currentNode);
550
+ return true;
551
+ }
552
+ if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
553
+ _forceRemove(currentNode);
554
+ return true;
555
+ }
556
+ if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
557
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
558
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
559
+ return false;
560
+ }
561
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
562
+ return false;
563
+ }
564
+ }
565
+ if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
566
+ const parentNode = getParentNode(currentNode) || currentNode.parentNode;
567
+ const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
568
+ if (childNodes && parentNode) {
569
+ const childCount = childNodes.length;
570
+ for (let i = childCount - 1; i >= 0; --i) {
571
+ const childClone = cloneNode(childNodes[i], true);
572
+ childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
573
+ parentNode.insertBefore(childClone, getNextSibling(currentNode));
574
+ }
575
+ }
576
+ }
577
+ _forceRemove(currentNode);
578
+ return true;
579
+ }
580
+ if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
581
+ _forceRemove(currentNode);
582
+ return true;
583
+ }
584
+ if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
585
+ _forceRemove(currentNode);
586
+ return true;
587
+ }
588
+ if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
589
+ content = currentNode.textContent;
590
+ arrayForEach([MUSTACHE_EXPR2, ERB_EXPR2, TMPLIT_EXPR2], (expr) => {
591
+ content = stringReplace(content, expr, " ");
592
+ });
593
+ if (currentNode.textContent !== content) {
594
+ arrayPush(DOMPurify2.removed, {
595
+ element: currentNode.cloneNode()
596
+ });
597
+ currentNode.textContent = content;
598
+ }
599
+ }
600
+ _executeHooks(hooks.afterSanitizeElements, currentNode, null);
601
+ return false;
602
+ };
603
+ const _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value) {
604
+ if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) {
605
+ return false;
606
+ }
607
+ if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR2, lcName)) ;
608
+ else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR2, lcName)) ;
609
+ else if (!ALLOWED_ATTR2[lcName] || FORBID_ATTR[lcName]) {
610
+ if (
611
+ // First condition does a very basic check if a) it's basically a valid custom element tagname AND
612
+ // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
613
+ // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
614
+ _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)) || // Alternative, second condition checks if it's an `is`-attribute, AND
615
+ // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
616
+ 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))
617
+ ) ;
618
+ else {
619
+ return false;
620
+ }
621
+ } else if (URI_SAFE_ATTRIBUTES[lcName]) ;
622
+ else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE2, ""))) ;
623
+ else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) ;
624
+ else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA2, stringReplace(value, ATTR_WHITESPACE2, ""))) ;
625
+ else if (value) {
626
+ return false;
627
+ } else ;
628
+ return true;
629
+ };
630
+ const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
631
+ return tagName !== "annotation-xml" && stringMatch(tagName, CUSTOM_ELEMENT2);
632
+ };
633
+ const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
634
+ _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
635
+ const {
636
+ attributes
637
+ } = currentNode;
638
+ if (!attributes || _isClobbered(currentNode)) {
639
+ return;
640
+ }
641
+ const hookEvent = {
642
+ attrName: "",
643
+ attrValue: "",
644
+ keepAttr: true,
645
+ allowedAttributes: ALLOWED_ATTR2,
646
+ forceKeepAttr: void 0
647
+ };
648
+ let l = attributes.length;
649
+ while (l--) {
650
+ const attr = attributes[l];
651
+ const {
652
+ name,
653
+ namespaceURI,
654
+ value: attrValue
655
+ } = attr;
656
+ const lcName = transformCaseFunc(name);
657
+ const initValue = attrValue;
658
+ let value = name === "value" ? initValue : stringTrim(initValue);
659
+ hookEvent.attrName = lcName;
660
+ hookEvent.attrValue = value;
661
+ hookEvent.keepAttr = true;
662
+ hookEvent.forceKeepAttr = void 0;
663
+ _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
664
+ value = hookEvent.attrValue;
665
+ if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name")) {
666
+ _removeAttribute(name, currentNode);
667
+ value = SANITIZE_NAMED_PROPS_PREFIX + value;
668
+ }
669
+ if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
670
+ _removeAttribute(name, currentNode);
671
+ continue;
672
+ }
673
+ if (hookEvent.forceKeepAttr) {
674
+ continue;
675
+ }
676
+ if (!hookEvent.keepAttr) {
677
+ _removeAttribute(name, currentNode);
678
+ continue;
679
+ }
680
+ if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
681
+ _removeAttribute(name, currentNode);
682
+ continue;
683
+ }
684
+ if (SAFE_FOR_TEMPLATES) {
685
+ arrayForEach([MUSTACHE_EXPR2, ERB_EXPR2, TMPLIT_EXPR2], (expr) => {
686
+ value = stringReplace(value, expr, " ");
687
+ });
688
+ }
689
+ const lcTag = transformCaseFunc(currentNode.nodeName);
690
+ if (!_isValidAttribute(lcTag, lcName, value)) {
691
+ _removeAttribute(name, currentNode);
692
+ continue;
693
+ }
694
+ if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function") {
695
+ if (namespaceURI) ;
696
+ else {
697
+ switch (trustedTypes.getAttributeType(lcTag, lcName)) {
698
+ case "TrustedHTML": {
699
+ value = trustedTypesPolicy.createHTML(value);
700
+ break;
701
+ }
702
+ case "TrustedScriptURL": {
703
+ value = trustedTypesPolicy.createScriptURL(value);
704
+ break;
705
+ }
706
+ }
707
+ }
708
+ }
709
+ if (value !== initValue) {
710
+ try {
711
+ if (namespaceURI) {
712
+ currentNode.setAttributeNS(namespaceURI, name, value);
713
+ } else {
714
+ currentNode.setAttribute(name, value);
715
+ }
716
+ if (_isClobbered(currentNode)) {
717
+ _forceRemove(currentNode);
718
+ } else {
719
+ arrayPop(DOMPurify2.removed);
720
+ }
721
+ } catch (_) {
722
+ _removeAttribute(name, currentNode);
723
+ }
724
+ }
725
+ }
726
+ _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
727
+ };
728
+ const _sanitizeShadowDOM = function _sanitizeShadowDOM2(fragment) {
729
+ let shadowNode = null;
730
+ const shadowIterator = _createNodeIterator(fragment);
731
+ _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
732
+ while (shadowNode = shadowIterator.nextNode()) {
733
+ _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
734
+ _sanitizeElements(shadowNode);
735
+ _sanitizeAttributes(shadowNode);
736
+ if (shadowNode.content instanceof DocumentFragment) {
737
+ _sanitizeShadowDOM2(shadowNode.content);
738
+ }
739
+ }
740
+ _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
741
+ };
742
+ DOMPurify2.sanitize = function(dirty) {
743
+ let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
744
+ let body = null;
745
+ let importedNode = null;
746
+ let currentNode = null;
747
+ let returnNode = null;
748
+ IS_EMPTY_INPUT = !dirty;
749
+ if (IS_EMPTY_INPUT) {
750
+ dirty = "<!-->";
751
+ }
752
+ if (typeof dirty !== "string" && !_isNode(dirty)) {
753
+ if (typeof dirty.toString === "function") {
754
+ dirty = dirty.toString();
755
+ if (typeof dirty !== "string") {
756
+ throw typeErrorCreate("dirty is not a string, aborting");
757
+ }
758
+ } else {
759
+ throw typeErrorCreate("toString is not a function");
760
+ }
761
+ }
762
+ if (!DOMPurify2.isSupported) {
763
+ return dirty;
764
+ }
765
+ if (!SET_CONFIG) {
766
+ _parseConfig(cfg);
767
+ }
768
+ DOMPurify2.removed = [];
769
+ if (typeof dirty === "string") {
770
+ IN_PLACE = false;
771
+ }
772
+ if (IN_PLACE) {
773
+ if (dirty.nodeName) {
774
+ const tagName = transformCaseFunc(dirty.nodeName);
775
+ if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
776
+ throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
777
+ }
778
+ }
779
+ } else if (dirty instanceof Node) {
780
+ body = _initDocument("<!---->");
781
+ importedNode = body.ownerDocument.importNode(dirty, true);
782
+ if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") {
783
+ body = importedNode;
784
+ } else if (importedNode.nodeName === "HTML") {
785
+ body = importedNode;
786
+ } else {
787
+ body.appendChild(importedNode);
788
+ }
789
+ } else {
790
+ if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
791
+ dirty.indexOf("<") === -1) {
792
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
793
+ }
794
+ body = _initDocument(dirty);
795
+ if (!body) {
796
+ return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
797
+ }
798
+ }
799
+ if (body && FORCE_BODY) {
800
+ _forceRemove(body.firstChild);
801
+ }
802
+ const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
803
+ while (currentNode = nodeIterator.nextNode()) {
804
+ _sanitizeElements(currentNode);
805
+ _sanitizeAttributes(currentNode);
806
+ if (currentNode.content instanceof DocumentFragment) {
807
+ _sanitizeShadowDOM(currentNode.content);
808
+ }
809
+ }
810
+ if (IN_PLACE) {
811
+ return dirty;
812
+ }
813
+ if (RETURN_DOM) {
814
+ if (RETURN_DOM_FRAGMENT) {
815
+ returnNode = createDocumentFragment.call(body.ownerDocument);
816
+ while (body.firstChild) {
817
+ returnNode.appendChild(body.firstChild);
818
+ }
819
+ } else {
820
+ returnNode = body;
821
+ }
822
+ if (ALLOWED_ATTR2.shadowroot || ALLOWED_ATTR2.shadowrootmode) {
823
+ returnNode = importNode.call(originalDocument, returnNode, true);
824
+ }
825
+ return returnNode;
826
+ }
827
+ let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
828
+ if (WHOLE_DOCUMENT && ALLOWED_TAGS2["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
829
+ serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
830
+ }
831
+ if (SAFE_FOR_TEMPLATES) {
832
+ arrayForEach([MUSTACHE_EXPR2, ERB_EXPR2, TMPLIT_EXPR2], (expr) => {
833
+ serializedHTML = stringReplace(serializedHTML, expr, " ");
834
+ });
835
+ }
836
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
837
+ };
838
+ DOMPurify2.setConfig = function() {
839
+ let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
840
+ _parseConfig(cfg);
841
+ SET_CONFIG = true;
842
+ };
843
+ DOMPurify2.clearConfig = function() {
844
+ CONFIG = null;
845
+ SET_CONFIG = false;
846
+ };
847
+ DOMPurify2.isValidAttribute = function(tag, attr, value) {
848
+ if (!CONFIG) {
849
+ _parseConfig({});
850
+ }
851
+ const lcTag = transformCaseFunc(tag);
852
+ const lcName = transformCaseFunc(attr);
853
+ return _isValidAttribute(lcTag, lcName, value);
854
+ };
855
+ DOMPurify2.addHook = function(entryPoint, hookFunction) {
856
+ if (typeof hookFunction !== "function") {
857
+ return;
858
+ }
859
+ arrayPush(hooks[entryPoint], hookFunction);
860
+ };
861
+ DOMPurify2.removeHook = function(entryPoint, hookFunction) {
862
+ if (hookFunction !== void 0) {
863
+ const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
864
+ return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
865
+ }
866
+ return arrayPop(hooks[entryPoint]);
867
+ };
868
+ DOMPurify2.removeHooks = function(entryPoint) {
869
+ hooks[entryPoint] = [];
870
+ };
871
+ DOMPurify2.removeAllHooks = function() {
872
+ hooks = _createHooksMap();
873
+ };
874
+ return DOMPurify2;
875
+ }
876
+ var entries, setPrototypeOf, isFrozen, getPrototypeOf, getOwnPropertyDescriptor, freeze, seal, create, apply, construct, arrayForEach, arrayLastIndexOf, arrayPop, arrayPush, arraySplice, stringToLowerCase, stringToString, stringMatch, stringReplace, stringIndexOf, stringTrim, objectHasOwnProperty, regExpTest, typeErrorCreate, html$1, svg$1, svgFilters, svgDisallowed, mathMl$1, mathMlDisallowed, text, html, svg, mathMl, xml, MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR, DATA_ATTR, ARIA_ATTR, IS_ALLOWED_URI, IS_SCRIPT_OR_DATA, ATTR_WHITESPACE, DOCTYPE_NAME, CUSTOM_ELEMENT, EXPRESSIONS, NODE_TYPE, getGlobal, _createTrustedTypesPolicy, _createHooksMap, purify;
877
+ var init_purify_es = __esm({
878
+ "node_modules/dompurify/dist/purify.es.mjs"() {
879
+ "use strict";
880
+ ({
881
+ entries,
882
+ setPrototypeOf,
883
+ isFrozen,
884
+ getPrototypeOf,
885
+ getOwnPropertyDescriptor
886
+ } = Object);
887
+ ({
888
+ freeze,
889
+ seal,
890
+ create
891
+ } = Object);
892
+ ({
893
+ apply,
894
+ construct
895
+ } = typeof Reflect !== "undefined" && Reflect);
896
+ if (!freeze) {
897
+ freeze = function freeze2(x) {
898
+ return x;
899
+ };
900
+ }
901
+ if (!seal) {
902
+ seal = function seal2(x) {
903
+ return x;
904
+ };
905
+ }
906
+ if (!apply) {
907
+ apply = function apply2(fun, thisValue, args) {
908
+ return fun.apply(thisValue, args);
909
+ };
910
+ }
911
+ if (!construct) {
912
+ construct = function construct2(Func, args) {
913
+ return new Func(...args);
914
+ };
915
+ }
916
+ arrayForEach = unapply(Array.prototype.forEach);
917
+ arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
918
+ arrayPop = unapply(Array.prototype.pop);
919
+ arrayPush = unapply(Array.prototype.push);
920
+ arraySplice = unapply(Array.prototype.splice);
921
+ stringToLowerCase = unapply(String.prototype.toLowerCase);
922
+ stringToString = unapply(String.prototype.toString);
923
+ stringMatch = unapply(String.prototype.match);
924
+ stringReplace = unapply(String.prototype.replace);
925
+ stringIndexOf = unapply(String.prototype.indexOf);
926
+ stringTrim = unapply(String.prototype.trim);
927
+ objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
928
+ regExpTest = unapply(RegExp.prototype.test);
929
+ typeErrorCreate = unconstruct(TypeError);
930
+ 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", "section", "select", "shadow", "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"]);
931
+ svg$1 = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]);
932
+ 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"]);
933
+ 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"]);
934
+ 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"]);
935
+ mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]);
936
+ text = freeze(["#text"]);
937
+ html = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "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", "pattern", "placeholder", "playsinline", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "wrap", "xmlns", "slot"]);
938
+ 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", "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"]);
939
+ mathMl = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnsalign", "columnlines", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lspace", "lquote", "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"]);
940
+ xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]);
941
+ MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm);
942
+ ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
943
+ TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm);
944
+ DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
945
+ ARIA_ATTR = seal(/^aria-[\-\w]+$/);
946
+ IS_ALLOWED_URI = seal(
947
+ /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
948
+ // eslint-disable-line no-useless-escape
949
+ );
950
+ IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
951
+ ATTR_WHITESPACE = seal(
952
+ /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
953
+ // eslint-disable-line no-control-regex
954
+ );
955
+ DOCTYPE_NAME = seal(/^html$/i);
956
+ CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
957
+ EXPRESSIONS = /* @__PURE__ */ Object.freeze({
958
+ __proto__: null,
959
+ ARIA_ATTR,
960
+ ATTR_WHITESPACE,
961
+ CUSTOM_ELEMENT,
962
+ DATA_ATTR,
963
+ DOCTYPE_NAME,
964
+ ERB_EXPR,
965
+ IS_ALLOWED_URI,
966
+ IS_SCRIPT_OR_DATA,
967
+ MUSTACHE_EXPR,
968
+ TMPLIT_EXPR
969
+ });
970
+ NODE_TYPE = {
971
+ element: 1,
972
+ attribute: 2,
973
+ text: 3,
974
+ cdataSection: 4,
975
+ entityReference: 5,
976
+ // Deprecated
977
+ entityNode: 6,
978
+ // Deprecated
979
+ progressingInstruction: 7,
980
+ comment: 8,
981
+ document: 9,
982
+ documentType: 10,
983
+ documentFragment: 11,
984
+ notation: 12
985
+ // Deprecated
986
+ };
987
+ getGlobal = function getGlobal2() {
988
+ return typeof window === "undefined" ? null : window;
989
+ };
990
+ _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, purifyHostElement) {
991
+ if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") {
992
+ return null;
993
+ }
994
+ let suffix = null;
995
+ const ATTR_NAME = "data-tt-policy-suffix";
996
+ if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
997
+ suffix = purifyHostElement.getAttribute(ATTR_NAME);
998
+ }
999
+ const policyName = "dompurify" + (suffix ? "#" + suffix : "");
1000
+ try {
1001
+ return trustedTypes.createPolicy(policyName, {
1002
+ createHTML(html2) {
1003
+ return html2;
1004
+ },
1005
+ createScriptURL(scriptUrl) {
1006
+ return scriptUrl;
1007
+ }
1008
+ });
1009
+ } catch (_) {
1010
+ console.warn("TrustedTypes policy " + policyName + " could not be created.");
1011
+ return null;
1012
+ }
1013
+ };
1014
+ _createHooksMap = function _createHooksMap2() {
1015
+ return {
1016
+ afterSanitizeAttributes: [],
1017
+ afterSanitizeElements: [],
1018
+ afterSanitizeShadowDOM: [],
1019
+ beforeSanitizeAttributes: [],
1020
+ beforeSanitizeElements: [],
1021
+ beforeSanitizeShadowDOM: [],
1022
+ uponSanitizeAttribute: [],
1023
+ uponSanitizeElement: [],
1024
+ uponSanitizeShadowNode: []
1025
+ };
1026
+ };
1027
+ purify = createDOMPurify();
1028
+ }
1029
+ });
1030
+
1031
+ // src/standalone.ts
1032
+ var standalone_exports = {};
1033
+ __export(standalone_exports, {
1034
+ ChangerawrMarkdown: () => ChangerawrMarkdown,
1035
+ createCumEngine: () => createCumEngine,
1036
+ default: () => standalone_default,
1037
+ parseCum: () => parseCum,
1038
+ renderCum: () => renderCum,
1039
+ renderCumToHtml: () => renderCumToHtml,
1040
+ renderCumToJson: () => renderCumToJson,
1041
+ renderCumToTailwind: () => renderCumToTailwind
1042
+ });
1043
+
1044
+ // src/parser.ts
1045
+ var MarkdownParser = class {
1046
+ constructor(config) {
1047
+ this.rules = [];
1048
+ this.warnings = [];
1049
+ this.config = __spreadValues({
1050
+ debugMode: false,
1051
+ maxIterations: 1e4,
1052
+ validateMarkdown: false
1053
+ }, config);
1054
+ }
1055
+ addRule(rule) {
1056
+ this.rules.push(rule);
1057
+ this.rules.sort((a, b) => {
1058
+ const aFeatureExtension = ["alert", "button", "embed"].includes(a.name);
1059
+ const bFeatureExtension = ["alert", "button", "embed"].includes(b.name);
1060
+ if (aFeatureExtension && !bFeatureExtension) return -1;
1061
+ if (!aFeatureExtension && bFeatureExtension) return 1;
1062
+ const aCoreExtension = ["text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(a.name);
1063
+ const bCoreExtension = ["text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(b.name);
1064
+ if (aCoreExtension && !bCoreExtension) return -1;
1065
+ if (!aCoreExtension && bCoreExtension) return 1;
1066
+ if (a.name === "image" && b.name === "link") return -1;
1067
+ if (a.name === "link" && b.name === "image") return 1;
1068
+ if (a.name === "task-item" && b.name === "list-item") return -1;
1069
+ if (a.name === "list-item" && b.name === "task-item") return 1;
1070
+ if (a.name === "codeblock" && b.name === "code") return -1;
1071
+ if (a.name === "code" && b.name === "codeblock") return 1;
1072
+ if (a.name === "bold" && b.name === "italic") return -1;
1073
+ if (a.name === "italic" && b.name === "bold") return 1;
1074
+ return a.name.localeCompare(b.name);
1075
+ });
1076
+ }
1077
+ hasRule(name) {
1078
+ return this.rules.some((rule) => rule.name === name);
1079
+ }
1080
+ parse(markdown2) {
1081
+ var _a;
1082
+ this.warnings = [];
1083
+ if (!markdown2.trim()) {
1084
+ return [];
1085
+ }
1086
+ if (this.rules.length === 0) {
1087
+ this.warnings.push("No parse rules registered - consider using CoreExtensions");
1088
+ return [{
1089
+ type: "text",
1090
+ content: markdown2,
1091
+ raw: markdown2
1092
+ }];
1093
+ }
1094
+ const processedMarkdown = this.preprocessMarkdown(markdown2);
1095
+ const tokens = [];
1096
+ let remaining = processedMarkdown;
1097
+ let iterationCount = 0;
1098
+ const maxIterations = this.config.maxIterations || 1e4;
1099
+ while (remaining.length > 0 && iterationCount < maxIterations) {
1100
+ iterationCount++;
1101
+ let matched = false;
1102
+ let bestMatch = null;
1103
+ for (const rule of this.rules) {
1104
+ try {
1105
+ const pattern = new RegExp(rule.pattern.source, rule.pattern.flags.replace("g", ""));
1106
+ const match = remaining.match(pattern);
1107
+ if (match && match.index !== void 0) {
1108
+ const priority = match.index === 0 ? 1e3 : 1e3 - match.index;
1109
+ if (!bestMatch || priority > bestMatch.priority || priority === bestMatch.priority && match.index < (bestMatch.match.index || 0)) {
1110
+ bestMatch = { rule, match, priority };
1111
+ }
1112
+ }
1113
+ } catch (error) {
1114
+ if (this.config.debugMode) {
1115
+ console.warn(`Error in rule "${rule.name}":`, error);
1116
+ }
1117
+ }
1118
+ }
1119
+ if (bestMatch && bestMatch.match.index !== void 0) {
1120
+ const { rule, match } = bestMatch;
1121
+ const matchIndex = match.index;
1122
+ if (matchIndex > 0) {
1123
+ const textBefore = remaining.slice(0, matchIndex);
1124
+ tokens.push({
1125
+ type: "text",
1126
+ content: textBefore,
1127
+ raw: textBefore
1128
+ });
1129
+ remaining = remaining.slice(matchIndex);
1130
+ continue;
1131
+ }
1132
+ try {
1133
+ const token = rule.render(match);
1134
+ tokens.push(__spreadProps(__spreadValues({}, token), {
1135
+ raw: match[0] || ""
1136
+ }));
1137
+ remaining = remaining.slice(((_a = match[0]) == null ? void 0 : _a.length) || 0);
1138
+ matched = true;
1139
+ } catch (error) {
1140
+ const errorMessage = error instanceof Error ? error.message : String(error);
1141
+ this.warnings.push(`Failed to render ${rule.name}: ${errorMessage}`);
1142
+ const char = remaining[0];
1143
+ if (char) {
1144
+ tokens.push({
1145
+ type: "text",
1146
+ content: char,
1147
+ raw: char
1148
+ });
1149
+ remaining = remaining.slice(1);
1150
+ }
1151
+ }
1152
+ }
1153
+ if (!matched) {
1154
+ const char = remaining[0];
1155
+ if (char) {
1156
+ tokens.push({
1157
+ type: "text",
1158
+ content: char,
1159
+ raw: char
1160
+ });
1161
+ remaining = remaining.slice(1);
1162
+ }
1163
+ }
1164
+ }
1165
+ if (iterationCount >= maxIterations) {
1166
+ this.warnings.push("Parser hit maximum iterations - possible infinite loop detected");
1167
+ }
1168
+ const processedTokens = this.postProcessTokens(tokens);
1169
+ return processedTokens;
1170
+ }
1171
+ getWarnings() {
1172
+ return [...this.warnings];
1173
+ }
1174
+ getConfig() {
1175
+ return __spreadValues({}, this.config);
1176
+ }
1177
+ updateConfig(config) {
1178
+ this.config = __spreadValues(__spreadValues({}, this.config), config);
1179
+ }
1180
+ setDebugMode(enabled) {
1181
+ this.config.debugMode = enabled;
1182
+ }
1183
+ clearWarnings() {
1184
+ this.warnings = [];
1185
+ }
1186
+ preprocessMarkdown(markdown2) {
1187
+ if (this.config.validateMarkdown) {
1188
+ this.validateMarkdown(markdown2);
1189
+ }
1190
+ return markdown2.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
1191
+ }
1192
+ validateMarkdown(markdown2) {
1193
+ const boldMatches = markdown2.match(/\*\*/g);
1194
+ if (boldMatches && boldMatches.length % 2 !== 0) {
1195
+ this.warnings.push("Unclosed bold markers (**) detected - some bold formatting may not work");
1196
+ }
1197
+ const italicMatches = markdown2.match(new RegExp("(?<!\\*)\\*(?!\\*)", "g"));
1198
+ if (italicMatches && italicMatches.length % 2 !== 0) {
1199
+ this.warnings.push("Unclosed italic markers (*) detected - some italic formatting may not work");
1200
+ }
1201
+ const codeBlockMatches = markdown2.match(/```/g);
1202
+ if (codeBlockMatches && codeBlockMatches.length % 2 !== 0) {
1203
+ this.warnings.push("Unclosed code blocks (```) detected - some code formatting may not work");
1204
+ }
1205
+ const inlineCodeMatches = markdown2.match(/`/g);
1206
+ if (inlineCodeMatches && inlineCodeMatches.length % 2 !== 0) {
1207
+ this.warnings.push("Unclosed inline code markers (`) detected - some code formatting may not work");
1208
+ }
1209
+ }
1210
+ postProcessTokens(tokens) {
1211
+ const processed = [];
1212
+ let i = 0;
1213
+ while (i < tokens.length) {
1214
+ const token = tokens[i];
1215
+ if (token && token.type === "text") {
1216
+ let textContent = token.content || token.raw || "";
1217
+ let j = i + 1;
1218
+ while (j < tokens.length && tokens[j] && tokens[j].type === "text") {
1219
+ const nextToken = tokens[j];
1220
+ textContent += nextToken.content || nextToken.raw || "";
1221
+ j++;
1222
+ }
1223
+ if (textContent.trim().length > 0 || textContent.includes("\n")) {
1224
+ processed.push({
1225
+ type: "text",
1226
+ content: textContent,
1227
+ raw: textContent
1228
+ });
1229
+ }
1230
+ i = j;
1231
+ } else if (token) {
1232
+ processed.push(token);
1233
+ i++;
1234
+ } else {
1235
+ i++;
1236
+ }
1237
+ }
1238
+ return processed;
1239
+ }
1240
+ };
1241
+
1242
+ // src/utils.ts
1243
+ var DOMPurify = {
1244
+ sanitize: (html2) => html2
1245
+ };
1246
+ if (typeof window !== "undefined") {
1247
+ Promise.resolve().then(() => (init_purify_es(), purify_es_exports)).then((module) => {
1248
+ DOMPurify = module.default;
1249
+ }).catch((err) => {
1250
+ console.error("Failed to load DOMPurify", err);
1251
+ });
1252
+ }
1253
+ var ALLOWED_TAGS = [
1254
+ // Standard HTML
1255
+ "h1",
1256
+ "h2",
1257
+ "h3",
1258
+ "h4",
1259
+ "h5",
1260
+ "h6",
1261
+ "p",
1262
+ "br",
1263
+ "strong",
1264
+ "em",
1265
+ "del",
1266
+ "ins",
1267
+ "a",
1268
+ "img",
1269
+ "ul",
1270
+ "ol",
1271
+ "li",
1272
+ "blockquote",
1273
+ "pre",
1274
+ "code",
1275
+ "table",
1276
+ "thead",
1277
+ "tbody",
1278
+ "tr",
1279
+ "th",
1280
+ "td",
1281
+ "div",
1282
+ "span",
1283
+ "sup",
1284
+ "sub",
1285
+ "hr",
1286
+ "input",
1287
+ // Embeds
1288
+ "iframe",
1289
+ "embed",
1290
+ "object",
1291
+ "param",
1292
+ "video",
1293
+ "audio",
1294
+ "source",
1295
+ // SVG
1296
+ "svg",
1297
+ "path",
1298
+ "polyline",
1299
+ "line",
1300
+ "circle",
1301
+ "rect",
1302
+ "g",
1303
+ "defs",
1304
+ "use",
1305
+ // Form elements
1306
+ "form",
1307
+ "fieldset",
1308
+ "legend",
1309
+ "label",
1310
+ "select",
1311
+ "option",
1312
+ "textarea",
1313
+ "button"
1314
+ ];
1315
+ var ALLOWED_ATTR = [
1316
+ // Standard attributes
1317
+ "href",
1318
+ "title",
1319
+ "alt",
1320
+ "src",
1321
+ "class",
1322
+ "id",
1323
+ "target",
1324
+ "rel",
1325
+ "type",
1326
+ "checked",
1327
+ "disabled",
1328
+ "loading",
1329
+ "width",
1330
+ "height",
1331
+ "style",
1332
+ "role",
1333
+ // Iframe attributes
1334
+ "frameborder",
1335
+ "allowfullscreen",
1336
+ "allow",
1337
+ "sandbox",
1338
+ "scrolling",
1339
+ "allowtransparency",
1340
+ "name",
1341
+ "seamless",
1342
+ "srcdoc",
1343
+ // Data attributes (for embeds)
1344
+ "data-*",
1345
+ // SVG attributes
1346
+ "viewBox",
1347
+ "fill",
1348
+ "stroke",
1349
+ "stroke-width",
1350
+ "stroke-linecap",
1351
+ "stroke-linejoin",
1352
+ "d",
1353
+ "points",
1354
+ "x1",
1355
+ "y1",
1356
+ "x2",
1357
+ "y2",
1358
+ "cx",
1359
+ "cy",
1360
+ "r",
1361
+ "rx",
1362
+ "ry",
1363
+ // Media attributes
1364
+ "autoplay",
1365
+ "controls",
1366
+ "loop",
1367
+ "muted",
1368
+ "preload",
1369
+ "poster",
1370
+ // Form attributes
1371
+ "value",
1372
+ "placeholder",
1373
+ "required",
1374
+ "readonly",
1375
+ "maxlength",
1376
+ "minlength",
1377
+ "max",
1378
+ "min",
1379
+ "step",
1380
+ "pattern",
1381
+ "autocomplete",
1382
+ "autofocus"
1383
+ ];
1384
+ function escapeHtml(text2) {
1385
+ const map = {
1386
+ "&": "&amp;",
1387
+ "<": "&lt;",
1388
+ ">": "&gt;",
1389
+ '"': "&quot;",
1390
+ "'": "&#39;"
1391
+ };
1392
+ return text2.replace(/[&<>"']/g, (char) => map[char] || char);
1393
+ }
1394
+ function generateId(text2) {
1395
+ return text2.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").trim();
1396
+ }
1397
+ function sanitizeHtml(html2) {
1398
+ try {
1399
+ if (html2.includes("codepen.io/") || html2.includes("youtube.com/embed/")) {
1400
+ return html2;
1401
+ }
1402
+ if (typeof (DOMPurify == null ? void 0 : DOMPurify.sanitize) === "function") {
1403
+ const sanitized = DOMPurify.sanitize(html2, {
1404
+ ALLOWED_TAGS,
1405
+ ALLOWED_ATTR,
1406
+ ALLOW_DATA_ATTR: true,
1407
+ ALLOW_UNKNOWN_PROTOCOLS: false,
1408
+ SAFE_FOR_TEMPLATES: false,
1409
+ WHOLE_DOCUMENT: false,
1410
+ RETURN_DOM: false,
1411
+ RETURN_DOM_FRAGMENT: false,
1412
+ FORCE_BODY: false,
1413
+ SANITIZE_DOM: false,
1414
+ SANITIZE_NAMED_PROPS: false,
1415
+ FORBID_ATTR: ["onload", "onerror", "onclick", "onmouseover", "onmouseout", "onfocus", "onblur"],
1416
+ ADD_TAGS: ["iframe", "embed", "object", "param"],
1417
+ ADD_ATTR: [
1418
+ "allow",
1419
+ "allowfullscreen",
1420
+ "frameborder",
1421
+ "scrolling",
1422
+ "allowtransparency",
1423
+ "sandbox",
1424
+ "loading",
1425
+ "style",
1426
+ "title",
1427
+ "name",
1428
+ "seamless",
1429
+ "srcdoc"
1430
+ ],
1431
+ ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
1432
+ });
1433
+ if (sanitized.length < html2.length * 0.7) {
1434
+ return basicSanitize(html2);
1435
+ }
1436
+ return sanitized;
1437
+ }
1438
+ return basicSanitize(html2);
1439
+ } catch (error) {
1440
+ console.error("Sanitization failed:", error);
1441
+ return basicSanitize(html2);
1442
+ }
1443
+ }
1444
+ function basicSanitize(html2) {
1445
+ return html2.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/on\w+\s*=\s*"[^"]*"/gi, "").replace(/on\w+\s*=\s*'[^']*'/gi, "").replace(/javascript:/gi, "");
1446
+ }
1447
+ function extractDomain(url) {
1448
+ try {
1449
+ return new URL(url).hostname;
1450
+ } catch (e) {
1451
+ return url;
1452
+ }
1453
+ }
1454
+ function parseOptions(options) {
1455
+ const parsed = {};
1456
+ if (!options) return parsed;
1457
+ options.split(",").forEach((option) => {
1458
+ const [key, value] = option.split(":").map((s) => s.trim());
1459
+ if (key && value) {
1460
+ parsed[key] = value;
1461
+ }
1462
+ });
1463
+ return parsed;
1464
+ }
1465
+
1466
+ // src/renderer.ts
1467
+ var MarkdownRenderer = class {
1468
+ constructor(config) {
1469
+ this.rules = /* @__PURE__ */ new Map();
1470
+ this.warnings = [];
1471
+ this.config = __spreadValues({
1472
+ format: "tailwind",
1473
+ sanitize: true,
1474
+ allowUnsafeHtml: false,
1475
+ debugMode: false
1476
+ }, config);
1477
+ }
1478
+ addRule(rule) {
1479
+ this.rules.set(rule.type, rule);
1480
+ }
1481
+ hasRule(type) {
1482
+ return this.rules.has(type);
1483
+ }
1484
+ render(tokens) {
1485
+ this.warnings = [];
1486
+ const tokensWithFormat = tokens.map((token) => __spreadProps(__spreadValues({}, token), {
1487
+ attributes: __spreadProps(__spreadValues({}, token.attributes), {
1488
+ format: this.config.format
1489
+ })
1490
+ }));
1491
+ const htmlParts = tokensWithFormat.map((token) => this.renderToken(token));
1492
+ const combinedHtml = htmlParts.join("");
1493
+ if (this.config.sanitize && !this.config.allowUnsafeHtml) {
1494
+ return sanitizeHtml(combinedHtml);
1495
+ }
1496
+ return combinedHtml;
1497
+ }
1498
+ renderToken(token) {
1499
+ const rule = this.rules.get(token.type);
1500
+ if (rule) {
1501
+ try {
1502
+ return rule.render(token);
1503
+ } catch (error) {
1504
+ const errorMessage = error instanceof Error ? error.message : String(error);
1505
+ this.warnings.push(`Render error for ${token.type}: ${errorMessage}`);
1506
+ return this.createErrorBlock(`Render error for ${token.type}: ${errorMessage}`);
1507
+ }
1508
+ }
1509
+ if (this.config.debugMode) {
1510
+ return this.createDebugBlock(token);
1511
+ }
1512
+ return escapeHtml(token.content || token.raw || "");
1513
+ }
1514
+ createErrorBlock(message) {
1515
+ if (this.config.format === "html") {
1516
+ return `<div style="background-color: #fee; border: 1px solid #fcc; color: #c66; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;">
1517
+ <strong>Render Error:</strong> ${escapeHtml(message)}
1518
+ </div>`;
1519
+ }
1520
+ return `<div class="bg-red-100 border border-red-300 text-red-800 p-2 rounded text-sm mb-2">
1521
+ <strong>Render Error:</strong> ${escapeHtml(message)}
1522
+ </div>`;
1523
+ }
1524
+ createDebugBlock(token) {
1525
+ if (this.config.format === "html") {
1526
+ return `<div style="background-color: #fffbf0; border: 1px solid #fed; color: #b8860b; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;">
1527
+ <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>
1528
+ <strong>Content:</strong> ${escapeHtml(token.content || token.raw || "")}
1529
+ </div>`;
1530
+ }
1531
+ return `<div class="bg-yellow-100 border border-yellow-300 text-yellow-800 p-2 rounded text-sm mb-2">
1532
+ <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>
1533
+ <strong>Content:</strong> ${escapeHtml(token.content || token.raw || "")}
1534
+ </div>`;
1535
+ }
1536
+ getWarnings() {
1537
+ return [...this.warnings];
1538
+ }
1539
+ getConfig() {
1540
+ return __spreadValues({}, this.config);
1541
+ }
1542
+ updateConfig(config) {
1543
+ this.config = __spreadValues(__spreadValues({}, this.config), config);
1544
+ }
1545
+ setDebugMode(enabled) {
1546
+ this.config.debugMode = enabled;
1547
+ }
1548
+ clearWarnings() {
1549
+ this.warnings = [];
1550
+ }
1551
+ };
1552
+
1553
+ // src/extensions/core/blockquote.ts
1554
+ var BlockquoteExtension = {
1555
+ name: "blockquote",
1556
+ parseRules: [
1557
+ {
1558
+ name: "blockquote",
1559
+ pattern: /^>\s+(.+)$/m,
1560
+ render: (match) => ({
1561
+ type: "blockquote",
1562
+ content: match[1] || "",
1563
+ raw: match[0] || ""
1564
+ })
1565
+ }
1566
+ ],
1567
+ renderRules: [
1568
+ {
1569
+ type: "blockquote",
1570
+ render: (token) => {
1571
+ var _a;
1572
+ const content = escapeHtml(token.content);
1573
+ const format = ((_a = token.attributes) == null ? void 0 : _a.format) || "html";
1574
+ if (format === "html") {
1575
+ return `<blockquote style="border-left: 2px solid #d1d5db; padding: 8px 0 8px 16px; margin: 16px 0; font-style: italic; color: #6b7280;">${content}</blockquote>`;
1576
+ }
1577
+ return `<blockquote class="pl-4 py-2 border-l-2 border-border italic text-muted-foreground my-4">${content}</blockquote>`;
1578
+ }
1579
+ }
1580
+ ]
1581
+ };
1582
+
1583
+ // src/extensions/core/breaks.ts
1584
+ var LineBreakExtension = {
1585
+ name: "line-break",
1586
+ parseRules: [
1587
+ {
1588
+ name: "hard-break-backslash",
1589
+ pattern: /\\\s*\n/,
1590
+ render: (match) => ({
1591
+ type: "line-break",
1592
+ content: "",
1593
+ raw: match[0] || ""
1594
+ })
1595
+ },
1596
+ {
1597
+ name: "hard-break-spaces",
1598
+ pattern: / +\n/,
1599
+ render: (match) => ({
1600
+ type: "line-break",
1601
+ content: "",
1602
+ raw: match[0] || ""
1603
+ })
1604
+ }
1605
+ ],
1606
+ renderRules: [
1607
+ {
1608
+ type: "line-break",
1609
+ render: () => "<br>"
1610
+ },
1611
+ {
1612
+ type: "paragraph-break",
1613
+ render: () => "</p><p>"
1614
+ },
1615
+ {
1616
+ type: "soft-break",
1617
+ render: (token) => token.content || " "
1618
+ }
1619
+ ]
1620
+ };
1621
+
1622
+ // src/extensions/core/code.ts
1623
+ var InlineCodeExtension = {
1624
+ name: "inline-code",
1625
+ parseRules: [
1626
+ {
1627
+ name: "code",
1628
+ pattern: /`([^`]+)`/,
1629
+ render: (match) => ({
1630
+ type: "code",
1631
+ content: match[1] || "",
1632
+ raw: match[0] || ""
1633
+ })
1634
+ }
1635
+ ],
1636
+ renderRules: [
1637
+ {
1638
+ type: "code",
1639
+ render: (token) => {
1640
+ var _a;
1641
+ const content = escapeHtml(token.content);
1642
+ const format = (_a = token.attributes) == null ? void 0 : _a.format;
1643
+ if (format === "html") {
1644
+ return `<code style="background-color: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.875rem;">${content}</code>`;
1645
+ }
1646
+ return `<code class="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">${content}</code>`;
1647
+ }
1648
+ }
1649
+ ]
1650
+ };
1651
+ var CodeBlockExtension = {
1652
+ name: "codeblock",
1653
+ parseRules: [
1654
+ {
1655
+ name: "codeblock",
1656
+ pattern: /```(\w+)?\s*\n([\s\S]*?)\n```/,
1657
+ render: (match) => ({
1658
+ type: "codeblock",
1659
+ content: match[2] || "",
1660
+ raw: match[0] || "",
1661
+ attributes: {
1662
+ language: match[1] || "text"
1663
+ }
1664
+ })
1665
+ }
1666
+ ],
1667
+ renderRules: [
1668
+ {
1669
+ type: "codeblock",
1670
+ render: (token) => {
1671
+ var _a, _b;
1672
+ const language = ((_a = token.attributes) == null ? void 0 : _a.language) || "text";
1673
+ const escapedCode = escapeHtml(token.content);
1674
+ const format = ((_b = token.attributes) == null ? void 0 : _b.format) || "html";
1675
+ if (format === "html") {
1676
+ return `<pre style="background-color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; margin: 16px 0;"><code class="language-${escapeHtml(language)}">${escapedCode}</code></pre>`;
1677
+ }
1678
+ return `<pre class="bg-muted p-4 rounded-md overflow-x-auto my-4"><code class="language-${escapeHtml(language)}">${escapedCode}</code></pre>`;
1679
+ }
1680
+ }
1681
+ ]
1682
+ };
1683
+
1684
+ // src/extensions/core/emphasis.ts
1685
+ var BoldExtension = {
1686
+ name: "bold",
1687
+ parseRules: [
1688
+ {
1689
+ name: "bold",
1690
+ pattern: /\*\*((?:(?!\*\*).)+)\*\*/,
1691
+ render: (match) => ({
1692
+ type: "bold",
1693
+ content: match[1] || "",
1694
+ raw: match[0] || ""
1695
+ })
1696
+ }
1697
+ ],
1698
+ renderRules: [
1699
+ {
1700
+ type: "bold",
1701
+ render: (token) => {
1702
+ var _a;
1703
+ const content = escapeHtml(token.content);
1704
+ const format = (_a = token.attributes) == null ? void 0 : _a.format;
1705
+ if (format === "html") {
1706
+ return `<strong>${content}</strong>`;
1707
+ }
1708
+ return `<strong class="font-bold">${content}</strong>`;
1709
+ }
1710
+ }
1711
+ ]
1712
+ };
1713
+ var ItalicExtension = {
1714
+ name: "italic",
1715
+ parseRules: [
1716
+ {
1717
+ name: "italic",
1718
+ pattern: /\*((?:(?!\*).)+)\*/,
1719
+ render: (match) => ({
1720
+ type: "italic",
1721
+ content: match[1] || "",
1722
+ raw: match[0] || ""
1723
+ })
1724
+ }
1725
+ ],
1726
+ renderRules: [
1727
+ {
1728
+ type: "italic",
1729
+ render: (token) => {
1730
+ var _a;
1731
+ const content = escapeHtml(token.content);
1732
+ const format = (_a = token.attributes) == null ? void 0 : _a.format;
1733
+ if (format === "html") {
1734
+ return `<em>${content}</em>`;
1735
+ }
1736
+ return `<em class="italic">${content}</em>`;
1737
+ }
1738
+ }
1739
+ ]
1740
+ };
1741
+
1742
+ // src/extensions/core/heading.ts
1743
+ var HeadingExtension = {
1744
+ name: "heading",
1745
+ parseRules: [
1746
+ {
1747
+ name: "heading",
1748
+ pattern: /^(#{1,6})\s+(.+)$/m,
1749
+ render: (match) => {
1750
+ var _a, _b;
1751
+ return {
1752
+ type: "heading",
1753
+ content: ((_a = match[2]) == null ? void 0 : _a.trim()) || "",
1754
+ raw: match[0] || "",
1755
+ attributes: {
1756
+ level: String(((_b = match[1]) == null ? void 0 : _b.length) || 1)
1757
+ }
1758
+ };
1759
+ }
1760
+ }
1761
+ ],
1762
+ renderRules: [
1763
+ {
1764
+ type: "heading",
1765
+ render: (token) => {
1766
+ var _a, _b;
1767
+ const level = parseInt(((_a = token.attributes) == null ? void 0 : _a.level) || "1");
1768
+ const text2 = token.content;
1769
+ const id = generateId(text2);
1770
+ const escapedContent = escapeHtml(text2);
1771
+ const format = ((_b = token.attributes) == null ? void 0 : _b.format) || "html";
1772
+ if (format === "html") {
1773
+ return `<h${level} id="${id}">${escapedContent}</h${level}>`;
1774
+ }
1775
+ let headingClasses = "group relative flex items-center gap-2";
1776
+ switch (level) {
1777
+ case 1:
1778
+ headingClasses += " text-3xl font-bold mt-8 mb-4";
1779
+ break;
1780
+ case 2:
1781
+ headingClasses += " text-2xl font-semibold mt-6 mb-3";
1782
+ break;
1783
+ case 3:
1784
+ headingClasses += " text-xl font-medium mt-5 mb-3";
1785
+ break;
1786
+ case 4:
1787
+ headingClasses += " text-lg font-medium mt-4 mb-2";
1788
+ break;
1789
+ case 5:
1790
+ headingClasses += " text-base font-medium mt-3 mb-2";
1791
+ break;
1792
+ case 6:
1793
+ headingClasses += " text-sm font-medium mt-3 mb-2";
1794
+ break;
1795
+ }
1796
+ return `<h${level} id="${id}" class="${headingClasses}">
1797
+ ${escapedContent}
1798
+ <a href="#${id}" class="opacity-0 group-hover:opacity-100 text-muted-foreground transition-opacity">
1799
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1800
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
1801
+ <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
1802
+ </svg>
1803
+ </a>
1804
+ </h${level}>`;
1805
+ }
1806
+ }
1807
+ ]
1808
+ };
1809
+
1810
+ // src/extensions/core/hr.ts
1811
+ var HorizontalRuleExtension = {
1812
+ name: "hr",
1813
+ parseRules: [
1814
+ {
1815
+ name: "hr",
1816
+ pattern: /^---$/m,
1817
+ render: (match) => ({
1818
+ type: "hr",
1819
+ content: "",
1820
+ raw: match[0] || ""
1821
+ })
1822
+ }
1823
+ ],
1824
+ renderRules: [
1825
+ {
1826
+ type: "hr",
1827
+ render: (token) => {
1828
+ var _a;
1829
+ const format = (_a = token.attributes) == null ? void 0 : _a.format;
1830
+ if (format === "html") {
1831
+ return '<hr style="margin: 24px 0; border: none; border-top: 1px solid #d1d5db;">';
1832
+ }
1833
+ return '<hr class="my-6 border-t border-border">';
1834
+ }
1835
+ }
1836
+ ]
1837
+ };
1838
+
1839
+ // src/extensions/core/image.ts
1840
+ var ImageExtension = {
1841
+ name: "image",
1842
+ parseRules: [
1843
+ {
1844
+ name: "image",
1845
+ pattern: /!\[([^\]]*)\]\(([^)]+?)(?:\s+"([^"]+)")?\)/,
1846
+ render: (match) => ({
1847
+ type: "image",
1848
+ content: match[1] || "",
1849
+ raw: match[0] || "",
1850
+ attributes: {
1851
+ alt: match[1] || "",
1852
+ src: match[2] || "",
1853
+ title: match[3] || ""
1854
+ }
1855
+ })
1856
+ }
1857
+ ],
1858
+ renderRules: [
1859
+ {
1860
+ type: "image",
1861
+ render: (token) => {
1862
+ var _a, _b, _c, _d;
1863
+ const src = ((_a = token.attributes) == null ? void 0 : _a.src) || "";
1864
+ const alt = ((_b = token.attributes) == null ? void 0 : _b.alt) || "";
1865
+ const title = ((_c = token.attributes) == null ? void 0 : _c.title) || "";
1866
+ const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
1867
+ const format = ((_d = token.attributes) == null ? void 0 : _d.format) || "html";
1868
+ if (format === "html") {
1869
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
1870
+ }
1871
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
1872
+ }
1873
+ }
1874
+ ]
1875
+ };
1876
+
1877
+ // src/extensions/core/links.ts
1878
+ var LinkExtension = {
1879
+ name: "link",
1880
+ parseRules: [
1881
+ {
1882
+ name: "link",
1883
+ pattern: /\[(?!(?:button|embed):)([^\]]+)\]\(([^)]+)\)/,
1884
+ render: (match) => ({
1885
+ type: "link",
1886
+ content: match[1] || "",
1887
+ raw: match[0] || "",
1888
+ attributes: {
1889
+ href: match[2] || ""
1890
+ }
1891
+ })
1892
+ }
1893
+ ],
1894
+ renderRules: [
1895
+ {
1896
+ type: "link",
1897
+ render: (token) => {
1898
+ var _a, _b;
1899
+ const href = ((_a = token.attributes) == null ? void 0 : _a.href) || "#";
1900
+ const escapedHref = escapeHtml(href);
1901
+ const escapedText = escapeHtml(token.content);
1902
+ const format = ((_b = token.attributes) == null ? void 0 : _b.format) || "html";
1903
+ if (format === "html") {
1904
+ return `<a href="${escapedHref}" target="_blank" rel="noopener noreferrer">${escapedText}</a>`;
1905
+ }
1906
+ return `<a href="${escapedHref}" class="text-primary hover:underline inline-flex items-center gap-1" target="_blank" rel="noopener noreferrer">
1907
+ ${escapedText}
1908
+ <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link">
1909
+ <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
1910
+ <polyline points="15 3 21 3 21 9"></polyline>
1911
+ <line x1="10" y1="14" x2="21" y2="3"></line>
1912
+ </svg>
1913
+ </a>`;
1914
+ }
1915
+ }
1916
+ ]
1917
+ };
1918
+
1919
+ // src/extensions/core/lists.ts
1920
+ var ListExtension = {
1921
+ name: "list",
1922
+ parseRules: [
1923
+ {
1924
+ name: "list-item",
1925
+ pattern: /^(\s*)[-*+]\s+(.+)$/m,
1926
+ render: (match) => ({
1927
+ type: "list-item",
1928
+ content: match[2] || "",
1929
+ raw: match[0] || ""
1930
+ })
1931
+ }
1932
+ ],
1933
+ renderRules: [
1934
+ {
1935
+ type: "list-item",
1936
+ render: (token) => `<li>${escapeHtml(token.content)}</li>`
1937
+ }
1938
+ ]
1939
+ };
1940
+ var TaskListExtension = {
1941
+ name: "task-list",
1942
+ parseRules: [
1943
+ {
1944
+ name: "task-item",
1945
+ pattern: /^(\s*)-\s*\[([ xX])\]\s*(.+)$/m,
1946
+ render: (match) => ({
1947
+ type: "task-item",
1948
+ content: match[3] || "",
1949
+ raw: match[0] || "",
1950
+ attributes: {
1951
+ checked: String((match[2] || "").toLowerCase() === "x")
1952
+ }
1953
+ })
1954
+ }
1955
+ ],
1956
+ renderRules: [
1957
+ {
1958
+ type: "task-item",
1959
+ render: (token) => {
1960
+ var _a, _b;
1961
+ const isChecked = ((_a = token.attributes) == null ? void 0 : _a.checked) === "true";
1962
+ const escapedContent = escapeHtml(token.content);
1963
+ const format = ((_b = token.attributes) == null ? void 0 : _b.format) || "html";
1964
+ if (format === "html") {
1965
+ return `<div style="display: flex; align-items: center; gap: 8px; margin: 8px 0;">
1966
+ <input type="checkbox" ${isChecked ? "checked" : ""} disabled style="margin: 0;" />
1967
+ <span${isChecked ? ' style="text-decoration: line-through; color: #6b7280;"' : ""}>${escapedContent}</span>
1968
+ </div>`;
1969
+ }
1970
+ return `<div class="flex items-center gap-2 my-2 task-list-item">
1971
+ <input type="checkbox" ${isChecked ? "checked" : ""} disabled
1972
+ class="form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" />
1973
+ <span${isChecked ? ' class="line-through text-muted-foreground"' : ""}>${escapedContent}</span>
1974
+ </div>`;
1975
+ }
1976
+ }
1977
+ ]
1978
+ };
1979
+
1980
+ // src/extensions/core/paragraph.ts
1981
+ var ParagraphExtension = {
1982
+ name: "paragraph",
1983
+ parseRules: [],
1984
+ renderRules: [
1985
+ {
1986
+ type: "paragraph",
1987
+ render: (token) => {
1988
+ var _a;
1989
+ if (!token.content) return "";
1990
+ const content = token.content.trim();
1991
+ if (!content) return "";
1992
+ const processedContent = content.includes("<br>") ? content : escapeHtml(content);
1993
+ const format = ((_a = token.attributes) == null ? void 0 : _a.format) || "html";
1994
+ if (format === "html") {
1995
+ return `<p style="line-height: 1.75; margin-bottom: 16px;">${processedContent}</p>`;
1996
+ }
1997
+ return `<p class="leading-7 mb-4">${processedContent}</p>`;
1998
+ }
1999
+ }
2000
+ ]
2001
+ };
2002
+
2003
+ // src/extensions/core/text.ts
2004
+ var TextExtension = {
2005
+ name: "text",
2006
+ parseRules: [],
2007
+ renderRules: [
2008
+ {
2009
+ type: "text",
2010
+ render: (token) => {
2011
+ if (!token.content) return "";
2012
+ return escapeHtml(token.content);
2013
+ }
2014
+ }
2015
+ ]
2016
+ };
2017
+
2018
+ // src/extensions/core/index.ts
2019
+ var CoreExtensions = [
2020
+ TextExtension,
2021
+ HeadingExtension,
2022
+ BoldExtension,
2023
+ ItalicExtension,
2024
+ InlineCodeExtension,
2025
+ CodeBlockExtension,
2026
+ LinkExtension,
2027
+ ImageExtension,
2028
+ ListExtension,
2029
+ TaskListExtension,
2030
+ BlockquoteExtension,
2031
+ HorizontalRuleExtension,
2032
+ ParagraphExtension,
2033
+ LineBreakExtension
2034
+ ];
2035
+
2036
+ // src/extensions/alert.ts
2037
+ var AlertExtension = {
2038
+ name: "alert",
2039
+ parseRules: [
2040
+ {
2041
+ name: "alert",
2042
+ pattern: /:::(\w+)(?:\s+(.*?))?\s*\n([\s\S]*?)\n:::/,
2043
+ render: (match) => {
2044
+ var _a;
2045
+ return {
2046
+ type: "alert",
2047
+ content: ((_a = match[3]) == null ? void 0 : _a.trim()) || "",
2048
+ raw: match[0] || "",
2049
+ attributes: {
2050
+ type: match[1] || "info",
2051
+ title: match[2] || ""
2052
+ }
2053
+ };
2054
+ }
2055
+ }
2056
+ ],
2057
+ renderRules: [
2058
+ {
2059
+ type: "alert",
2060
+ render: (token) => {
2061
+ var _a, _b;
2062
+ const type = ((_a = token.attributes) == null ? void 0 : _a.type) || "info";
2063
+ const title = ((_b = token.attributes) == null ? void 0 : _b.title) || "";
2064
+ const typeConfig = {
2065
+ info: {
2066
+ icon: "\u2139\uFE0F",
2067
+ classes: "bg-blue-500/10 border-blue-500/30 text-blue-600 border-l-blue-500"
2068
+ },
2069
+ warning: {
2070
+ icon: "\u26A0\uFE0F",
2071
+ classes: "bg-amber-500/10 border-amber-500/30 text-amber-600 border-l-amber-500"
2072
+ },
2073
+ error: {
2074
+ icon: "\u274C",
2075
+ classes: "bg-red-500/10 border-red-500/30 text-red-600 border-l-red-500"
2076
+ },
2077
+ success: {
2078
+ icon: "\u2705",
2079
+ classes: "bg-green-500/10 border-green-500/30 text-green-600 border-l-green-500"
2080
+ },
2081
+ tip: {
2082
+ icon: "\u{1F4A1}",
2083
+ classes: "bg-purple-500/10 border-purple-500/30 text-purple-600 border-l-purple-500"
2084
+ },
2085
+ note: {
2086
+ icon: "\u{1F4DD}",
2087
+ classes: "bg-gray-500/10 border-gray-500/30 text-gray-600 border-l-gray-500"
2088
+ }
2089
+ };
2090
+ const config = typeConfig[type] || typeConfig.info;
2091
+ const baseClasses = "border-l-4 p-4 mb-4 rounded-md transition-colors duration-200";
2092
+ const classes = `${baseClasses} ${config == null ? void 0 : config.classes}`;
2093
+ const titleHtml = title ? `<div class="font-medium mb-2 flex items-center gap-2">
2094
+ <span class="text-lg" role="img" aria-label="${type}">${config == null ? void 0 : config.icon}</span>
2095
+ <span>${title}</span>
2096
+ </div>` : `<div class="font-medium mb-2 flex items-center gap-2">
2097
+ <span class="text-lg" role="img" aria-label="${type}">${config == null ? void 0 : config.icon}</span>
2098
+ <span>${type.charAt(0).toUpperCase() + type.slice(1)}</span>
2099
+ </div>`;
2100
+ return `<div class="${classes}" role="alert" aria-live="polite">
2101
+ ${titleHtml}
2102
+ <div class="leading-relaxed">${token.content}</div>
2103
+ </div>`;
2104
+ }
2105
+ }
2106
+ ]
2107
+ };
2108
+
2109
+ // src/extensions/button.ts
2110
+ var ButtonExtension = {
2111
+ name: "button",
2112
+ parseRules: [
2113
+ {
2114
+ name: "button",
2115
+ pattern: /\[button:([^\]]+)\]\(([^)]+)\)(?:\{([^}]+)\})?/,
2116
+ render: (match) => {
2117
+ const options = match[3] ? match[3].split(",").map((opt) => opt.trim()) : [];
2118
+ return {
2119
+ type: "button",
2120
+ content: match[1] || "",
2121
+ raw: match[0] || "",
2122
+ attributes: {
2123
+ href: match[2] || "",
2124
+ style: options.find(
2125
+ (opt) => ["default", "primary", "secondary", "success", "danger", "outline", "ghost"].includes(opt)
2126
+ ) || "primary",
2127
+ size: options.find((opt) => ["sm", "md", "lg"].includes(opt)) || "md",
2128
+ disabled: String(options.includes("disabled")),
2129
+ target: options.includes("self") ? "_self" : "_blank"
2130
+ }
2131
+ };
2132
+ }
2133
+ }
2134
+ ],
2135
+ renderRules: [
2136
+ {
2137
+ type: "button",
2138
+ render: (token) => {
2139
+ var _a, _b, _c, _d, _e;
2140
+ const href = ((_a = token.attributes) == null ? void 0 : _a.href) || "#";
2141
+ const style = ((_b = token.attributes) == null ? void 0 : _b.style) || "primary";
2142
+ const size = ((_c = token.attributes) == null ? void 0 : _c.size) || "md";
2143
+ const disabled = ((_d = token.attributes) == null ? void 0 : _d.disabled) === "true";
2144
+ const target = ((_e = token.attributes) == null ? void 0 : _e.target) || "_blank";
2145
+ const baseClasses = `
2146
+ inline-flex items-center justify-center font-medium rounded-lg
2147
+ transition-all duration-200 ease-out
2148
+ focus:outline-none focus:ring-2 focus:ring-offset-2
2149
+ disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none
2150
+ transform hover:scale-[1.02] active:scale-[0.98]
2151
+ shadow-sm hover:shadow-md active:shadow-sm
2152
+ border border-transparent
2153
+ relative overflow-hidden
2154
+ before:absolute before:inset-0 before:rounded-lg
2155
+ before:bg-gradient-to-br before:from-white/20 before:to-transparent
2156
+ before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-200
2157
+ `.replace(/\s+/g, " ").trim();
2158
+ const sizeClasses = {
2159
+ sm: "px-3 py-1.5 text-sm gap-1.5",
2160
+ md: "px-4 py-2 text-base gap-2",
2161
+ lg: "px-6 py-3 text-lg gap-2.5"
2162
+ };
2163
+ const styleClasses = {
2164
+ default: `
2165
+ bg-slate-600 text-white border-slate-500
2166
+ hover:bg-slate-700 hover:border-slate-400
2167
+ focus:ring-slate-500
2168
+ shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
2169
+ hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
2170
+ `,
2171
+ primary: `
2172
+ bg-blue-600 text-white border-blue-500
2173
+ hover:bg-blue-700 hover:border-blue-400
2174
+ focus:ring-blue-500
2175
+ shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
2176
+ hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
2177
+ `,
2178
+ secondary: `
2179
+ bg-gray-600 text-white border-gray-500
2180
+ hover:bg-gray-700 hover:border-gray-400
2181
+ focus:ring-gray-500
2182
+ shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
2183
+ hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
2184
+ `,
2185
+ success: `
2186
+ bg-green-600 text-white border-green-500
2187
+ hover:bg-green-700 hover:border-green-400
2188
+ focus:ring-green-500
2189
+ shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
2190
+ hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
2191
+ `,
2192
+ danger: `
2193
+ bg-red-600 text-white border-red-500
2194
+ hover:bg-red-700 hover:border-red-400
2195
+ focus:ring-red-500
2196
+ shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]
2197
+ hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]
2198
+ `,
2199
+ outline: `
2200
+ bg-transparent text-blue-600 border-blue-600
2201
+ hover:bg-blue-50 hover:border-blue-700 hover:text-blue-700
2202
+ focus:ring-blue-500
2203
+ shadow-[0_0_0_1px_rgba(59,130,246,0.5)_inset]
2204
+ hover:shadow-[0_0_0_1px_rgba(29,78,216,0.6)_inset,0_1px_2px_0_rgba(0,0,0,0.05)]
2205
+ `,
2206
+ ghost: `
2207
+ bg-transparent text-gray-700 border-transparent
2208
+ hover:bg-gray-100 hover:text-gray-900
2209
+ focus:ring-gray-500
2210
+ shadow-none
2211
+ hover:shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]
2212
+ `
2213
+ };
2214
+ const classes = `
2215
+ ${baseClasses}
2216
+ ${sizeClasses[size] || sizeClasses.md}
2217
+ ${styleClasses[style] || styleClasses.primary}
2218
+ `.replace(/\s+/g, " ").trim();
2219
+ const targetAttr = target === "_blank" ? ' target="_blank" rel="noopener noreferrer"' : target === "_self" ? ' target="_self"' : "";
2220
+ const disabledAttr = disabled ? ' aria-disabled="true" tabindex="-1"' : "";
2221
+ const externalIcon = target === "_blank" && !disabled ? `<svg class="w-4 h-4 ml-1 opacity-75" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2222
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
2223
+ </svg>` : "";
2224
+ return `<a href="${href}" class="${classes}"${targetAttr}${disabledAttr}>
2225
+ <span class="relative z-10">${token.content}</span>${externalIcon}
2226
+ </a>`;
2227
+ }
2228
+ }
2229
+ ]
2230
+ };
2231
+
2232
+ // src/extensions/embed.ts
2233
+ var EmbedExtension = {
2234
+ name: "embed",
2235
+ parseRules: [
2236
+ {
2237
+ name: "embed",
2238
+ pattern: /\[embed:(\w+)\]\(([^)]+)\)(?:\{([^}]+)\})?/,
2239
+ render: (match) => {
2240
+ return {
2241
+ type: "embed",
2242
+ content: match[2] || "",
2243
+ // URL
2244
+ raw: match[0] || "",
2245
+ attributes: {
2246
+ provider: match[1] || "generic",
2247
+ url: match[2] || "",
2248
+ options: match[3] || ""
2249
+ }
2250
+ };
2251
+ }
2252
+ }
2253
+ ],
2254
+ renderRules: [
2255
+ {
2256
+ type: "embed",
2257
+ render: (token) => {
2258
+ var _a, _b, _c;
2259
+ const provider = ((_a = token.attributes) == null ? void 0 : _a.provider) || "generic";
2260
+ const url = ((_b = token.attributes) == null ? void 0 : _b.url) || "";
2261
+ const options = ((_c = token.attributes) == null ? void 0 : _c.options) || "";
2262
+ return renderEmbed(provider, url, options);
2263
+ }
2264
+ }
2265
+ ]
2266
+ };
2267
+ function renderEmbed(provider, url, options) {
2268
+ const baseClasses = "rounded-lg border bg-card text-card-foreground shadow-sm mb-6 overflow-hidden";
2269
+ const parsedOptions = parseOptions(options);
2270
+ switch (provider.toLowerCase()) {
2271
+ case "youtube":
2272
+ return renderYouTubeEmbed(url, parsedOptions, baseClasses);
2273
+ case "codepen":
2274
+ return renderCodePenEmbed(url, parsedOptions, baseClasses);
2275
+ case "figma":
2276
+ return renderFigmaEmbed(url, parsedOptions, baseClasses);
2277
+ case "twitter":
2278
+ case "tweet":
2279
+ return renderTwitterEmbed(url, parsedOptions, baseClasses);
2280
+ case "github":
2281
+ return renderGitHubEmbed(url, parsedOptions, baseClasses);
2282
+ case "vimeo":
2283
+ return renderVimeoEmbed(url, parsedOptions, baseClasses);
2284
+ case "spotify":
2285
+ return renderSpotifyEmbed(url, parsedOptions, baseClasses);
2286
+ case "codesandbox":
2287
+ return renderCodeSandboxEmbed(url, parsedOptions, baseClasses);
2288
+ default:
2289
+ return renderGenericEmbed(url, parsedOptions, baseClasses);
2290
+ }
2291
+ }
2292
+ function renderYouTubeEmbed(url, options, classes) {
2293
+ const videoId = extractYouTubeId(url);
2294
+ if (!videoId) {
2295
+ return createErrorEmbed("Invalid YouTube URL", url, classes);
2296
+ }
2297
+ const params = new URLSearchParams();
2298
+ if (options.autoplay === "1") params.set("autoplay", "1");
2299
+ if (options.mute === "1") params.set("mute", "1");
2300
+ if (options.loop === "1") {
2301
+ params.set("loop", "1");
2302
+ params.set("playlist", videoId);
2303
+ }
2304
+ if (options.controls === "0") params.set("controls", "0");
2305
+ if (options.start) params.set("start", options.start);
2306
+ params.set("rel", "0");
2307
+ params.set("modestbranding", "1");
2308
+ const embedUrl = `https://www.youtube.com/embed/${videoId}?${params.toString()}`;
2309
+ return `<div class="${classes}">
2310
+ <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
2311
+ <iframe
2312
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;"
2313
+ src="${embedUrl}"
2314
+ title="YouTube video player"
2315
+ frameborder="0"
2316
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
2317
+ allowfullscreen>
2318
+ </iframe>
2319
+ </div>
2320
+ </div>`;
2321
+ }
2322
+ function renderCodePenEmbed(url, options, classes) {
2323
+ const match = url.match(/codepen\.io\/([^\/]+)\/(?:pen|embed)\/([^\/\?#]+)/);
2324
+ if (!match) {
2325
+ return createErrorEmbed("Invalid CodePen URL", url, classes);
2326
+ }
2327
+ const [, user, penId] = match;
2328
+ const height = options.height || "400";
2329
+ const theme = options.theme === "light" ? "light" : "dark";
2330
+ const defaultTab = options.tab || "result";
2331
+ const embedParams = new URLSearchParams({
2332
+ "default-tab": defaultTab,
2333
+ "theme-id": theme,
2334
+ "editable": "true"
2335
+ });
2336
+ const embedUrl = `https://codepen.io/${user}/embed/${penId}?${embedParams.toString()}`;
2337
+ return `<div class="${classes}">
2338
+ <iframe
2339
+ height="${height}"
2340
+ style="width: 100%; border: 0;"
2341
+ scrolling="no"
2342
+ title="CodePen Embed - ${penId}"
2343
+ src="${embedUrl}"
2344
+ frameborder="0"
2345
+ loading="lazy"
2346
+ allowtransparency="true"
2347
+ allowfullscreen="true">
2348
+ </iframe>
2349
+ </div>`;
2350
+ }
2351
+ function renderVimeoEmbed(url, options, classes) {
2352
+ const videoId = extractVimeoId(url);
2353
+ if (!videoId) {
2354
+ return createErrorEmbed("Invalid Vimeo URL", url, classes);
2355
+ }
2356
+ const params = new URLSearchParams();
2357
+ if (options.autoplay === "1") params.set("autoplay", "1");
2358
+ if (options.mute === "1") params.set("muted", "1");
2359
+ if (options.loop === "1") params.set("loop", "1");
2360
+ const embedUrl = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;
2361
+ return `<div class="${classes}">
2362
+ <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
2363
+ <iframe
2364
+ style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;"
2365
+ src="${embedUrl}"
2366
+ title="Vimeo video player"
2367
+ frameborder="0"
2368
+ allow="autoplay; fullscreen; picture-in-picture"
2369
+ allowfullscreen>
2370
+ </iframe>
2371
+ </div>
2372
+ </div>`;
2373
+ }
2374
+ function renderSpotifyEmbed(url, options, classes) {
2375
+ const embedUrl = url.replace("open.spotify.com", "open.spotify.com/embed");
2376
+ const height = options.height || "380";
2377
+ return `<div class="${classes}">
2378
+ <iframe
2379
+ style="border-radius: 12px;"
2380
+ src="${embedUrl}"
2381
+ width="100%"
2382
+ height="${height}"
2383
+ frameborder="0"
2384
+ allowfullscreen=""
2385
+ allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
2386
+ loading="lazy">
2387
+ </iframe>
2388
+ </div>`;
2389
+ }
2390
+ function renderCodeSandboxEmbed(url, options, classes) {
2391
+ let embedUrl = url;
2392
+ if (url.includes("/s/")) {
2393
+ embedUrl = url.replace("/s/", "/embed/");
2394
+ }
2395
+ const height = options.height || "500";
2396
+ const view = options.view || "preview";
2397
+ if (!embedUrl.includes("?")) {
2398
+ embedUrl += `?view=${view}`;
2399
+ }
2400
+ return `<div class="${classes}">
2401
+ <iframe
2402
+ src="${embedUrl}"
2403
+ style="width: 100%; height: ${height}px; border: 0; border-radius: 4px; overflow: hidden;"
2404
+ title="CodeSandbox Embed"
2405
+ allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
2406
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts">
2407
+ </iframe>
2408
+ </div>`;
2409
+ }
2410
+ function renderFigmaEmbed(url, options, classes) {
2411
+ const embedUrl = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;
2412
+ const height = options.height || "450";
2413
+ return `<div class="${classes}">
2414
+ <iframe
2415
+ style="border: none;"
2416
+ width="100%"
2417
+ height="${height}"
2418
+ src="${embedUrl}"
2419
+ allowfullscreen>
2420
+ </iframe>
2421
+ </div>`;
2422
+ }
2423
+ function renderTwitterEmbed(url, _options, classes) {
2424
+ return `<div class="${classes}">
2425
+ <div class="p-4">
2426
+ <div class="flex items-center gap-3 mb-3">
2427
+ <svg class="w-6 h-6 fill-current text-blue-500" viewBox="0 0 24 24">
2428
+ <path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
2429
+ </svg>
2430
+ <div>
2431
+ <div class="font-semibold text-foreground">Twitter Post</div>
2432
+ <div class="text-sm text-muted-foreground">External Link</div>
2433
+ </div>
2434
+ </div>
2435
+ <a href="${url}" target="_blank"
2436
+ class="inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors">
2437
+ View on Twitter
2438
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2439
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
2440
+ </svg>
2441
+ </a>
2442
+ </div>
2443
+ </div>`;
2444
+ }
2445
+ function renderGitHubEmbed(url, _options, classes) {
2446
+ const parts = url.replace("https://github.com/", "").split("/");
2447
+ const owner = parts[0];
2448
+ const repo = parts[1];
2449
+ if (!owner || !repo) {
2450
+ return createErrorEmbed("Invalid GitHub URL", url, classes);
2451
+ }
2452
+ return `<div class="${classes}">
2453
+ <div class="p-4">
2454
+ <div class="flex items-center gap-3 mb-3">
2455
+ <svg class="w-6 h-6 fill-current" viewBox="0 0 24 24">
2456
+ <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
2457
+ </svg>
2458
+ <div>
2459
+ <div class="font-semibold text-foreground text-lg">${owner}/${repo}</div>
2460
+ <div class="text-sm text-muted-foreground">GitHub Repository</div>
2461
+ </div>
2462
+ </div>
2463
+ <a href="${url}" target="_blank"
2464
+ class="inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors">
2465
+ View on GitHub
2466
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2467
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
2468
+ </svg>
2469
+ </a>
2470
+ </div>
2471
+ </div>`;
2472
+ }
2473
+ function renderGenericEmbed(url, _options, classes) {
2474
+ const domain = extractDomain(url);
2475
+ return `<div class="${classes}">
2476
+ <div class="p-4">
2477
+ <div class="flex items-center gap-3 mb-3">
2478
+ <div class="w-10 h-10 rounded-lg bg-muted flex items-center justify-center">
2479
+ <svg class="w-5 h-5 text-muted-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2480
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
2481
+ </svg>
2482
+ </div>
2483
+ <div>
2484
+ <div class="font-semibold text-foreground">External Link</div>
2485
+ <div class="text-sm text-muted-foreground">${domain}</div>
2486
+ </div>
2487
+ </div>
2488
+ <a href="${url}" target="_blank"
2489
+ class="inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors break-all">
2490
+ ${url}
2491
+ <svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2492
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
2493
+ </svg>
2494
+ </a>
2495
+ </div>
2496
+ </div>`;
2497
+ }
2498
+ function createErrorEmbed(error, url, classes) {
2499
+ return `<div class="${classes}">
2500
+ <div class="p-4 text-destructive">
2501
+ <div class="font-medium flex items-center gap-2">
2502
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2503
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
2504
+ </svg>
2505
+ ${error}
2506
+ </div>
2507
+ <div class="text-sm text-muted-foreground mt-1 break-all">${url}</div>
2508
+ </div>
2509
+ </div>`;
2510
+ }
2511
+ function extractYouTubeId(url) {
2512
+ const patterns = [
2513
+ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/shorts\/)([^&\n?#]+)/,
2514
+ /youtube\.com\/watch\?.*v=([^&\n?#]+)/
2515
+ ];
2516
+ for (const pattern of patterns) {
2517
+ const match = url.match(pattern);
2518
+ if (match) return match[1] || null;
2519
+ }
2520
+ return null;
2521
+ }
2522
+ function extractVimeoId(url) {
2523
+ var _a;
2524
+ const match = url.match(/vimeo\.com\/(?:.*\/)?(\d+)/);
2525
+ return (_a = match == null ? void 0 : match[1]) != null ? _a : null;
2526
+ }
2527
+
2528
+ // src/engine.ts
2529
+ var ChangerawrMarkdown = class {
2530
+ constructor(config) {
2531
+ this.extensions = /* @__PURE__ */ new Map();
2532
+ this.parser = new MarkdownParser(config == null ? void 0 : config.parser);
2533
+ this.renderer = new MarkdownRenderer(config == null ? void 0 : config.renderer);
2534
+ this.registerCoreExtensions();
2535
+ this.registerFeatureExtensions();
2536
+ if (config == null ? void 0 : config.extensions) {
2537
+ config.extensions.forEach((extension) => {
2538
+ this.registerExtension(extension);
2539
+ });
2540
+ }
2541
+ }
2542
+ registerFeatureExtensions() {
2543
+ this.registerExtension(AlertExtension);
2544
+ this.registerExtension(ButtonExtension);
2545
+ this.registerExtension(EmbedExtension);
2546
+ }
2547
+ registerCoreExtensions() {
2548
+ CoreExtensions.forEach((extension) => {
2549
+ this.registerExtension(extension);
2550
+ });
2551
+ }
2552
+ registerExtension(extension) {
2553
+ try {
2554
+ if (!extension.name || typeof extension.name !== "string") {
2555
+ throw new Error("Extension must have a valid name");
2556
+ }
2557
+ if (!Array.isArray(extension.parseRules)) {
2558
+ throw new Error("Extension must have parseRules array");
2559
+ }
2560
+ if (!Array.isArray(extension.renderRules)) {
2561
+ throw new Error("Extension must have renderRules array");
2562
+ }
2563
+ extension.parseRules.forEach((rule, index) => {
2564
+ if (!rule.name || typeof rule.name !== "string") {
2565
+ throw new Error(`Parse rule ${index} must have a valid name`);
2566
+ }
2567
+ if (!rule.pattern || !(rule.pattern instanceof RegExp)) {
2568
+ throw new Error(`Parse rule ${index} must have a valid RegExp pattern`);
2569
+ }
2570
+ if (!rule.render || typeof rule.render !== "function") {
2571
+ throw new Error(`Parse rule ${index} must have a valid render function`);
2572
+ }
2573
+ });
2574
+ extension.renderRules.forEach((rule, index) => {
2575
+ if (!rule.type || typeof rule.type !== "string") {
2576
+ throw new Error(`Render rule ${index} must have a valid type`);
2577
+ }
2578
+ if (!rule.render || typeof rule.render !== "function") {
2579
+ throw new Error(`Render rule ${index} must have a valid render function`);
2580
+ }
2581
+ });
2582
+ this.extensions.set(extension.name, extension);
2583
+ extension.parseRules.forEach((rule) => {
2584
+ this.parser.addRule(rule);
2585
+ });
2586
+ extension.renderRules.forEach((rule) => {
2587
+ this.renderer.addRule(rule);
2588
+ });
2589
+ return {
2590
+ success: true,
2591
+ extensionName: extension.name
2592
+ };
2593
+ } catch (error) {
2594
+ const errorMessage = error instanceof Error ? error.message : String(error);
2595
+ return {
2596
+ success: false,
2597
+ extensionName: extension.name,
2598
+ error: errorMessage
2599
+ };
2600
+ }
2601
+ }
2602
+ unregisterExtension(name) {
2603
+ const extension = this.extensions.get(name);
2604
+ if (!extension) {
2605
+ return false;
2606
+ }
2607
+ try {
2608
+ this.extensions.delete(name);
2609
+ this.rebuildParserAndRenderer();
2610
+ return true;
2611
+ } catch (e) {
2612
+ return false;
2613
+ }
2614
+ }
2615
+ parse(markdown2) {
2616
+ return this.parser.parse(markdown2);
2617
+ }
2618
+ render(tokens) {
2619
+ return this.renderer.render(tokens);
2620
+ }
2621
+ toHtml(markdown2) {
2622
+ const tokens = this.parse(markdown2);
2623
+ return this.render(tokens);
2624
+ }
2625
+ getExtensions() {
2626
+ return Array.from(this.extensions.keys());
2627
+ }
2628
+ hasExtension(name) {
2629
+ return this.extensions.has(name);
2630
+ }
2631
+ getWarnings() {
2632
+ return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];
2633
+ }
2634
+ getDebugInfo() {
2635
+ return {
2636
+ warnings: this.getWarnings(),
2637
+ parseTime: 0,
2638
+ renderTime: 0,
2639
+ tokenCount: 0,
2640
+ iterationCount: 0
2641
+ };
2642
+ }
2643
+ getPerformanceMetrics() {
2644
+ return {
2645
+ parseTime: 0,
2646
+ renderTime: 0,
2647
+ totalTime: 0,
2648
+ tokenCount: 0
2649
+ };
2650
+ }
2651
+ rebuildParserAndRenderer() {
2652
+ const parserConfig = this.parser.getConfig();
2653
+ const rendererConfig = this.renderer.getConfig();
2654
+ this.parser = new MarkdownParser(parserConfig);
2655
+ this.renderer = new MarkdownRenderer(rendererConfig);
2656
+ const extensionsToRegister = Array.from(this.extensions.values());
2657
+ const featureExtensions = extensionsToRegister.filter(
2658
+ (ext) => ["alert", "button", "embed"].includes(ext.name)
2659
+ );
2660
+ const coreExtensions = extensionsToRegister.filter(
2661
+ (ext) => ["text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(ext.name)
2662
+ );
2663
+ const customExtensions = extensionsToRegister.filter(
2664
+ (ext) => !["alert", "button", "embed", "text", "heading", "bold", "italic", "code", "codeblock", "link", "image", "list", "task-list", "blockquote", "hr", "paragraph", "line-break"].includes(ext.name)
2665
+ );
2666
+ [...featureExtensions, ...coreExtensions, ...customExtensions].forEach((extension) => {
2667
+ extension.parseRules.forEach((rule) => {
2668
+ this.parser.addRule(rule);
2669
+ });
2670
+ extension.renderRules.forEach((rule) => {
2671
+ this.renderer.addRule(rule);
2672
+ });
2673
+ });
2674
+ }
2675
+ };
2676
+ var markdown = new ChangerawrMarkdown();
2677
+
2678
+ // src/standalone.ts
2679
+ function renderCum(markdown2, config) {
2680
+ const engine = new ChangerawrMarkdown(config);
2681
+ return engine.toHtml(markdown2);
2682
+ }
2683
+ function parseCum(markdown2, config) {
2684
+ const engine = new ChangerawrMarkdown(config);
2685
+ return engine.parse(markdown2);
2686
+ }
2687
+ function createCumEngine(config) {
2688
+ return new ChangerawrMarkdown(config);
2689
+ }
2690
+ function renderCumToHtml(markdown2) {
2691
+ return renderCum(markdown2, {
2692
+ renderer: { format: "html" }
2693
+ });
2694
+ }
2695
+ function renderCumToTailwind(markdown2) {
2696
+ return renderCum(markdown2, {
2697
+ renderer: { format: "tailwind" }
2698
+ });
2699
+ }
2700
+ function renderCumToJson(markdown2) {
2701
+ return parseCum(markdown2);
2702
+ }
2703
+ var standalone_default = {
2704
+ renderCum,
2705
+ parseCum,
2706
+ createCumEngine,
2707
+ renderCumToHtml,
2708
+ renderCumToTailwind,
2709
+ renderCumToJson,
2710
+ // Legacy aliases
2711
+ render: renderCum,
2712
+ parse: parseCum,
2713
+ // Include the main class
2714
+ ChangerawrMarkdown
2715
+ };
2716
+ return __toCommonJS(standalone_exports);
2717
+ })();
2718
+ /*! Bundled license information:
2719
+
2720
+ dompurify/dist/purify.es.mjs:
2721
+ (*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE *)
2722
+ */