@mulmoclaude/core 4.4.2 → 4.5.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.
Files changed (75) hide show
  1. package/assets/helps/bug-report-faq.md +13 -0
  2. package/assets/helps/business.md +4 -0
  3. package/assets/helps/error-recovery.md +71 -0
  4. package/assets/helps/gemini.md +1 -1
  5. package/assets/helps/mulmoscript.md +71 -1
  6. package/assets/helps/presentation-deck.md +4 -1
  7. package/assets/helps/storyteller.md +7 -0
  8. package/dist/collection/core/accentColor.d.ts +23 -0
  9. package/dist/collection/core/iconGlyph.d.ts +26 -0
  10. package/dist/collection/core/schema.d.ts +9 -0
  11. package/dist/collection/core/schemaZ.d.ts +18 -0
  12. package/dist/collection/core/shortcutInfo.d.ts +14 -0
  13. package/dist/collection/core/uiTypes.d.ts +6 -0
  14. package/dist/collection/index.cjs +22 -2
  15. package/dist/collection/index.cjs.map +1 -1
  16. package/dist/collection/index.d.ts +3 -0
  17. package/dist/collection/index.js +17 -3
  18. package/dist/collection/index.js.map +1 -1
  19. package/dist/collection/registry/server/index.cjs +3 -3
  20. package/dist/collection/registry/server/index.js +3 -3
  21. package/dist/collection/server/index.cjs +5 -4
  22. package/dist/collection/server/index.js +5 -5
  23. package/dist/collection/server/paths.d.ts +10 -0
  24. package/dist/collection-watchers/index.cjs +5 -5
  25. package/dist/collection-watchers/index.js +5 -5
  26. package/dist/{discovery-Dl9nRa-m.cjs → discovery-2TvulIz8.cjs} +25 -5
  27. package/dist/discovery-2TvulIz8.cjs.map +1 -0
  28. package/dist/{discovery-P64fgtuD.js → discovery-BY-nMCuh.js} +20 -6
  29. package/dist/discovery-BY-nMCuh.js.map +1 -0
  30. package/dist/feeds/index.cjs +2 -2
  31. package/dist/feeds/index.js +2 -2
  32. package/dist/feeds/server/index.cjs +5 -5
  33. package/dist/feeds/server/index.js +5 -5
  34. package/dist/files/atomic.d.ts +4 -0
  35. package/dist/files/index.cjs +1 -1
  36. package/dist/files/index.js +1 -1
  37. package/dist/google/index.cjs +3 -3
  38. package/dist/google/index.js +3 -3
  39. package/dist/iconGlyph-D8JeNg7R.js +59 -0
  40. package/dist/iconGlyph-D8JeNg7R.js.map +1 -0
  41. package/dist/iconGlyph-fSBp6k4J.cjs +70 -0
  42. package/dist/iconGlyph-fSBp6k4J.cjs.map +1 -0
  43. package/dist/{ingestTypes-CaX7_s-K.cjs → ingestTypes-DsVH9BYy.cjs} +2 -2
  44. package/dist/{ingestTypes-CaX7_s-K.cjs.map → ingestTypes-DsVH9BYy.cjs.map} +1 -1
  45. package/dist/{ingestTypes-CIy1lHjf.js → ingestTypes-GkG7bJdB.js} +2 -2
  46. package/dist/{ingestTypes-CIy1lHjf.js.map → ingestTypes-GkG7bJdB.js.map} +1 -1
  47. package/dist/{itemId-BY2YPBkT.js → itemId-4P9S_ehz.js} +48 -2
  48. package/dist/itemId-4P9S_ehz.js.map +1 -0
  49. package/dist/{itemId-CEQdK01z.cjs → itemId-CGT2J7YK.cjs} +65 -1
  50. package/dist/itemId-CGT2J7YK.cjs.map +1 -0
  51. package/dist/plugin-vue/IconGlyph.d.ts +27 -0
  52. package/dist/plugin-vue/index.cjs +117 -201
  53. package/dist/plugin-vue/index.cjs.map +1 -1
  54. package/dist/plugin-vue/index.d.ts +1 -0
  55. package/dist/plugin-vue/index.js +118 -203
  56. package/dist/plugin-vue/index.js.map +1 -1
  57. package/dist/{promptSafety-Bp780ezk.js → promptSafety-Bte62OvU.js} +2 -2
  58. package/dist/{promptSafety-Bp780ezk.js.map → promptSafety-Bte62OvU.js.map} +1 -1
  59. package/dist/{promptSafety-C0BWDsfT.cjs → promptSafety-Cv-SoTd4.cjs} +2 -2
  60. package/dist/{promptSafety-C0BWDsfT.cjs.map → promptSafety-Cv-SoTd4.cjs.map} +1 -1
  61. package/dist/{root-BMroU_mB.js → root-BcS4-Kge.js} +12 -2
  62. package/dist/root-BcS4-Kge.js.map +1 -0
  63. package/dist/{root-rPH6FGDT.cjs → root-BvwBUcol.cjs} +12 -2
  64. package/dist/root-BvwBUcol.cjs.map +1 -0
  65. package/dist/{server-BvXO49Vj.js → server-BENtFplH.js} +47 -18
  66. package/dist/{server-BvXO49Vj.js.map → server-BENtFplH.js.map} +1 -1
  67. package/dist/{server-CF1qllGV.cjs → server-Wz4_ALLl.cjs} +47 -18
  68. package/dist/{server-CF1qllGV.cjs.map → server-Wz4_ALLl.cjs.map} +1 -1
  69. package/package.json +8 -8
  70. package/dist/discovery-Dl9nRa-m.cjs.map +0 -1
  71. package/dist/discovery-P64fgtuD.js.map +0 -1
  72. package/dist/itemId-BY2YPBkT.js.map +0 -1
  73. package/dist/itemId-CEQdK01z.cjs.map +0 -1
  74. package/dist/root-BMroU_mB.js.map +0 -1
  75. package/dist/root-rPH6FGDT.cjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_iconGlyph = require("../iconGlyph-fSBp6k4J.cjs");
2
3
  let _mulmoclaude_markdown_utils_markdown_frontmatter = require("@mulmoclaude/markdown-utils/markdown/frontmatter");
3
4
  let vue = require("vue");
4
5
  let gui_chat_protocol_vue = require("gui-chat-protocol/vue");
@@ -87,8 +88,57 @@ function useClipboardCopy(resetMs = DEFAULT_RESET_MS) {
87
88
  };
88
89
  }
89
90
  //#endregion
91
+ //#region src/plugin-vue/IconGlyph.ts
92
+ var DEFAULT_SIZE_CLASS = "text-base";
93
+ var DEFAULT_FONT_CLASS = "material-symbols-outlined";
94
+ var SYMBOL_CONTAINMENT = {
95
+ display: "inline-block",
96
+ width: "1em",
97
+ overflow: "hidden"
98
+ };
99
+ var GLYPH_CONTAINMENT = {
100
+ display: "inline-block",
101
+ maxWidth: "1.25em",
102
+ overflow: "hidden",
103
+ lineHeight: "1"
104
+ };
105
+ /** Both branches carry the same semantics, and the icon-font one needs them
106
+ * MORE: its text content is the ligature NAME, so an unlabelled span makes a
107
+ * screen reader announce "podcasts" / "rss_feed" as content. 48 icon spans
108
+ * across this repo already mark themselves `aria-hidden`; these are the same
109
+ * kind of span. */
110
+ function labellingFor(ariaLabel) {
111
+ return ariaLabel ? {
112
+ role: "img",
113
+ "aria-label": ariaLabel
114
+ } : { "aria-hidden": "true" };
115
+ }
116
+ var IconGlyph = (props) => {
117
+ const sizeClass = props.sizeClass ?? DEFAULT_SIZE_CLASS;
118
+ const glyph = require_iconGlyph.resolveIconGlyph(props.icon, props.fallback ?? "dataset");
119
+ const labelling = labellingFor(props.ariaLabel);
120
+ if (glyph.kind === "symbol") return (0, vue.h)("span", {
121
+ class: [props.fontClass ?? DEFAULT_FONT_CLASS, sizeClass],
122
+ style: SYMBOL_CONTAINMENT,
123
+ ...labelling
124
+ }, glyph.name);
125
+ return (0, vue.h)("span", {
126
+ class: sizeClass,
127
+ style: GLYPH_CONTAINMENT,
128
+ ...labelling
129
+ }, glyph.text);
130
+ };
131
+ IconGlyph.displayName = "IconGlyph";
132
+ IconGlyph.props = {
133
+ icon: String,
134
+ fallback: String,
135
+ sizeClass: String,
136
+ ariaLabel: String,
137
+ fontClass: String
138
+ };
139
+ //#endregion
90
140
  //#region ../../node_modules/dompurify/dist/purify.es.mjs
91
- /*! @license DOMPurify 3.4.14 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.14/LICENSE */
141
+ /*! @license DOMPurify 3.4.13 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.13/LICENSE */
92
142
  function _arrayLikeToArray(r, a) {
93
143
  (null == a || a > r.length) && (a = r.length);
94
144
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
@@ -817,7 +867,6 @@ var svg = freeze([
817
867
  "patterncontentunits",
818
868
  "patterntransform",
819
869
  "patternunits",
820
- "pointer-events",
821
870
  "points",
822
871
  "preservealpha",
823
872
  "preserveaspectratio",
@@ -872,7 +921,6 @@ var svg = freeze([
872
921
  "u2",
873
922
  "unicode",
874
923
  "values",
875
- "vector-effect",
876
924
  "viewbox",
877
925
  "visibility",
878
926
  "version",
@@ -986,24 +1034,6 @@ var NODE_TYPE = {
986
1034
  documentFragment: 11,
987
1035
  notation: 12
988
1036
  };
989
- var LITERAL_TEXT_ELEMENT_NAMES = [
990
- "style",
991
- "script",
992
- "xmp",
993
- "iframe",
994
- "noembed",
995
- "noframes",
996
- "plaintext",
997
- "noscript"
998
- ];
999
- var LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));
1000
- var LITERAL_TEXT_CLOSE = function() {
1001
- const map = {};
1002
- arrayForEach(LITERAL_TEXT_ELEMENT_NAMES, (name) => {
1003
- map[name] = seal(new RegExp("</" + name + "(?=[\\t\\n\\f\\r />])", "i"));
1004
- });
1005
- return freeze(map);
1006
- }();
1007
1037
  var getGlobal = function getGlobal() {
1008
1038
  return typeof window === "undefined" ? null : window;
1009
1039
  };
@@ -1063,25 +1093,10 @@ var _createHooksMap = function _createHooksMap() {
1063
1093
  var _resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) {
1064
1094
  return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
1065
1095
  };
1066
- /**
1067
- * Resolve an object-valued configuration option: a prototype-free clone
1068
- * of cfg[key] when it is an own, truthy object property, else a fresh
1069
- * fallback built by makeFallback (fresh on every parse, so a previous
1070
- * parse can never leak state into the next one).
1071
- *
1072
- * @param cfg the cloned, prototype-free configuration object
1073
- * @param key the configuration property to read
1074
- * @param makeFallback builds the fallback value when the option is absent
1075
- * @returns the resolved object
1076
- */
1077
- var _resolveObjectOption = function _resolveObjectOption(cfg, key, makeFallback) {
1078
- const value = objectHasOwnProperty(cfg, key) ? cfg[key] : void 0;
1079
- return value && typeof value === "object" ? clone(value) : makeFallback();
1080
- };
1081
1096
  function createDOMPurify() {
1082
1097
  let window = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
1083
1098
  const DOMPurify = (root) => createDOMPurify(root);
1084
- DOMPurify.version = "3.4.14";
1099
+ DOMPurify.version = "3.4.13";
1085
1100
  DOMPurify.removed = [];
1086
1101
  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
1087
1102
  DOMPurify.isSupported = false;
@@ -1106,12 +1121,6 @@ function createDOMPurify() {
1106
1121
  const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
1107
1122
  const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
1108
1123
  const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, "ownerDocument") : null;
1109
- const _readNodeType = function _readNodeType(node) {
1110
- return getNodeType ? getNodeType(node) : node.nodeType;
1111
- };
1112
- const _readNodeName = function _readNodeName(node) {
1113
- return getNodeName ? getNodeName(node) : node.nodeName;
1114
- };
1115
1124
  if (typeof HTMLTemplateElement === "function") {
1116
1125
  const template = document.createElement("template");
1117
1126
  if (template.content && template.content.ownerDocument) document = template.content.ownerDocument;
@@ -1369,9 +1378,9 @@ function createDOMPurify() {
1369
1378
  IN_PLACE = cfg.IN_PLACE || false;
1370
1379
  IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
1371
1380
  NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
1372
- MATHML_TEXT_INTEGRATION_POINTS = _resolveObjectOption(cfg, "MATHML_TEXT_INTEGRATION_POINTS", () => addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS));
1373
- HTML_INTEGRATION_POINTS = _resolveObjectOption(cfg, "HTML_INTEGRATION_POINTS", () => addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS));
1374
- const customElementHandling = _resolveObjectOption(cfg, "CUSTOM_ELEMENT_HANDLING", () => create(null));
1381
+ MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
1382
+ HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
1383
+ const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
1375
1384
  CUSTOM_ELEMENT_HANDLING = create(null);
1376
1385
  if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
1377
1386
  if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
@@ -1418,6 +1427,11 @@ function createDOMPurify() {
1418
1427
  addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
1419
1428
  }
1420
1429
  }
1430
+ if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
1431
+ if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
1432
+ if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
1433
+ addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
1434
+ }
1421
1435
  if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
1422
1436
  if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
1423
1437
  addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
@@ -1534,32 +1548,6 @@ function createDOMPurify() {
1534
1548
  }
1535
1549
  };
1536
1550
  /**
1537
- * _stripAttributeNode
1538
- *
1539
- * Remove a single Attr node case/namespace-exactly on an attribute-teardown
1540
- * path. Name-based removeAttribute() ASCII-lowercases its lookup key for an
1541
- * HTML element in an HTML document and so silently misses a case-preserved
1542
- * handler (e.g. `ONERROR` off an XML/XHTML import) - the same defect
1543
- * _removeAttribute() was fixed for, which a name-based call would reintroduce
1544
- * on these IN_PLACE teardown paths. Unlike _removeAttribute this does not
1545
- * record into DOMPurify.removed: the neutralize passes intentionally do not
1546
- * book-keep. A clobbered/detached node falls back to best-effort name-based
1547
- * removal.
1548
- *
1549
- * @param element the element to strip the attribute from
1550
- * @param attribute the Attr node to remove
1551
- * @param name the attribute's name, for the fallback path
1552
- */
1553
- const _stripAttributeNode = function _stripAttributeNode(element, attribute, name) {
1554
- try {
1555
- element.removeAttributeNode(attribute);
1556
- } catch (_) {
1557
- try {
1558
- element.removeAttribute(name);
1559
- } catch (_) {}
1560
- }
1561
- };
1562
- /**
1563
1551
  * _neutralizeRoot
1564
1552
  *
1565
1553
  * Fail-closed teardown of an in-place root after the sanitize walk aborts
@@ -1593,45 +1581,30 @@ function createDOMPurify() {
1593
1581
  if (attributes) for (let i = attributes.length - 1; i >= 0; --i) {
1594
1582
  const attribute = attributes[i];
1595
1583
  const name = attribute && attribute.name;
1596
- if (typeof name === "string") _stripAttributeNode(root, attribute, name);
1584
+ if (typeof name === "string") try {
1585
+ root.removeAttribute(name);
1586
+ } catch (_) {}
1597
1587
  }
1598
1588
  };
1599
1589
  /**
1600
1590
  * _removeAttribute
1601
1591
  *
1602
- * Name-based getAttributeNode()/removeAttribute() ASCII-lowercase their
1603
- * lookup key for HTML elements in an HTML document, so they silently miss an
1604
- * attribute whose stored qualified name still contains uppercase ASCII
1605
- * letters. That happens when the node came from a case-preserving source
1606
- * (an XML/XHTML document imported via importNode(), or createAttributeNS()),
1607
- * where e.g. `ONERROR` survives the walk: the policy check lowercases to
1608
- * `onerror` and rejects it, but `removeAttribute('ONERROR')` looks up
1609
- * `onerror` and finds nothing. Remove the exact Attr node instead, which is
1610
- * case- and namespace-exact, and fall back to name-based removal only when
1611
- * the caller could not supply the node.
1612
- *
1613
1592
  * @param name an Attribute name
1614
1593
  * @param element a DOM node
1615
- * @param attr the exact Attr node to remove, when the caller has it
1616
1594
  */
1617
- const _removeAttribute = function _removeAttribute(name, element, attr) {
1618
- if (!attr) try {
1619
- attr = element.getAttributeNode(name);
1620
- } catch (_) {
1621
- attr = null;
1622
- }
1623
- arrayPush(DOMPurify.removed, {
1624
- attribute: attr || null,
1625
- from: element
1626
- });
1595
+ const _removeAttribute = function _removeAttribute(name, element) {
1627
1596
  try {
1628
- if (attr) element.removeAttributeNode(attr);
1629
- else element.removeAttribute(name);
1597
+ arrayPush(DOMPurify.removed, {
1598
+ attribute: element.getAttributeNode(name),
1599
+ from: element
1600
+ });
1630
1601
  } catch (_) {
1631
- try {
1632
- element.removeAttribute(name);
1633
- } catch (_) {}
1602
+ arrayPush(DOMPurify.removed, {
1603
+ attribute: null,
1604
+ from: element
1605
+ });
1634
1606
  }
1607
+ element.removeAttribute(name);
1635
1608
  if (name === "is") if (RETURN_DOM || RETURN_DOM_FRAGMENT) try {
1636
1609
  _forceRemove(element);
1637
1610
  } catch (_) {}
@@ -1656,7 +1629,9 @@ function createDOMPurify() {
1656
1629
  const attribute = attributes[i];
1657
1630
  const name = attribute && attribute.name;
1658
1631
  if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) continue;
1659
- _stripAttributeNode(element, attribute, name);
1632
+ try {
1633
+ element.removeAttribute(name);
1634
+ } catch (_) {}
1660
1635
  }
1661
1636
  };
1662
1637
  /**
@@ -1685,7 +1660,7 @@ function createDOMPurify() {
1685
1660
  const stack = [root];
1686
1661
  while (stack.length > 0) {
1687
1662
  const node = stack.pop();
1688
- if (_readNodeType(node) === NODE_TYPE.element) _stripDisallowedAttributes(node);
1663
+ if ((getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element) _stripDisallowedAttributes(node);
1689
1664
  const childNodes = getChildNodes(node);
1690
1665
  if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push(childNodes[i]);
1691
1666
  }
@@ -1725,28 +1700,12 @@ function createDOMPurify() {
1725
1700
  *
1726
1701
  * @param root the in-place root to sweep
1727
1702
  */
1728
- /**
1729
- * Central policy for declarative-partial-updates patch-linkage attributes,
1730
- * shared by the _neutralizePatchLinkage pre-pass and _isValidAttribute so
1731
- * the two sites cannot drift: `patchsrc` always links, `for` links
1732
- * everywhere except on <label>/<output>, and the whole policy is gated on
1733
- * SAFE_FOR_XML (see the rationale block in _isValidAttribute).
1734
- *
1735
- * @param lcName the transformCaseFunc'd attribute name
1736
- * @param lcTag the transformCaseFunc'd tag name of the carrying element
1737
- * @return true if the attribute is patch linkage and must be dropped
1738
- */
1739
- const _isPatchLinkageAttribute = function _isPatchLinkageAttribute(lcName, lcTag) {
1740
- if (!SAFE_FOR_XML) return false;
1741
- if (lcName === "patchsrc") return true;
1742
- return lcName === "for" && lcTag !== "label" && lcTag !== "output";
1743
- };
1744
1703
  const _neutralizePatchLinkage = function _neutralizePatchLinkage(root) {
1745
1704
  if (!SAFE_FOR_XML) return;
1746
1705
  const stack = [root];
1747
1706
  while (stack.length > 0) {
1748
1707
  const node = stack.pop();
1749
- const nodeType = _readNodeType(node);
1708
+ const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
1750
1709
  if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
1751
1710
  try {
1752
1711
  remove(node);
@@ -1755,10 +1714,10 @@ function createDOMPurify() {
1755
1714
  }
1756
1715
  if (nodeType === NODE_TYPE.element) {
1757
1716
  const element = node;
1758
- const lcTag = transformCaseFunc(_readNodeName(node));
1717
+ const lcTag = transformCaseFunc(getNodeName ? getNodeName(node) : node.nodeName);
1759
1718
  try {
1760
1719
  if (element.hasAttribute && element.hasAttribute("patchsrc")) element.removeAttribute("patchsrc");
1761
- if (element.hasAttribute && element.hasAttribute("for") && _isPatchLinkageAttribute("for", lcTag)) element.removeAttribute("for");
1720
+ if (element.hasAttribute && element.hasAttribute("for") && lcTag !== "label" && lcTag !== "output") element.removeAttribute("for");
1762
1721
  } catch (_) {}
1763
1722
  }
1764
1723
  const childNodes = getChildNodes(node);
@@ -1927,32 +1886,12 @@ function createDOMPurify() {
1927
1886
  */
1928
1887
  const _isUnsafeNode = function _isUnsafeNode(currentNode, tagName) {
1929
1888
  if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) return true;
1930
- if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && LITERAL_TEXT_ELEMENTS[tagName] && (_isNode(currentNode.firstElementChild) || typeof currentNode.textContent === "string" && regExpTest(LITERAL_TEXT_CLOSE[tagName], currentNode.textContent))) return true;
1889
+ if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) return true;
1931
1890
  if (currentNode.nodeType === NODE_TYPE.processingInstruction) return true;
1932
1891
  if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) return true;
1933
1892
  return false;
1934
1893
  };
1935
1894
  /**
1936
- * Evaluate a CUSTOM_ELEMENT_HANDLING check (a RegExp or a predicate
1937
- * function, per the validation in _parseConfig) against a name.
1938
- * Additional arguments are forwarded to predicate functions - the
1939
- * attributeNameCheck predicate receives the tag name as its second
1940
- * argument. A null/absent check never matches.
1941
- *
1942
- * @param check the configured tagNameCheck / attributeNameCheck value
1943
- * @param name the name to test
1944
- * @param args extra arguments forwarded to a predicate function
1945
- * @return true if the check matches the name
1946
- */
1947
- const _matchesNameCheck = function _matchesNameCheck(check, name) {
1948
- if (check instanceof RegExp) return regExpTest(check, name);
1949
- if (check instanceof Function) {
1950
- for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key];
1951
- return Boolean(check(name, ...args));
1952
- }
1953
- return false;
1954
- };
1955
- /**
1956
1895
  * Handle a node whose tag is forbidden or not allowlisted: keep
1957
1896
  * allowed custom elements (false return exits _sanitizeElements
1958
1897
  * early - the namespace and fallback-tag removal checks are
@@ -1970,7 +1909,10 @@ function createDOMPurify() {
1970
1909
  * @return true if the node was removed, false if kept
1971
1910
  */
1972
1911
  const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName, root) {
1973
- if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1912
+ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
1913
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
1914
+ if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
1915
+ }
1974
1916
  if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
1975
1917
  const parentNode = getParentNode(currentNode);
1976
1918
  const childNodes = getChildNodes(currentNode);
@@ -2004,42 +1946,6 @@ function createDOMPurify() {
2004
1946
  return set === defaultSet || set === setConfigSet ? clone(set) : set;
2005
1947
  };
2006
1948
  /**
2007
- * Shared guard for a node that a hook has detached from the walk tree,
2008
- * used after each element-hook site in _sanitizeElements. Detaching is a
2009
- * long-standing user pattern (issue #469; draw.io-style foreignObject
2010
- * filtering). Per the cached, unclobberable parentNode getter the node is
2011
- * genuinely out of the tree, so it can reach neither the serialized
2012
- * output nor an IN_PLACE live tree; treat it as removed and stop
2013
- * processing it. Without this guard, the unsafe-node / namespace checks
2014
- * would call _forceRemove on a parentless node and hit the REPORT-3
2015
- * fail-closed throw — which exists for nodes DOMPurify wants gone but
2016
- * *cannot* detach (clobbered / parentless roots), the opposite of a node
2017
- * that is already safely gone. The walk root is exempt: a detached
2018
- * IN_PLACE root is legitimate input and must still be fully sanitized,
2019
- * and a kill-decision on it must keep hitting the REPORT-3 throw.
2020
- *
2021
- * Nodes detached by hooks stay the hook's responsibility for placement:
2022
- * they are not recorded in DOMPurify.removed, so the post-walk IN_PLACE
2023
- * pass (which iterates DOMPurify.removed) does not reach them. But a
2024
- * hook-detached subtree can still hold a queued resource-event handler -
2025
- * e.g. an <img onload> that began loading when the caller built the live
2026
- * tree - which fires in page scope after sanitize returns even though the
2027
- * handler never reached the returned tree. That is the audit-5 F1 hazard,
2028
- * and the documented node.remove() hook pattern walks straight into it.
2029
- * So on the IN_PLACE path we neutralize the detached subtree inline,
2030
- * stripping its non-allow-listed attributes before returning, exactly as
2031
- * the post-walk pass does for _forceRemove'd subtrees.
2032
- *
2033
- * @param currentNode the node a hook may have detached
2034
- * @param root the current walk root
2035
- * @return true if the node is detached and now handled, false otherwise
2036
- */
2037
- const _handleHookDetachedNode = function _handleHookDetachedNode(currentNode, root) {
2038
- if (currentNode === root || getParentNode(currentNode) !== null) return false;
2039
- if (IN_PLACE) _neutralizeSubtree(currentNode);
2040
- return true;
2041
- };
2042
- /**
2043
1949
  * _sanitizeElements
2044
1950
  *
2045
1951
  * @protect nodeName
@@ -2050,18 +1956,24 @@ function createDOMPurify() {
2050
1956
  */
2051
1957
  const _sanitizeElements = function _sanitizeElements(currentNode, root) {
2052
1958
  _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
2053
- if (_handleHookDetachedNode(currentNode, root)) return true;
1959
+ if (currentNode !== root && getParentNode(currentNode) === null) {
1960
+ if (IN_PLACE) _neutralizeSubtree(currentNode);
1961
+ return true;
1962
+ }
2054
1963
  if (_isClobbered(currentNode)) {
2055
1964
  _forceRemove(currentNode);
2056
1965
  return true;
2057
1966
  }
2058
- const tagName = transformCaseFunc(_readNodeName(currentNode));
1967
+ const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
2059
1968
  ALLOWED_TAGS = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
2060
1969
  _executeHooks(hooks.uponSanitizeElement, currentNode, {
2061
1970
  tagName,
2062
1971
  allowedTags: ALLOWED_TAGS
2063
1972
  });
2064
- if (_handleHookDetachedNode(currentNode, root)) return true;
1973
+ if (currentNode !== root && getParentNode(currentNode) === null) {
1974
+ if (IN_PLACE) _neutralizeSubtree(currentNode);
1975
+ return true;
1976
+ }
2065
1977
  if (_isUnsafeNode(currentNode, tagName)) {
2066
1978
  _forceRemove(currentNode);
2067
1979
  return true;
@@ -2071,7 +1983,7 @@ function createDOMPurify() {
2071
1983
  if (removed === false) _executeHooks(hooks.afterSanitizeElements, currentNode, null);
2072
1984
  return removed;
2073
1985
  }
2074
- if (_readNodeType(currentNode) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
1986
+ if ((getNodeType ? getNodeType(currentNode) : currentNode.nodeType) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
2075
1987
  _forceRemove(currentNode);
2076
1988
  return true;
2077
1989
  }
@@ -2099,17 +2011,20 @@ function createDOMPurify() {
2099
2011
  */
2100
2012
  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
2101
2013
  if (FORBID_ATTR[lcName]) return false;
2102
- if (_isPatchLinkageAttribute(lcName, lcTag)) return false;
2014
+ if (SAFE_FOR_XML && lcName === "patchsrc") return false;
2015
+ if (SAFE_FOR_XML && lcName === "for" && lcTag !== "label" && lcTag !== "output") return false;
2103
2016
  if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document || value in formElement)) return false;
2104
2017
  const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
2105
- if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) return true;
2106
- if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) return true;
2107
- if (!nameIsPermitted) return _isBasicCustomElement(lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName, lcTag) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && _matchesNameCheck(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value);
2108
- if (URI_SAFE_ATTRIBUTES[lcName]) return true;
2109
- if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) return true;
2110
- if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) return true;
2111
- if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) return true;
2112
- return !value;
2018
+ if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName));
2019
+ else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName));
2020
+ else if (!nameIsPermitted) if (_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || 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)));
2021
+ else return false;
2022
+ else if (URI_SAFE_ATTRIBUTES[lcName]);
2023
+ else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
2024
+ else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]);
2025
+ else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
2026
+ else if (value) return false;
2027
+ return true;
2113
2028
  };
2114
2029
  const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [
2115
2030
  "annotation-xml",
@@ -2211,29 +2126,29 @@ function createDOMPurify() {
2211
2126
  _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
2212
2127
  value = hookEvent.attrValue;
2213
2128
  if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
2214
- _removeAttribute(name, currentNode, attr);
2129
+ _removeAttribute(name, currentNode);
2215
2130
  value = SANITIZE_NAMED_PROPS_PREFIX + value;
2216
2131
  }
2217
2132
  if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
2218
- _removeAttribute(name, currentNode, attr);
2133
+ _removeAttribute(name, currentNode);
2219
2134
  continue;
2220
2135
  }
2221
2136
  if (lcName === "attributename" && stringMatch(value, "href")) {
2222
- _removeAttribute(name, currentNode, attr);
2137
+ _removeAttribute(name, currentNode);
2223
2138
  continue;
2224
2139
  }
2225
2140
  if (hookEvent.forceKeepAttr) continue;
2226
2141
  if (!hookEvent.keepAttr) {
2227
- _removeAttribute(name, currentNode, attr);
2142
+ _removeAttribute(name, currentNode);
2228
2143
  continue;
2229
2144
  }
2230
2145
  if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
2231
- _removeAttribute(name, currentNode, attr);
2146
+ _removeAttribute(name, currentNode);
2232
2147
  continue;
2233
2148
  }
2234
2149
  if (SAFE_FOR_TEMPLATES) value = _stripTemplateExpressions(value);
2235
2150
  if (!_isValidAttribute(lcTag, lcName, value)) {
2236
- _removeAttribute(name, currentNode, attr);
2151
+ _removeAttribute(name, currentNode);
2237
2152
  continue;
2238
2153
  }
2239
2154
  value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
@@ -2255,7 +2170,7 @@ function createDOMPurify() {
2255
2170
  _sanitizeElements(shadowNode, fragment);
2256
2171
  _sanitizeAttributes(shadowNode);
2257
2172
  if (_isDocumentFragment(shadowNode.content)) _sanitizeShadowDOM2(shadowNode.content);
2258
- if (_readNodeType(shadowNode) === NODE_TYPE.element) {
2173
+ if ((getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType) === NODE_TYPE.element) {
2259
2174
  const innerSr = getShadowRoot(shadowNode);
2260
2175
  if (_isDocumentFragment(innerSr)) {
2261
2176
  _sanitizeAttachedShadowRoots(innerSr);
@@ -2296,7 +2211,7 @@ function createDOMPurify() {
2296
2211
  continue;
2297
2212
  }
2298
2213
  const node = item.node;
2299
- const isElement = _readNodeType(node) === NODE_TYPE.element;
2214
+ const isElement = (getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element;
2300
2215
  const childNodes = getChildNodes(node);
2301
2216
  if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push({
2302
2217
  node: childNodes[i],
@@ -2347,7 +2262,7 @@ function createDOMPurify() {
2347
2262
  const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
2348
2263
  if (inPlace) {
2349
2264
  _neutralizePatchLinkage(dirty);
2350
- const nn = _readNodeName(dirty);
2265
+ const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
2351
2266
  if (typeof nn === "string") {
2352
2267
  const tagName = transformCaseFunc(nn);
2353
2268
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
@@ -2498,6 +2413,7 @@ function _resetSanitizeForTests() {
2498
2413
  hookInstalled = false;
2499
2414
  }
2500
2415
  //#endregion
2416
+ exports.IconGlyph = IconGlyph;
2501
2417
  exports._resetSanitizeForTests = _resetSanitizeForTests;
2502
2418
  exports.buildMarkdownDocView = buildMarkdownDocView;
2503
2419
  exports.formatScalarField = formatScalarField;