weapp-tailwindcss 5.1.12 → 5.1.14

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 (46) hide show
  1. package/dist/bundlers/vite/css-finalizer.d.ts +1 -0
  2. package/dist/bundlers/vite/frameworks/taro/index.d.ts +2 -0
  3. package/dist/bundlers/vite/frameworks/uni-app/index.d.ts +2 -0
  4. package/dist/bundlers/vite/frameworks/uni-app-x/index.d.ts +2 -0
  5. package/dist/bundlers/vite/generate-bundle/remembered-css-replay.d.ts +3 -0
  6. package/dist/bundlers/vite/generate-bundle/root-style-output.d.ts +18 -0
  7. package/dist/bundlers/vite/generate-bundle/types.d.ts +2 -0
  8. package/dist/bundlers/vite/serve-root-import-shell.d.ts +8 -0
  9. package/dist/bundlers/vite/source-candidates.d.ts +3 -0
  10. package/dist/{context-xSJE588m.mjs → context-BL8Gy71H.mjs} +5 -3
  11. package/dist/{context-DRRgW7i2.js → context-VeFq_8vW.js} +5 -3
  12. package/dist/core.js +1 -1
  13. package/dist/core.mjs +1 -1
  14. package/dist/{generator-BvPcmqxU.mjs → generator-B59OA64h.mjs} +17 -3
  15. package/dist/{generator-CS10c9g1.js → generator-CEnUsjed.js} +17 -3
  16. package/dist/generator.js +1 -1
  17. package/dist/generator.mjs +1 -1
  18. package/dist/{gulp-DNZZvUMq.js → gulp-C1Q3LRzg.js} +9 -5
  19. package/dist/{gulp-BEOzXrbp.mjs → gulp-DUYWxmZC.mjs} +9 -5
  20. package/dist/gulp.js +1 -1
  21. package/dist/gulp.mjs +1 -1
  22. package/dist/{hmr-timing-DW1g3zjl.js → hmr-timing-BZ5sWIqO.js} +104 -14
  23. package/dist/{hmr-timing-hRhRAjYV.mjs → hmr-timing-C3ed5vCx.mjs} +105 -15
  24. package/dist/index.js +4 -4
  25. package/dist/index.mjs +4 -4
  26. package/dist/postcss.js +1 -1
  27. package/dist/postcss.mjs +1 -1
  28. package/dist/presets.js +1 -1
  29. package/dist/presets.mjs +1 -1
  30. package/dist/rspack.js +1 -1
  31. package/dist/rspack.mjs +1 -1
  32. package/dist/{source-candidate-scan-signature-t4XKAQ04.mjs → source-candidate-scan-signature-D7RWjWsY.mjs} +17 -44
  33. package/dist/{source-candidate-scan-signature-CMgu5bJk.js → source-candidate-scan-signature-R3dzamcm.js} +17 -44
  34. package/dist/tailwindcss/candidates.d.ts +4 -0
  35. package/dist/{tailwindcss-DZT_pWrd.mjs → tailwindcss-DPcKMLxL.mjs} +1 -1
  36. package/dist/{tailwindcss-z9JMF-qU.js → tailwindcss-KBYPJ2DW.js} +1 -1
  37. package/dist/{vite-VGfkFQkC.js → vite-BNlPdsGM.js} +272 -59
  38. package/dist/{vite-DF1gE6a5.mjs → vite-CBU5NXTX.mjs} +272 -59
  39. package/dist/vite.js +1 -1
  40. package/dist/vite.mjs +1 -1
  41. package/dist/weapp-tw-css-import-rewrite-loader.js +2061 -15
  42. package/dist/{webpack-CTYm19zA.mjs → webpack-CZ38fMGC.mjs} +10 -6
  43. package/dist/{webpack-CzXjfvYS.js → webpack-Jpe048pQ.js} +10 -6
  44. package/dist/webpack.js +1 -1
  45. package/dist/webpack.mjs +1 -1
  46. package/package.json +2 -2
@@ -72,7 +72,7 @@ function stripBundlerGeneratedCssMarkers(source) {
72
72
  //#region src/bundlers/shared/generator-css/markers.ts
73
73
  const TAILWIND_V4_BANNER_RE = /\/\*!\s*tailwindcss v4\./;
74
74
  const TAILWIND_ESCAPED_UTILITY_MARKER_RE = /\.[^,{]{0,512}(?:\\:|\\\[|\\#)/;
75
- const TAILWIND_ROOT_THEME_MARKER_RE = /(?::host|page|\.tw-root|wx-root-portal-content)[^{]{0,256}\{[^}]{0,4096}--(?:color|spacing|text|font-weight|radius)-/;
75
+ const TAILWIND_ROOT_THEME_MARKER_RE = /(?::root\s*,\s*:host|:host\s*,\s*page\s*,\s*\.tw-root\s*,\s*wx-root-portal-content)[^{]{0,256}\{[^}]{0,4096}(?:--spacing\b|--(?:color|text|font|default|radius)-)/;
76
76
  const GENERATOR_PLACEHOLDER_MARKER_RE = /\/\*!\s*weapp-tailwindcss generator-placeholder\s*\*\//i;
77
77
  const GENERATOR_PLACEHOLDER_MARKER_GLOBAL_RE = /\/\*!\s*weapp-tailwindcss generator-placeholder\s*\*\/\s*/gi;
78
78
  const TAILWIND_BANNER_PREFIX_RE = /^\/\*!\s*tailwindcss v[^*]*\*\/\s*/i;
@@ -138,7 +138,7 @@ function hasTailwindGeneratedCss(rawSource) {
138
138
  }
139
139
  function hasTailwindGeneratedCssMarkers(rawSource) {
140
140
  if (rawSource.includes("--tw-") || rawSource.includes("tailwindcss v") || rawSource.includes(":not(#\\#)") || GENERATOR_PLACEHOLDER_MARKER_RE.test(rawSource)) return true;
141
- if (!rawSource.includes("\\:") && !rawSource.includes("\\[") && !rawSource.includes("\\#") && !rawSource.includes("--color-") && !rawSource.includes("--spacing-") && !rawSource.includes("--text-") && !rawSource.includes("--font-weight-") && !rawSource.includes("--radius-")) return false;
141
+ if (!rawSource.includes("\\:") && !rawSource.includes("\\[") && !rawSource.includes("\\#") && !rawSource.includes("--color-") && !rawSource.includes("--spacing") && !rawSource.includes("--text-") && !rawSource.includes("--font-") && !rawSource.includes("--font-weight-") && !rawSource.includes("--default-") && !rawSource.includes("--radius-")) return false;
142
142
  return TAILWIND_ESCAPED_UTILITY_MARKER_RE.test(rawSource) || TAILWIND_ROOT_THEME_MARKER_RE.test(rawSource);
143
143
  }
144
144
  //#endregion
@@ -1952,8 +1952,22 @@ function removeTailwindV4GeneratorAtRulesFallback(source) {
1952
1952
  function isTailwindGeneratedPreflightComment(text) {
1953
1953
  return text.includes("cssremedy") || text.includes("Use the user's configured") || text.includes("tailwindlabs/tailwindcss") || text.includes("Prevent padding and border from affecting element width") || text.includes("Remove default margins and padding") || text.includes("Deprecated") || text.includes("Reset all borders") || text.includes("Add the correct text decoration") || text.includes("Make elements with the HTML hidden attribute stay hidden") || text.includes("Inherit font styles in all browsers") || text.includes("Add the correct height in Firefox") || text.includes("Remove the default font size and weight for headings") || text.includes("Reset links to optimize for opt-in styling") || text.includes("Add the correct font weight in Edge and Safari") || text.includes("Use the user's configured `mono` font-family") || text.includes("Add the correct font size in all browsers") || text.includes("Prevent `sub` and `sup` elements from affecting the line height") || text.includes("Remove text indentation from table contents") || text.includes("Use the modern Firefox focus style") || text.includes("Add the correct vertical alignment") || text.includes("Add the correct display") || text.includes("Make lists unstyled by default") || text.includes("Make replaced elements `display: block` by default") || text.includes("Constrain images and videos to the parent width") || text.includes("Restore default font weight") || text.includes("Restore indentation") || text.includes("Restore space after button") || text.includes("Prevent resizing textareas horizontally") || text.includes("Remove the inner padding in Chrome and Safari") || text.includes("Ensure date/time inputs have the same height") || text.includes("Prevent height from changing on date/time inputs") || text.includes("Remove excess padding from pseudo-elements") || text.includes("Center dropdown marker shown on inputs") || text.includes("Remove the additional `:invalid` styles") || text.includes("Correct the inability to style the border radius") || text.includes("Correct the cursor style of increment and decrement buttons");
1954
1954
  }
1955
+ const TAILWIND_GENERATED_THEME_SCOPE_SELECTORS = /* @__PURE__ */ new Set([
1956
+ ":host",
1957
+ ":root",
1958
+ "page",
1959
+ ".tw-root",
1960
+ "wx-root-portal-content"
1961
+ ]);
1962
+ function isTailwindGeneratedThemeScopeSelector(selector) {
1963
+ const selectors = selector.split(",").map((item) => item.trim()).filter(Boolean);
1964
+ const selectorSet = new Set(selectors);
1965
+ if (selectorSet.size !== selectors.length) return false;
1966
+ if (!selectors.every((item) => TAILWIND_GENERATED_THEME_SCOPE_SELECTORS.has(item))) return false;
1967
+ return selectorSet.size === 2 && selectorSet.has(":root") && selectorSet.has(":host") || selectorSet.size === 4 && selectorSet.has(":host") && selectorSet.has("page") && selectorSet.has(".tw-root") && selectorSet.has("wx-root-portal-content");
1968
+ }
1955
1969
  function isTailwindGeneratedThemeRule(selector, node) {
1956
- if (!/(?:^|,)\s*(?::host|page|\.tw-root|wx-root-portal-content)\b/.test(selector)) return false;
1970
+ if (!isTailwindGeneratedThemeScopeSelector(selector)) return false;
1957
1971
  return node.nodes?.some((child) => child.type === "decl" && /^--(?:color|spacing|text|font|default|radius|tw-)/.test(child.prop)) ?? false;
1958
1972
  }
1959
1973
  function isTailwindGeneratedPreflightRule(selector, node) {
@@ -3339,6 +3353,44 @@ function mergeGeneratorResults(generatedResults) {
3339
3353
  };
3340
3354
  }
3341
3355
  //#endregion
3356
+ //#region src/wxml/custom-attributes.ts
3357
+ function regTest(reg, str) {
3358
+ reg.lastIndex = 0;
3359
+ return reg.test(str);
3360
+ }
3361
+ function isPropsMatch(props, attr) {
3362
+ if (Array.isArray(props)) {
3363
+ let lowerAttr;
3364
+ for (const prop of props) if (typeof prop === "string") {
3365
+ lowerAttr ??= attr.toLowerCase();
3366
+ if (prop.toLowerCase() === lowerAttr) return true;
3367
+ } else if (regTest(prop, attr)) return true;
3368
+ return false;
3369
+ } else if (typeof props === "string") return props === attr;
3370
+ else return regTest(props, attr);
3371
+ }
3372
+ function createAttributeMatcher(entities) {
3373
+ if (!entities || entities.length === 0) return;
3374
+ const wildcardAttributeRules = [];
3375
+ const tagAttributeRuleMap = /* @__PURE__ */ new Map();
3376
+ const regexpAttributeRules = [];
3377
+ for (const [selector, props] of entities) if (selector === "*") wildcardAttributeRules.push(props);
3378
+ else if (typeof selector === "string") {
3379
+ const list = tagAttributeRuleMap.get(selector);
3380
+ if (list) list.push(props);
3381
+ else tagAttributeRuleMap.set(selector, [props]);
3382
+ } else regexpAttributeRules.push([selector, props]);
3383
+ return (tag, attr) => {
3384
+ for (const props of wildcardAttributeRules) if (isPropsMatch(props, attr)) return true;
3385
+ const tagRules = tagAttributeRuleMap.get(tag);
3386
+ if (tagRules) {
3387
+ for (const props of tagRules) if (isPropsMatch(props, attr)) return true;
3388
+ }
3389
+ for (const [selector, props] of regexpAttributeRules) if (regTest(selector, tag) && isPropsMatch(props, attr)) return true;
3390
+ return false;
3391
+ };
3392
+ }
3393
+ //#endregion
3342
3394
  //#region src/babel/index.ts
3343
3395
  function _interopDefaultCompat(e) {
3344
3396
  return e && typeof e === "object" && "default" in e ? e.default : e;
@@ -3780,6 +3832,1906 @@ function replaceHandleValue(path, options) {
3780
3832
  }
3781
3833
  Object.freeze({ wrapExpression: true });
3782
3834
  //#endregion
3835
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/decode-codepoint.js
3836
+ const decodeMap = /* @__PURE__ */ new Map([
3837
+ [0, 65533],
3838
+ [128, 8364],
3839
+ [130, 8218],
3840
+ [131, 402],
3841
+ [132, 8222],
3842
+ [133, 8230],
3843
+ [134, 8224],
3844
+ [135, 8225],
3845
+ [136, 710],
3846
+ [137, 8240],
3847
+ [138, 352],
3848
+ [139, 8249],
3849
+ [140, 338],
3850
+ [142, 381],
3851
+ [145, 8216],
3852
+ [146, 8217],
3853
+ [147, 8220],
3854
+ [148, 8221],
3855
+ [149, 8226],
3856
+ [150, 8211],
3857
+ [151, 8212],
3858
+ [152, 732],
3859
+ [153, 8482],
3860
+ [154, 353],
3861
+ [155, 8250],
3862
+ [156, 339],
3863
+ [158, 382],
3864
+ [159, 376]
3865
+ ]);
3866
+ /**
3867
+ * Replace the given code point with a replacement character if it is a
3868
+ * surrogate or is outside the valid range. Otherwise return the code
3869
+ * point unchanged.
3870
+ * @param codePoint Unicode code point to convert.
3871
+ */
3872
+ function replaceCodePoint(codePoint) {
3873
+ if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) return 65533;
3874
+ return decodeMap.get(codePoint) ?? codePoint;
3875
+ }
3876
+ //#endregion
3877
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/internal/decode-shared.js
3878
+ /**
3879
+ * Shared base64 decode helper for generated decode data.
3880
+ * Assumes global atob is available.
3881
+ * @param input Input string to encode or decode.
3882
+ */
3883
+ function decodeBase64(input) {
3884
+ const binary = atob(input);
3885
+ const evenLength = binary.length & -2;
3886
+ const out = new Uint16Array(evenLength / 2);
3887
+ for (let index = 0, outIndex = 0; index < evenLength; index += 2) {
3888
+ const lo = binary.charCodeAt(index);
3889
+ const hi = binary.charCodeAt(index + 1);
3890
+ out[outIndex++] = lo | hi << 8;
3891
+ }
3892
+ return out;
3893
+ }
3894
+ //#endregion
3895
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/generated/decode-data-html.js
3896
+ /** Packed HTML decode trie data. */
3897
+ const htmlDecodeTree = /* #__PURE__ */ decodeBase64("QR08ALkAAgH6AYsDNQR2BO0EPgXZBQEGLAbdBxMISQrvCmQLfQurDKQNLw4fD4YPpA+6D/IPAAAAAAAAAAAAAAAAKhBMEY8TmxUWF2EYLBkxGuAa3RsJHDscWR8YIC8jSCSIJcMl6ie3Ku8rEC0CLjoupS7kLgAIRU1hYmNmZ2xtbm9wcnN0dVQAWgBeAGUAaQBzAHcAfgCBAIQAhwCSAJoAoACsALMAbABpAGcAO4DGAMZAUAA7gCYAJkBjAHUAdABlADuAwQDBQHIiZXZlAAJhAAFpeW0AcgByAGMAO4DCAMJAEGRyAADgNdgE3XIAYQB2AGUAO4DAAMBA8CFoYZFj4SFjcgBhZAAAoFMqAAFncIsAjgBvAG4ABGFmAADgNdg43fAlbHlGdW5jdGlvbgCgYSBpAG4AZwA7gMUAxUAAAWNzpACoAHIAAOA12Jzc6SFnbgCgVCJpAGwAZABlADuAwwDDQG0AbAA7gMQAxEAABGFjZWZvcnN1xQDYANoA7QDxAPYA+QD8AAABY3LJAM8AayNzbGFzaAAAoBYidgHTANUAAKDnKmUAZAAAoAYjeQARZIABY3J0AOAA5QDrAGEidXNlAACgNSLuI291bGxpcwCgLCFhAJJjcgAA4DXYBd1wAGYAAOA12Dnd5SF2ZdhiYwDyAOoAbSJwZXEAAKBOIgAHSE9hY2RlZmhpbG9yc3UXARoBHwE6AVIBVQFiAWQBZgGCAakB6QHtAfIBYwB5ACdkUABZADuAqQCpQIABY3B5ACUBKAE1AfUhdGUGYWmg0iJ0KGFsRGlmZmVyZW50aWFsRAAAoEUhbCJleXMAAKAtIQACYWVpb0EBRAFKAU0B8iFvbgxhZABpAGwAO4DHAMdAcgBjAAhhbiJpbnQAAKAwIm8AdAAKYQABZG5ZAV0BaSJsbGEAuGB0I2VyRG90ALdg8gA5AWkAp2NyImNsZQAAAkRNUFRwAXQBeQF9AW8AdAAAoJkiaSJudXMAAKCWIuwhdXMAoJUiaSJtZXMAAKCXIm8AAAFjc4cBlAFrKndpc2VDb250b3VySW50ZWdyYWwAAKAyImUjQ3VybHkAAAFEUZwBpAFvJXVibGVRdW90ZQAAoB0gdSJvdGUAAKAZIAACbG5wdbABtgHNAdgBbwBuAGWgNyIAoHQqgAFnaXQAvAHBAcUB8iJ1ZW50AKBhIm4AdAAAoC8i7yV1ckludGVncmFsAKAuIgABZnLRAdMBAKACIe8iZHVjdACgECJuLnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbAAAoDMi7yFzcwCgLypjAHIAAOA12J7ccABDoNMiYQBwAACgTSKABURKU1phY2VmaW9zAAsCEgIVAhgCGwIsAjQCOQI9AnMCfwNvoEUh9CJyYWhkAKARKWMAeQACZGMAeQAFZGMAeQAPZIABZ3JzACECJQIoAuchZXIAoCEgcgAAoKEhaAB2AACg5CoAAWF5MAIzAvIhb24OYRRkbAB0oAciYQCUY3IAAOA12AfdAAFhZkECawIAAWNtRQJnAvIjaXRpY2FsAAJBREdUUAJUAl8CYwJjInV0ZQC0YG8AdAFZAloC2WJiJGxlQWN1dGUA3WJyImF2ZQBgYGkibGRlANxi7yFuZACgxCJmJWVyZW50aWFsRAAAoEYhcAR9AgAAAAAAAIECjgIAABoDZgAA4DXYO91EoagAhQKJAm8AdAAAoNwgcSJ1YWwAAKBQIuIhbGUAA0NETFJVVpkCqAK1Au8C/wIRA28AbgB0AG8AdQByAEkAbgB0AGUAZwByAGEA7ADEAW8AdAKvAgAAAACwAqhgbiNBcnJvdwAAoNMhAAFlb7kC0AJmAHQAgAFBUlQAwQLGAs0CciJyb3cAAKDQIekkZ2h0QXJyb3cAoNQhZQDlACsCbgBnAAABTFLWAugC5SFmdAABQVLcAuECciJyb3cAAKD4J+kkZ2h0QXJyb3cAoPon6SRnaHRBcnJvdwCg+SdpImdodAAAAUFU9gL7AnIicm93AACg0iFlAGUAAKCoInAAQQIGAwAAAAALA3Iicm93AACg0SFvJHduQXJyb3cAAKDVIWUlcnRpY2FsQmFyAACgJSJuAAADQUJMUlRhJAM2AzoDWgNxA3oDciJyb3cAAKGTIUJVLAMwA2EAcgAAoBMpcCNBcnJvdwAAoPUhciJldmUAEWPlIWZ00gJDAwAASwMAAFIDaSVnaHRWZWN0b3IAAKBQKWUkZVZlY3RvcgAAoF4p5SJjdG9yQqC9IWEAcgAAoFYpaSJnaHQA1AFiAwAAaQNlJGVWZWN0b3IAAKBfKeUiY3RvckKgwSFhAHIAAKBXKWUAZQBBoKQiciJyb3cAAKCnIXIAcgBvAPcAtAIAAWN0gwOHA3IA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YwAAoN8i4SFycnCgtiEAoD0pgKIqImJjZG9zACsVMBU6FT4VQRVyImNhcAAAoEgqAAFhdTQVNxVwAACgRipwAACgSipvAHQAAKCNInIAAKBFKgDgKiIA/gACYWxydksVURVuFXMVcgByAG2gtyEAoDwpeQCAAWV2dwBYFWUVaRVxAHACXxUAAAAAYxVyAGUA4wAXFXUA4wAZFWUAZQAAoM4iZSJkZ2UAAKDPImUAbgA7gKQApEBlI2Fycm93AAABbHJ7FX8V5SFmdACgtiFpImdodAAAoLchZQDkAG0VAAFjaYsVkRVvAG4AaQBuAPQAkwFuAHQAAKAxImwiY3R5AACgLSOACUFIYWJjZGVmaGlqbG9yc3R1d3oAuBW7Fb8V1RXgFegV+RUKFhUWHxZUFlcWZRbFFtsW7xb7FgUXChdyAPIAtAJhAHIAAKBlKQACZ2xyc8YVyhXOFdAV5yFlcgCgICDlIXRoAKA4IfIA9QxoAHagECAAoKMiawHZFd4VYSJyb3cAAKAPKWEA4wBfAgABYXnkFecV8iFvbg9hNGQAoUYhYW/tFfQVAAFnciEC8RVyAACgyiF0InNlcQAAoHcqgAFnbG0A/xUCFgUWO4CwALBAdABhALRjcCJ0eXYAAKCxKQABaXIOFhIW8yFodACgfykA4DXYId1hAHIAAAFschsWHRYAoMMhAKDCIYACYWVnc3YAKBauAjYWOhY+Fm0AAKHEIm9zLhY0Fm4AZABzoMQi9SFpdACgZiZhIm1tYQDdY2kAbgAAoPIiAKH3AGlvQxZRFmQAZQAAgfcAO29KFksW90BuI3RpbWVzAACgxyJuAPgAUBZjAHkAUmRjAG8CXhYAAAAAYhZyAG4AAKAeI28AcAAAoA0jgAJscHR1dwBuFnEWdRaSFp4W7CFhciRgZgAA4DXYVd0AotkCZW1wc30WhBaJFo0WcQBkoFAibwB0AACgUSJpIm51cwAAoDgi7CF1cwCgFCLxInVhcmUAoKEiYgBsAGUAYgBhAHIAdwBlAGQAZwDlANcAbgCAAWFkaAClFqoWtBZyAHIAbwD3APUMbwB3AG4AYQByAHIAbwB3APMA8xVhI3Jwb29uAAABbHK8FsAWZQBmAPQAHBZpAGcAaAD0AB4WYgHJFs8WawBhAHIAbwD3AJILbwLUFgAAAADYFnIAbgAAoB8jbwBwAACgDCOAAWNvdADhFukW7BYAAXJ55RboFgDgNdi53FVkbAAAoPYp8iFvaxFhAAFkcvMW9xZvAHQAAKDxImkA5qC/JVsSAAFhaP8WAhdyAPIANQNhAPIA1wvhIm5nbGUAoKYpAAFjaQ4XEBd5AF9k5yJyYXJyAKD/JwAJRGFjZGVmZ2xtbm9wcXJzdHV4MRc4F0YXWxcyBF4XaRd5F40XrBe0F78X2RcVGCEYLRg1GEAYAAFEbzUXgRZvAPQA+BUAAWNzPBdCF3UAdABlADuA6QDpQPQhZXIAoG4qAAJhaW95TRdQF1YXWhfyIW9uG2FyAGOgViI7gOoA6kDsIW9uAKBVIk1kbwB0ABdhAAFEcmIXZhdvAHQAAKBSIgDgNdgi3XKhmipuF3QXYQB2AGUAO4DoAOhAZKCWKm8AdAAAoJgqgKGZKmlscwCAF4UXhxfuInRlcnMAoOcjAKATIWSglSpvAHQAAKCXKoABYXBzAJMXlheiF2MAcgATYXQAeQBzogUinxcAAAAAoRdlAHQAAKAFInAAMaADIDMBqRerFwCgBCAAoAUgAAFnc7AXsRdLYXAAAKACIAABZ3C4F7sXbwBuABlhZgAA4DXYVt2AAWFscwDFF8sXzxdyAHOg1SJsAACg4yl1AHMAAKBxKmkAAKG1A2x21RfYF28AbgC1Y/VjAAJjc3V24BfoF/0XEBgAAWlv5BdWF3IAYwAAoFYiaQLuFwAAAADwF+0ADQThIW50AAFnbPUX+Rd0AHIAAKCWKuUhc3MAoJUqgAFhZWkAAxgGGAoYbABzAD1gcwB0AACgXyJ2AESgYSJEAACgeCrwImFyc2wAoOUpAAFEYRkYHRhvAHQAAKBTInIAcgAAoHEpgAFjZGkAJxgqGO0XcgAAoC8hbwD0AIwCAAFhaDEYMhi3YzuA8ADwQAABbXI5GD0YbAA7gOsA60BvAACgrCCAAWNpcABGGEgYSxhsACFgcwD0ACwEAAFlb08YVxhjAHQAYQB0AGkAbwDuABoEbgBlAG4AdABpAGEAbADlADME4Ql1GAAAgRgAAIMYiBgAAAAAoRilGAAAqhgAALsYvhjRGAAA1xgnGWwAbABpAG4AZwBkAG8AdABzAGUA8QBlF3kARGRtImFsZQAAoEAmgAFpbHIAjRiRGJ0Y7CFpZwCgA/tpApcYAAAAAJoYZwAAoAD7aQBnAACgBPsA4DXYI93sIWlnAKAB++whaWcA4GYAagCAAWFsdACvGLIYthh0AACgbSZpAGcAAKAC+24AcwAAoLElbwBmAJJh8AHCGAAAxhhmAADgNdhX3QABYWvJGMwYbADsAGsEdqDUIgCg2SphI3J0aW50AACgDSoAAWFv2hgiGQABY3PeGB8ZsQPnGP0YBRkSGRUZAAAdGbID7xjyGPQY9xj5GAAA+xg7gL0AvUAAoFMhO4C8ALxAAKBVIQCgWSEAoFshswEBGQAAAxkAoFQhAKBWIbQCCxkOGQAAAAAQGTuAvgC+QACgVyEAoFwhNQAAoFghtgEZGQAAGxkAoFohAKBdITgAAKBeIWwAAKBEIHcAbgAAoCIjYwByAADgNdi73IAIRWFiY2RlZmdpamxub3JzdHYARhlKGVoZXhlmGWkZkhmWGZkZnRmgGa0ZxhnLGc8Z4BkjGmygZyIAoIwqgAFjbXAAUBlTGVgZ9SF0ZfVhbQBhAOSgswM6FgCghipyImV2ZQAfYQABaXliGWUZcgBjAB1hM2RvAHQAIWGAoWUibHFzAMYEcBl6GfGhZSLOBAAAdhlsAGEAbgD0AN8EgKF+KmNkbACBGYQZjBljAACgqSpvAHQAb6CAKmyggioAoIQqZeDbIgD+cwAAoJQqcgAA4DXYJN3noGsirATtIWVsAKA3IWMAeQBTZIChdyJFYWoApxmpGasZAKCSKgCgpSoAoKQqAAJFYWVztBm2Gb0ZwhkAoGkicABwoIoq8iFveACgiipxoIgq8aCIKrUZaQBtAACg5yJwAGYAAOA12FjdYQB2AOUAYwIAAWNp0xnWGXIAAKAKIW0AAKFzImVs3BneGQCgjioAoJAqAIM+ADtjZGxxco0E6xn0GfgZ/BkBGgABY2nvGfEZAKCnKnIAAKB6Km8AdAAAoNci0CFhcgCglSl1ImVzdAAAoHwqgAJhZGVscwAKGvQZFhrVBCAa8AEPGgAAFBpwAHIAbwD4AFkZcgAAoHgpcQAAAWxxxAQbGmwAZQBzAPMASRlpAO0A5AQAAWVuJxouGnIjdG5lcXEAAOBpIgD+xQAsGgAFQWFiY2Vma29zeUAaQxpmGmoabRqDGocalhrCGtMacgDyAMwCAAJpbG1yShpOGlAaVBpyAHMA8ABxD2YAvWBpAGwA9AASBQABZHJYGlsaYwB5AEpkAKGUIWN3YBpkGmkAcgAAoEgpAKCtIWEAcgAAoA8h6SFyYyVhgAFhbHIAcxp7Gn8a8iF0c3WgZSZpAHQAAKBlJuwhaXAAoCYg4yFvbgCguSJyAADgNdgl3XMAAAFld4wakRphInJvdwAAoCUpYSJyb3cAAKAmKYACYW1vcHIAnxqjGqcauhq+GnIAcgAAoP8h9CFodACgOyJrAAABbHKsGrMaZSRmdGFycm93AACgqSHpJGdodGFycm93AKCqIWYAAOA12Fnd4iFhcgCgFSCAAWNsdADIGswa0BpyAADgNdi93GEAcwDoAGka8iFvaydhAAFicNca2xr1IWxsAKBDIOghZW4AoBAg4Qr2GgAA/RoAAAgbExsaGwAAIRs7GwAAAAA+G2IbmRuVG6sbAACyG80b0htjAHUAdABlADuA7QDtQAChYyBpeQEbBhtyAGMAO4DuAO5AOGQAAWN4CxsNG3kANWRjAGwAO4ChAKFAAAFmcssCFhsA4DXYJt1yAGEAdgBlADuA7ADsQIChSCFpbm8AJxsyGzYbAAFpbisbLxtuAHQAAKAMKnQAAKAtIuYhaW4AoNwpdABhAACgKSHsIWlnM2GAAWFvcABDG1sbXhuAAWNndABJG0sbWRtyACthgAFlbHAAcQVRG1UbaQBuAOUAyAVhAHIA9AByBWgAMWFmAACgtyJlAGQAtWEAoggiY2ZvdGkbbRt1G3kb4SFyZQCgBSFpAG4AdKAeImkAZQAAoN0pZABvAPQAWxsAoisiY2VscIEbhRuPG5QbYQBsAACguiIAAWdyiRuNG2UAcgDzACMQ4wCCG2EicmhrAACgFyryIW9kAKA8KgACY2dwdJ8boRukG6gbeQBRZG8AbgAvYWYAAOA12FrdYQC5Y3UAZQBzAHQAO4C/AL9AAAFjabUbuRtyAADgNdi+3G4AAKIIIkVkc3bCG8QbyBvQAwCg+SJvAHQAAKD1Inag9CIAoPMiaaBiIOwhZGUpYesB1hsAANkbYwB5AFZkbAA7gO8A70AAA2NmbW9zdeYb7hvyG/Ub+hsFHAABaXnqG+0bcgBjADVhOWRyAADgNdgn3eEhdGg3YnAAZgAA4DXYW93jAf8bAAADHHIAAOA12L/c8iFjeVhk6yFjeVRkAARhY2ZnaGpvcxUcGhwiHCYcKhwtHDAcNRzwIXBhdqC6A/BjAAFleR4cIRzkIWls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ZmdobG1vcHJzdHV3CiwNLBEsHSwnLDEsQCxLLFIsYix6LIQsjyzLLOgs7Sz/LAotcgDyAAkDYQByAACgYykAAWNyFSwbLHUAdABlADuA+gD6QPIACQ1yAOMBIywAACUseQBeZHYAZQBtYQABaXkrLDAscgBjADuA+wD7QENkgAFhYmgANyw6LD0scgDyANEO7CFhY3FhYQDyAOAOAAFpckQsSCzzIWh0AKB+KQDgNdgy3XIAYQB2AGUAO4D5APlAYQFWLF8scgAAAWxyWixcLACgvyEAoL4hbABrAACggCUAAWN0Zix2LG8CbCwAAAAAcyxyAG4AZaAcI3IAAKAcI28AcAAAoA8jcgBpAACg+CUAAWFsfiyBLGMAcgBrYTuAqACoQAABZ3CILIssbwBuAHNhZgAA4DXYZt0AA2FkaGxzdZksniynLLgsuyzFLHIAcgBvAPcACQ1vAHcAbgBhAHIAcgBvAPcA2A5hI3Jwb29uAAABbHKvLLMsZQBmAPQAWyxpAGcAaAD0AF0sdQDzAKYOaQAAocUDaGzBLMIs0mNvAG4AxWPwI2Fycm93cwCgyCGAAWNpdADRLOEs5CxvAtcsAAAAAN4scgBuAGWgHSNyAACgHSNvAHAAAKAOI24AZwBvYXIAaQAAoPklYwByAADgNdjK3IABZGlyAPMs9yz6LG8AdAAAoPAi7CFkZWlhaQBmoLUlAKC0JQABYW0DLQYtcgDyAMosbAA7gPwA/EDhIm5nbGUAoKcpgAdBQkRhY2RlZmxub3Byc3oAJy0qLTAtNC2bLZ0toS2/LcMtxy3TLdgt3C3gLfwtcgDyABADYQByAHag6CoAoOkqYQBzAOgA/gIAAW5yOC08LechcnQAoJwpgANla25wcnN0AJkpSC1NLVQtXi1iLYItYQBwAHAA4QAaHG8AdABoAGkAbgDnAKEXgAFoaXIAoSmzJFotbwBwAPQAdCVooJUh7wD4JgABaXVmLWotZwBtAOEAuygAAWJwbi14LXMjZXRuZXEAceCKIgD+AODLKgD+cyNldG5lcQBx4IsiAP4A4MwqAP4AAWhyhi2KLWUAdADhABIraSNhbmdsZQAAAWxyki2WLeUhZnQAoLIiaSJnaHQAAKCzInkAMmThIXNoAKCiIoABZWxyAKcttC24LWKiKCKuLQAAAACyLWEAcgAAoLsicQAAoFoi7CFpcACg7iIAAWJ0vC1eD2EA8gBfD3IAAOA12DPddAByAOkAlS1zAHUAAAFicM0t0C0A4IIi0iAA4IMi0iBwAGYAAOA12GfdcgBvAPAAWQt0AHIA6QCaLQABY3XkLegtcgAA4DXYy9wAAWJw7C30LW4AAAFFZXUt8S0A4IoiAP5uAAABRWV/LfktAOCLIgD+6SJnemFnAKCaKYADY2Vmb3BycwANLhAuJS4pLiMuLi40LukhcmN1YQABZGkULiEuAAFiZxguHC5hAHIAAKBfKmUAcaAnIgCgWSLlIXJwAKAYIXIAAOA12DTdcABmAADgNdho3WWgQCJhAHQA6ABqD2MAcgAA4DXYzNzjCuQRUC4AAFQuAABYLmIuAAAAAGMubS5wLnQuAAAAAIguki4AAJouJxIqEnQAcgDpAB0ScgAA4DXYNd0AAUFhWy5eLnIA8gDnAnIA8gCTB75jAAFBYWYuaS5yAPIA4AJyAPIAjAdhAPAAeh5pAHMAAKD7IoABZHB0APgReS6DLgABZmx9LoAuAOA12GnddQDzAP8RaQBtAOUABBIAAUFhiy6OLnIA8gDuAnIA8gCaBwABY3GVLgoScgAA4DXYzdwAAXB0nS6hLmwAdQDzACUScgDpACASAARhY2VmaW9zdbEuvC7ELsguzC7PLtQu2S5jAAABdXm2LrsudABlADuA/QD9QE9kAAFpecAuwy5yAGMAd2FLZG4AO4ClAKVAcgAA4DXYNt1jAHkAV2RwAGYAAOA12GrdYwByAADgNdjO3AABY23dLt8ueQBOZGwAO4D/AP9AAAVhY2RlZmhpb3N38y73Lv8uAi8MLxAvEy8YLx0vIi9jInV0ZQB6YQABYXn7Lv4u8iFvbn5hN2RvAHQAfGEAAWV0Bi8KL3QAcgDmAB8QYQC2Y3IAAOA12DfdYwB5ADZk5yJyYXJyAKDdIXAAZgAA4DXYa91jAHIAAOA12M/cAAFqbiYvKC8AoA0gagAAoAwg");
3898
+ //#endregion
3899
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/generated/decode-data-xml.js
3900
+ /** Packed XML decode trie data. */
3901
+ const xmlDecodeTree = /* #__PURE__ */ decodeBase64("AAJhZ2xxBwARABMAFQBtAg0AAAAAAA8AcAAmYG8AcwAnYHQAPmB0ADxg9SFvdCJg");
3902
+ //#endregion
3903
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/internal/bin-trie-flags.js
3904
+ /**
3905
+ * Bit flags & masks for the binary trie encoding used for entity decoding.
3906
+ *
3907
+ * Bit layout (16 bits total):
3908
+ * 15..14 VALUE_LENGTH (+1 encoding; 0 => no value)
3909
+ * 13 FLAG13. If valueLength>0: semicolon required flag (implicit ';').
3910
+ * If valueLength==0: compact run flag.
3911
+ * 12..7 BRANCH_LENGTH Branch length (0 => single branch in 6..0 if jumpOffset==char) OR run length (when compact run)
3912
+ * 6..0 JUMP_TABLE Jump offset (jump table) OR single-branch char code OR first run char
3913
+ */
3914
+ var BinTrieFlags;
3915
+ (function(BinTrieFlags) {
3916
+ BinTrieFlags[BinTrieFlags["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
3917
+ BinTrieFlags[BinTrieFlags["FLAG13"] = 8192] = "FLAG13";
3918
+ BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 8064] = "BRANCH_LENGTH";
3919
+ BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE";
3920
+ })(BinTrieFlags || (BinTrieFlags = {}));
3921
+ //#endregion
3922
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/decode.js
3923
+ var CharCodes$1;
3924
+ (function(CharCodes) {
3925
+ CharCodes[CharCodes["NUM"] = 35] = "NUM";
3926
+ CharCodes[CharCodes["SEMI"] = 59] = "SEMI";
3927
+ CharCodes[CharCodes["EQUALS"] = 61] = "EQUALS";
3928
+ CharCodes[CharCodes["ZERO"] = 48] = "ZERO";
3929
+ CharCodes[CharCodes["NINE"] = 57] = "NINE";
3930
+ CharCodes[CharCodes["LOWER_A"] = 97] = "LOWER_A";
3931
+ CharCodes[CharCodes["LOWER_F"] = 102] = "LOWER_F";
3932
+ CharCodes[CharCodes["LOWER_X"] = 120] = "LOWER_X";
3933
+ CharCodes[CharCodes["LOWER_Z"] = 122] = "LOWER_Z";
3934
+ CharCodes[CharCodes["UPPER_A"] = 65] = "UPPER_A";
3935
+ CharCodes[CharCodes["UPPER_F"] = 70] = "UPPER_F";
3936
+ CharCodes[CharCodes["UPPER_Z"] = 90] = "UPPER_Z";
3937
+ })(CharCodes$1 || (CharCodes$1 = {}));
3938
+ /** Bit that needs to be set to convert an upper case ASCII character to lower case */
3939
+ const TO_LOWER_BIT = 32;
3940
+ function isNumber(code) {
3941
+ return code >= CharCodes$1.ZERO && code <= CharCodes$1.NINE;
3942
+ }
3943
+ function isHexadecimalCharacter(code) {
3944
+ return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_F || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_F;
3945
+ }
3946
+ function isAsciiAlphaNumeric(code) {
3947
+ return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_Z || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_Z || isNumber(code);
3948
+ }
3949
+ /**
3950
+ * Checks if the given character is a valid end character for an entity in an attribute.
3951
+ *
3952
+ * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.
3953
+ * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
3954
+ * @param code Code point to decode.
3955
+ */
3956
+ function isEntityInAttributeInvalidEnd(code) {
3957
+ return code === CharCodes$1.EQUALS || isAsciiAlphaNumeric(code);
3958
+ }
3959
+ var EntityDecoderState;
3960
+ (function(EntityDecoderState) {
3961
+ EntityDecoderState[EntityDecoderState["EntityStart"] = 0] = "EntityStart";
3962
+ EntityDecoderState[EntityDecoderState["NumericStart"] = 1] = "NumericStart";
3963
+ EntityDecoderState[EntityDecoderState["NumericDecimal"] = 2] = "NumericDecimal";
3964
+ EntityDecoderState[EntityDecoderState["NumericHex"] = 3] = "NumericHex";
3965
+ EntityDecoderState[EntityDecoderState["NamedEntity"] = 4] = "NamedEntity";
3966
+ })(EntityDecoderState || (EntityDecoderState = {}));
3967
+ /**
3968
+ * Decoding mode for named entities.
3969
+ */
3970
+ var DecodingMode;
3971
+ (function(DecodingMode) {
3972
+ /** Entities in text nodes that can end with any character. */
3973
+ DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy";
3974
+ /** Only allow entities terminated with a semicolon. */
3975
+ DecodingMode[DecodingMode["Strict"] = 1] = "Strict";
3976
+ /** Entities in attributes have limitations on ending characters. */
3977
+ DecodingMode[DecodingMode["Attribute"] = 2] = "Attribute";
3978
+ })(DecodingMode || (DecodingMode = {}));
3979
+ /**
3980
+ * Token decoder with support of writing partial entities.
3981
+ */
3982
+ var EntityDecoder = class {
3983
+ decodeTree;
3984
+ emitCodePoint;
3985
+ errors;
3986
+ constructor(decodeTree, emitCodePoint, errors) {
3987
+ this.decodeTree = decodeTree;
3988
+ this.emitCodePoint = emitCodePoint;
3989
+ this.errors = errors;
3990
+ }
3991
+ /** The current state of the decoder. */
3992
+ state = EntityDecoderState.EntityStart;
3993
+ /** Characters that were consumed while parsing an entity. */
3994
+ consumed = 1;
3995
+ /**
3996
+ * The result of the entity.
3997
+ *
3998
+ * Either the result index of a numeric entity, or the codepoint of a
3999
+ * numeric entity.
4000
+ */
4001
+ result = 0;
4002
+ /** The current index in the decode tree. */
4003
+ treeIndex = 0;
4004
+ /** The number of characters that were consumed in excess. */
4005
+ excess = 1;
4006
+ /** The mode in which the decoder is operating. */
4007
+ decodeMode = DecodingMode.Strict;
4008
+ /** The number of characters that have been consumed in the current run. */
4009
+ runConsumed = 0;
4010
+ /**
4011
+ * Resets the instance to make it reusable.
4012
+ * @param decodeMode Entity decoding mode to use.
4013
+ */
4014
+ startEntity(decodeMode) {
4015
+ this.decodeMode = decodeMode;
4016
+ this.state = EntityDecoderState.EntityStart;
4017
+ this.result = 0;
4018
+ this.treeIndex = 0;
4019
+ this.excess = 1;
4020
+ this.consumed = 1;
4021
+ this.runConsumed = 0;
4022
+ }
4023
+ /**
4024
+ * Write an entity to the decoder. This can be called multiple times with partial entities.
4025
+ * If the entity is incomplete, the decoder will return -1.
4026
+ *
4027
+ * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
4028
+ * entity is incomplete, and resume when the next string is written.
4029
+ * @param input The string containing the entity (or a continuation of the entity).
4030
+ * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
4031
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
4032
+ */
4033
+ write(input, offset) {
4034
+ switch (this.state) {
4035
+ case EntityDecoderState.EntityStart:
4036
+ if (input.charCodeAt(offset) === CharCodes$1.NUM) {
4037
+ this.state = EntityDecoderState.NumericStart;
4038
+ this.consumed += 1;
4039
+ return this.stateNumericStart(input, offset + 1);
4040
+ }
4041
+ this.state = EntityDecoderState.NamedEntity;
4042
+ return this.stateNamedEntity(input, offset);
4043
+ case EntityDecoderState.NumericStart: return this.stateNumericStart(input, offset);
4044
+ case EntityDecoderState.NumericDecimal: return this.stateNumericDecimal(input, offset);
4045
+ case EntityDecoderState.NumericHex: return this.stateNumericHex(input, offset);
4046
+ case EntityDecoderState.NamedEntity: return this.stateNamedEntity(input, offset);
4047
+ }
4048
+ }
4049
+ /**
4050
+ * Switches between the numeric decimal and hexadecimal states.
4051
+ *
4052
+ * Equivalent to the `Numeric character reference state` in the HTML spec.
4053
+ * @param input The string containing the entity (or a continuation of the entity).
4054
+ * @param offset The current offset.
4055
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
4056
+ */
4057
+ stateNumericStart(input, offset) {
4058
+ if (offset >= input.length) return -1;
4059
+ if ((input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes$1.LOWER_X) {
4060
+ this.state = EntityDecoderState.NumericHex;
4061
+ this.consumed += 1;
4062
+ return this.stateNumericHex(input, offset + 1);
4063
+ }
4064
+ this.state = EntityDecoderState.NumericDecimal;
4065
+ return this.stateNumericDecimal(input, offset);
4066
+ }
4067
+ /**
4068
+ * Parses a hexadecimal numeric entity.
4069
+ *
4070
+ * Equivalent to the `Hexademical character reference state` in the HTML spec.
4071
+ * @param input The string containing the entity (or a continuation of the entity).
4072
+ * @param offset The current offset.
4073
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
4074
+ */
4075
+ stateNumericHex(input, offset) {
4076
+ while (offset < input.length) {
4077
+ const char = input.charCodeAt(offset);
4078
+ if (isNumber(char) || isHexadecimalCharacter(char)) {
4079
+ const digit = char <= CharCodes$1.NINE ? char - CharCodes$1.ZERO : (char | TO_LOWER_BIT) - CharCodes$1.LOWER_A + 10;
4080
+ this.result = this.result * 16 + digit;
4081
+ this.consumed++;
4082
+ offset++;
4083
+ } else return this.emitNumericEntity(char, 3);
4084
+ }
4085
+ return -1;
4086
+ }
4087
+ /**
4088
+ * Parses a decimal numeric entity.
4089
+ *
4090
+ * Equivalent to the `Decimal character reference state` in the HTML spec.
4091
+ * @param input The string containing the entity (or a continuation of the entity).
4092
+ * @param offset The current offset.
4093
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
4094
+ */
4095
+ stateNumericDecimal(input, offset) {
4096
+ while (offset < input.length) {
4097
+ const char = input.charCodeAt(offset);
4098
+ if (isNumber(char)) {
4099
+ this.result = this.result * 10 + (char - CharCodes$1.ZERO);
4100
+ this.consumed++;
4101
+ offset++;
4102
+ } else return this.emitNumericEntity(char, 2);
4103
+ }
4104
+ return -1;
4105
+ }
4106
+ /**
4107
+ * Validate and emit a numeric entity.
4108
+ *
4109
+ * Implements the logic from the `Hexademical character reference start
4110
+ * state` and `Numeric character reference end state` in the HTML spec.
4111
+ * @param lastCp The last code point of the entity. Used to see if the
4112
+ * entity was terminated with a semicolon.
4113
+ * @param expectedLength The minimum number of characters that should be
4114
+ * consumed. Used to validate that at least one digit
4115
+ * was consumed.
4116
+ * @returns The number of characters that were consumed.
4117
+ */
4118
+ emitNumericEntity(lastCp, expectedLength) {
4119
+ if (this.consumed <= expectedLength) {
4120
+ this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
4121
+ return 0;
4122
+ }
4123
+ if (lastCp === CharCodes$1.SEMI) this.consumed += 1;
4124
+ else if (this.decodeMode === DecodingMode.Strict) return 0;
4125
+ this.emitCodePoint(replaceCodePoint(this.result), this.consumed);
4126
+ if (this.errors) {
4127
+ if (lastCp !== CharCodes$1.SEMI) this.errors.missingSemicolonAfterCharacterReference();
4128
+ this.errors.validateNumericCharacterReference(this.result);
4129
+ }
4130
+ return this.consumed;
4131
+ }
4132
+ /**
4133
+ * Parses a named entity.
4134
+ *
4135
+ * Equivalent to the `Named character reference state` in the HTML spec.
4136
+ * @param input The string containing the entity (or a continuation of the entity).
4137
+ * @param offset The current offset.
4138
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
4139
+ */
4140
+ stateNamedEntity(input, offset) {
4141
+ const { decodeTree } = this;
4142
+ let current = decodeTree[this.treeIndex];
4143
+ let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
4144
+ while (offset < input.length) {
4145
+ if (valueLength === 0 && (current & BinTrieFlags.FLAG13) !== 0) {
4146
+ const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
4147
+ if (this.runConsumed === 0) {
4148
+ const firstChar = current & BinTrieFlags.JUMP_TABLE;
4149
+ if (input.charCodeAt(offset) !== firstChar) return this.result === 0 ? 0 : this.emitNotTerminatedNamedEntity();
4150
+ offset++;
4151
+ this.excess++;
4152
+ this.runConsumed++;
4153
+ }
4154
+ while (this.runConsumed < runLength) {
4155
+ if (offset >= input.length) return -1;
4156
+ const charIndexInPacked = this.runConsumed - 1;
4157
+ const packedWord = decodeTree[this.treeIndex + 1 + (charIndexInPacked >> 1)];
4158
+ const expectedChar = charIndexInPacked % 2 === 0 ? packedWord & 255 : packedWord >> 8 & 255;
4159
+ if (input.charCodeAt(offset) !== expectedChar) {
4160
+ this.runConsumed = 0;
4161
+ return this.result === 0 ? 0 : this.emitNotTerminatedNamedEntity();
4162
+ }
4163
+ offset++;
4164
+ this.excess++;
4165
+ this.runConsumed++;
4166
+ }
4167
+ this.runConsumed = 0;
4168
+ this.treeIndex += 1 + (runLength >> 1);
4169
+ current = decodeTree[this.treeIndex];
4170
+ valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
4171
+ }
4172
+ if (offset >= input.length) break;
4173
+ const char = input.charCodeAt(offset);
4174
+ if (char === CharCodes$1.SEMI && valueLength !== 0 && (current & BinTrieFlags.FLAG13) !== 0) return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
4175
+ this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
4176
+ if (this.treeIndex < 0) return this.result === 0 || this.decodeMode === DecodingMode.Attribute && (valueLength === 0 || isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
4177
+ current = decodeTree[this.treeIndex];
4178
+ valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
4179
+ if (valueLength !== 0) {
4180
+ if (char === CharCodes$1.SEMI) return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
4181
+ if (this.decodeMode !== DecodingMode.Strict && (current & BinTrieFlags.FLAG13) === 0) {
4182
+ this.result = this.treeIndex;
4183
+ this.consumed += this.excess;
4184
+ this.excess = 0;
4185
+ }
4186
+ }
4187
+ offset++;
4188
+ this.excess++;
4189
+ }
4190
+ return -1;
4191
+ }
4192
+ /**
4193
+ * Emit a named entity that was not terminated with a semicolon.
4194
+ * @returns The number of characters consumed.
4195
+ */
4196
+ emitNotTerminatedNamedEntity() {
4197
+ const { result, decodeTree } = this;
4198
+ const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;
4199
+ this.emitNamedEntityData(result, valueLength, this.consumed);
4200
+ this.errors?.missingSemicolonAfterCharacterReference();
4201
+ return this.consumed;
4202
+ }
4203
+ /**
4204
+ * Emit a named entity.
4205
+ * @param result The index of the entity in the decode tree.
4206
+ * @param valueLength The number of bytes in the entity.
4207
+ * @param consumed The number of characters consumed.
4208
+ * @returns The number of characters consumed.
4209
+ */
4210
+ emitNamedEntityData(result, valueLength, consumed) {
4211
+ const { decodeTree } = this;
4212
+ this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~(BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13) : decodeTree[result + 1], consumed);
4213
+ if (valueLength === 3) this.emitCodePoint(decodeTree[result + 2], consumed);
4214
+ return consumed;
4215
+ }
4216
+ /**
4217
+ * Signal to the parser that the end of the input was reached.
4218
+ *
4219
+ * Remaining data will be emitted and relevant errors will be produced.
4220
+ * @returns The number of characters consumed.
4221
+ */
4222
+ end() {
4223
+ switch (this.state) {
4224
+ case EntityDecoderState.NamedEntity: return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
4225
+ case EntityDecoderState.NumericDecimal: return this.emitNumericEntity(0, 2);
4226
+ case EntityDecoderState.NumericHex: return this.emitNumericEntity(0, 3);
4227
+ case EntityDecoderState.NumericStart:
4228
+ this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
4229
+ return 0;
4230
+ case EntityDecoderState.EntityStart: return 0;
4231
+ }
4232
+ }
4233
+ };
4234
+ /**
4235
+ * Determines the branch of the current node that is taken given the current
4236
+ * character. This function is used to traverse the trie.
4237
+ * @param decodeTree The trie.
4238
+ * @param current The current node.
4239
+ * @param nodeIndex Index immediately after the current node header.
4240
+ * @param char The current character.
4241
+ * @returns The index of the next node, or -1 if no branch is taken.
4242
+ */
4243
+ function determineBranch(decodeTree, current, nodeIndex, char) {
4244
+ const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
4245
+ const jumpOffset = current & BinTrieFlags.JUMP_TABLE;
4246
+ if (branchCount === 0) return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1;
4247
+ if (jumpOffset) {
4248
+ const value = char - jumpOffset;
4249
+ return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIndex + value] - 1;
4250
+ }
4251
+ const packedKeySlots = branchCount + 1 >> 1;
4252
+ let lo = 0;
4253
+ let hi = branchCount - 1;
4254
+ while (lo <= hi) {
4255
+ const mid = lo + hi >>> 1;
4256
+ const midKey = decodeTree[nodeIndex + (mid >> 1)] >> (mid & 1) * 8 & 255;
4257
+ if (midKey < char) lo = mid + 1;
4258
+ else if (midKey > char) hi = mid - 1;
4259
+ else return decodeTree[nodeIndex + packedKeySlots + mid];
4260
+ }
4261
+ return -1;
4262
+ }
4263
+ //#endregion
4264
+ //#region ../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Tokenizer.js
4265
+ var CharCodes;
4266
+ (function(CharCodes) {
4267
+ CharCodes[CharCodes["Tab"] = 9] = "Tab";
4268
+ CharCodes[CharCodes["NewLine"] = 10] = "NewLine";
4269
+ CharCodes[CharCodes["FormFeed"] = 12] = "FormFeed";
4270
+ CharCodes[CharCodes["CarriageReturn"] = 13] = "CarriageReturn";
4271
+ CharCodes[CharCodes["Space"] = 32] = "Space";
4272
+ CharCodes[CharCodes["ExclamationMark"] = 33] = "ExclamationMark";
4273
+ CharCodes[CharCodes["Number"] = 35] = "Number";
4274
+ CharCodes[CharCodes["Amp"] = 38] = "Amp";
4275
+ CharCodes[CharCodes["SingleQuote"] = 39] = "SingleQuote";
4276
+ CharCodes[CharCodes["DoubleQuote"] = 34] = "DoubleQuote";
4277
+ CharCodes[CharCodes["Dash"] = 45] = "Dash";
4278
+ CharCodes[CharCodes["Slash"] = 47] = "Slash";
4279
+ CharCodes[CharCodes["Zero"] = 48] = "Zero";
4280
+ CharCodes[CharCodes["Nine"] = 57] = "Nine";
4281
+ CharCodes[CharCodes["Semi"] = 59] = "Semi";
4282
+ CharCodes[CharCodes["Lt"] = 60] = "Lt";
4283
+ CharCodes[CharCodes["Eq"] = 61] = "Eq";
4284
+ CharCodes[CharCodes["Gt"] = 62] = "Gt";
4285
+ CharCodes[CharCodes["Questionmark"] = 63] = "Questionmark";
4286
+ CharCodes[CharCodes["UpperA"] = 65] = "UpperA";
4287
+ CharCodes[CharCodes["LowerA"] = 97] = "LowerA";
4288
+ CharCodes[CharCodes["UpperF"] = 70] = "UpperF";
4289
+ CharCodes[CharCodes["LowerF"] = 102] = "LowerF";
4290
+ CharCodes[CharCodes["UpperZ"] = 90] = "UpperZ";
4291
+ CharCodes[CharCodes["LowerZ"] = 122] = "LowerZ";
4292
+ CharCodes[CharCodes["LowerX"] = 120] = "LowerX";
4293
+ CharCodes[CharCodes["OpeningSquareBracket"] = 91] = "OpeningSquareBracket";
4294
+ })(CharCodes || (CharCodes = {}));
4295
+ /** All the states the tokenizer can be in. */
4296
+ var State;
4297
+ (function(State) {
4298
+ State[State["Text"] = 1] = "Text";
4299
+ State[State["BeforeTagName"] = 2] = "BeforeTagName";
4300
+ State[State["InTagName"] = 3] = "InTagName";
4301
+ State[State["InSelfClosingTag"] = 4] = "InSelfClosingTag";
4302
+ State[State["BeforeClosingTagName"] = 5] = "BeforeClosingTagName";
4303
+ State[State["InClosingTagName"] = 6] = "InClosingTagName";
4304
+ State[State["AfterClosingTagName"] = 7] = "AfterClosingTagName";
4305
+ State[State["BeforeAttributeName"] = 8] = "BeforeAttributeName";
4306
+ State[State["InAttributeName"] = 9] = "InAttributeName";
4307
+ State[State["AfterAttributeName"] = 10] = "AfterAttributeName";
4308
+ State[State["BeforeAttributeValue"] = 11] = "BeforeAttributeValue";
4309
+ State[State["InAttributeValueDq"] = 12] = "InAttributeValueDq";
4310
+ State[State["InAttributeValueSq"] = 13] = "InAttributeValueSq";
4311
+ State[State["InAttributeValueNq"] = 14] = "InAttributeValueNq";
4312
+ State[State["BeforeDeclaration"] = 15] = "BeforeDeclaration";
4313
+ State[State["InDeclaration"] = 16] = "InDeclaration";
4314
+ State[State["InProcessingInstruction"] = 17] = "InProcessingInstruction";
4315
+ State[State["BeforeComment"] = 18] = "BeforeComment";
4316
+ State[State["CDATASequence"] = 19] = "CDATASequence";
4317
+ State[State["DeclarationSequence"] = 20] = "DeclarationSequence";
4318
+ State[State["InSpecialComment"] = 21] = "InSpecialComment";
4319
+ State[State["InCommentLike"] = 22] = "InCommentLike";
4320
+ State[State["SpecialStartSequence"] = 23] = "SpecialStartSequence";
4321
+ State[State["InSpecialTag"] = 24] = "InSpecialTag";
4322
+ State[State["InPlainText"] = 25] = "InPlainText";
4323
+ State[State["InEntity"] = 26] = "InEntity";
4324
+ })(State || (State = {}));
4325
+ function isWhitespace$1(c) {
4326
+ return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn;
4327
+ }
4328
+ function isEndOfTagSection(c) {
4329
+ return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace$1(c);
4330
+ }
4331
+ function isASCIIAlpha(c) {
4332
+ return c >= CharCodes.LowerA && c <= CharCodes.LowerZ || c >= CharCodes.UpperA && c <= CharCodes.UpperZ;
4333
+ }
4334
+ /**
4335
+ * Quote style used for parsed attributes.
4336
+ */
4337
+ var QuoteType;
4338
+ (function(QuoteType) {
4339
+ QuoteType[QuoteType["NoValue"] = 0] = "NoValue";
4340
+ QuoteType[QuoteType["Unquoted"] = 1] = "Unquoted";
4341
+ QuoteType[QuoteType["Single"] = 2] = "Single";
4342
+ QuoteType[QuoteType["Double"] = 3] = "Double";
4343
+ })(QuoteType || (QuoteType = {}));
4344
+ /**
4345
+ * Sequences used to match longer strings.
4346
+ *
4347
+ * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End
4348
+ * sequences with an increased offset.
4349
+ */
4350
+ const Sequences = {
4351
+ Empty: /* @__PURE__ */ new Uint8Array(0),
4352
+ Cdata: new Uint8Array([
4353
+ 67,
4354
+ 68,
4355
+ 65,
4356
+ 84,
4357
+ 65,
4358
+ 91
4359
+ ]),
4360
+ CdataEnd: new Uint8Array([
4361
+ 93,
4362
+ 93,
4363
+ 62
4364
+ ]),
4365
+ CommentEnd: new Uint8Array([
4366
+ 45,
4367
+ 45,
4368
+ 33,
4369
+ 62
4370
+ ]),
4371
+ Doctype: new Uint8Array([
4372
+ 100,
4373
+ 111,
4374
+ 99,
4375
+ 116,
4376
+ 121,
4377
+ 112,
4378
+ 101
4379
+ ]),
4380
+ IframeEnd: new Uint8Array([
4381
+ 60,
4382
+ 47,
4383
+ 105,
4384
+ 102,
4385
+ 114,
4386
+ 97,
4387
+ 109,
4388
+ 101
4389
+ ]),
4390
+ NoembedEnd: new Uint8Array([
4391
+ 60,
4392
+ 47,
4393
+ 110,
4394
+ 111,
4395
+ 101,
4396
+ 109,
4397
+ 98,
4398
+ 101,
4399
+ 100
4400
+ ]),
4401
+ NoframesEnd: new Uint8Array([
4402
+ 60,
4403
+ 47,
4404
+ 110,
4405
+ 111,
4406
+ 102,
4407
+ 114,
4408
+ 97,
4409
+ 109,
4410
+ 101,
4411
+ 115
4412
+ ]),
4413
+ Plaintext: new Uint8Array([
4414
+ 60,
4415
+ 47,
4416
+ 112,
4417
+ 108,
4418
+ 97,
4419
+ 105,
4420
+ 110,
4421
+ 116,
4422
+ 101,
4423
+ 120,
4424
+ 116
4425
+ ]),
4426
+ ScriptEnd: new Uint8Array([
4427
+ 60,
4428
+ 47,
4429
+ 115,
4430
+ 99,
4431
+ 114,
4432
+ 105,
4433
+ 112,
4434
+ 116
4435
+ ]),
4436
+ StyleEnd: new Uint8Array([
4437
+ 60,
4438
+ 47,
4439
+ 115,
4440
+ 116,
4441
+ 121,
4442
+ 108,
4443
+ 101
4444
+ ]),
4445
+ TitleEnd: new Uint8Array([
4446
+ 60,
4447
+ 47,
4448
+ 116,
4449
+ 105,
4450
+ 116,
4451
+ 108,
4452
+ 101
4453
+ ]),
4454
+ TextareaEnd: new Uint8Array([
4455
+ 60,
4456
+ 47,
4457
+ 116,
4458
+ 101,
4459
+ 120,
4460
+ 116,
4461
+ 97,
4462
+ 114,
4463
+ 101,
4464
+ 97
4465
+ ]),
4466
+ XmpEnd: new Uint8Array([
4467
+ 60,
4468
+ 47,
4469
+ 120,
4470
+ 109,
4471
+ 112
4472
+ ])
4473
+ };
4474
+ /**
4475
+ * Maps the first lowercase character of an HTML tag name to the sequence
4476
+ * used for special-tag detection. All sequences share a common layout
4477
+ * where index 2 is the first tag-name character, so matching always
4478
+ * continues from offset 3.
4479
+ */
4480
+ const specialStartSequences = /* @__PURE__ */ new Map([
4481
+ [Sequences.IframeEnd[2], Sequences.IframeEnd],
4482
+ [Sequences.NoembedEnd[2], Sequences.NoembedEnd],
4483
+ [Sequences.Plaintext[2], Sequences.Plaintext],
4484
+ [Sequences.ScriptEnd[2], Sequences.ScriptEnd],
4485
+ [Sequences.TitleEnd[2], Sequences.TitleEnd],
4486
+ [Sequences.XmpEnd[2], Sequences.XmpEnd]
4487
+ ]);
4488
+ /**
4489
+ * Tokenizer implementation used by `Parser`.
4490
+ */
4491
+ var Tokenizer$1 = class {
4492
+ cbs;
4493
+ /** The current state the tokenizer is in. */
4494
+ state = State.Text;
4495
+ /** The read buffer. */
4496
+ buffer = "";
4497
+ /** The beginning of the section that is currently being read. */
4498
+ sectionStart = 0;
4499
+ /** The index within the buffer that we are currently looking at. */
4500
+ index = 0;
4501
+ /** The start of the last entity. */
4502
+ entityStart = 0;
4503
+ /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */
4504
+ baseState = State.Text;
4505
+ /** For special parsing behavior inside of script and style tags. */
4506
+ isSpecial = false;
4507
+ /** Indicates whether the tokenizer has been paused. */
4508
+ running = true;
4509
+ /** The offset of the current buffer. */
4510
+ offset = 0;
4511
+ xmlMode;
4512
+ decodeEntities;
4513
+ recognizeSelfClosing;
4514
+ entityDecoder;
4515
+ constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode }, cbs) {
4516
+ this.cbs = cbs;
4517
+ this.xmlMode = xmlMode;
4518
+ this.decodeEntities = decodeEntities;
4519
+ this.recognizeSelfClosing = recognizeSelfClosing;
4520
+ this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));
4521
+ }
4522
+ reset() {
4523
+ this.state = State.Text;
4524
+ this.buffer = "";
4525
+ this.sectionStart = 0;
4526
+ this.index = 0;
4527
+ this.baseState = State.Text;
4528
+ this.isSpecial = false;
4529
+ this.currentSequence = Sequences.Empty;
4530
+ this.sequenceIndex = 0;
4531
+ this.running = true;
4532
+ this.offset = 0;
4533
+ }
4534
+ write(chunk) {
4535
+ this.offset += this.buffer.length;
4536
+ this.buffer = chunk;
4537
+ this.parse();
4538
+ }
4539
+ end() {
4540
+ if (this.running) this.finish();
4541
+ }
4542
+ pause() {
4543
+ this.running = false;
4544
+ }
4545
+ resume() {
4546
+ this.running = true;
4547
+ if (this.index < this.buffer.length + this.offset) this.parse();
4548
+ }
4549
+ stateText(c) {
4550
+ if (c === CharCodes.Lt || !this.decodeEntities && this.fastForwardTo(CharCodes.Lt)) {
4551
+ if (this.index > this.sectionStart) this.cbs.ontext(this.sectionStart, this.index);
4552
+ this.state = State.BeforeTagName;
4553
+ this.sectionStart = this.index;
4554
+ } else if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
4555
+ }
4556
+ currentSequence = Sequences.Empty;
4557
+ sequenceIndex = 0;
4558
+ enterTagBody() {
4559
+ if (this.currentSequence === Sequences.Plaintext) {
4560
+ this.currentSequence = Sequences.Empty;
4561
+ this.state = State.InPlainText;
4562
+ } else if (this.isSpecial) {
4563
+ this.state = State.InSpecialTag;
4564
+ this.sequenceIndex = 0;
4565
+ } else this.state = State.Text;
4566
+ }
4567
+ /**
4568
+ * Match the opening tag name against an HTML text-only tag sequence.
4569
+ *
4570
+ * Some tags share an initial prefix (`script`/`style`, `title`/`textarea`,
4571
+ * `noembed`/`noframes`), so we may switch to an alternate sequence at the
4572
+ * first distinguishing byte. On a successful full match we fall back to
4573
+ * the normal tag-name state; a later `>` will enter raw-text, RCDATA, or
4574
+ * plaintext mode based on `currentSequence` / `isSpecial`.
4575
+ * @param c Current character code point.
4576
+ */
4577
+ stateSpecialStartSequence(c) {
4578
+ const lower = c | 32;
4579
+ if (this.sequenceIndex < this.currentSequence.length) {
4580
+ if (lower === this.currentSequence[this.sequenceIndex]) {
4581
+ this.sequenceIndex++;
4582
+ return;
4583
+ }
4584
+ if (this.sequenceIndex === 3) {
4585
+ if (this.currentSequence === Sequences.ScriptEnd && lower === Sequences.StyleEnd[3]) {
4586
+ this.currentSequence = Sequences.StyleEnd;
4587
+ this.sequenceIndex = 4;
4588
+ return;
4589
+ }
4590
+ if (this.currentSequence === Sequences.TitleEnd && lower === Sequences.TextareaEnd[3]) {
4591
+ this.currentSequence = Sequences.TextareaEnd;
4592
+ this.sequenceIndex = 4;
4593
+ return;
4594
+ }
4595
+ } else if (this.sequenceIndex === 4 && this.currentSequence === Sequences.NoembedEnd && lower === Sequences.NoframesEnd[4]) {
4596
+ this.currentSequence = Sequences.NoframesEnd;
4597
+ this.sequenceIndex = 5;
4598
+ return;
4599
+ }
4600
+ } else if (isEndOfTagSection(c)) {
4601
+ this.sequenceIndex = 0;
4602
+ this.state = State.InTagName;
4603
+ this.stateInTagName(c);
4604
+ return;
4605
+ }
4606
+ this.isSpecial = false;
4607
+ this.currentSequence = Sequences.Empty;
4608
+ this.sequenceIndex = 0;
4609
+ this.state = State.InTagName;
4610
+ this.stateInTagName(c);
4611
+ }
4612
+ stateCDATASequence(c) {
4613
+ if (c === Sequences.Cdata[this.sequenceIndex]) {
4614
+ if (++this.sequenceIndex === Sequences.Cdata.length) {
4615
+ this.state = State.InCommentLike;
4616
+ this.currentSequence = Sequences.CdataEnd;
4617
+ this.sequenceIndex = 0;
4618
+ this.sectionStart = this.index + 1;
4619
+ }
4620
+ } else {
4621
+ this.sequenceIndex = 0;
4622
+ if (this.xmlMode) {
4623
+ this.state = State.InDeclaration;
4624
+ this.stateInDeclaration(c);
4625
+ } else {
4626
+ this.state = State.InSpecialComment;
4627
+ this.stateInSpecialComment(c);
4628
+ }
4629
+ }
4630
+ }
4631
+ /**
4632
+ * When we wait for one specific character, we can speed things up
4633
+ * by skipping through the buffer until we find it.
4634
+ * @param c Current character code point.
4635
+ * @returns Whether the character was found.
4636
+ */
4637
+ fastForwardTo(c) {
4638
+ while (++this.index < this.buffer.length + this.offset) if (this.buffer.charCodeAt(this.index - this.offset) === c) return true;
4639
+ this.index = this.buffer.length + this.offset - 1;
4640
+ return false;
4641
+ }
4642
+ /**
4643
+ * Emit a comment token and return to the text state.
4644
+ * @param offset Number of characters in the end sequence that have already been matched.
4645
+ */
4646
+ emitComment(offset) {
4647
+ this.cbs.oncomment(this.sectionStart, this.index, offset);
4648
+ this.sequenceIndex = 0;
4649
+ this.sectionStart = this.index + 1;
4650
+ this.state = State.Text;
4651
+ }
4652
+ /**
4653
+ * Comments and CDATA end with `-->` and `]]>`.
4654
+ *
4655
+ * Their common qualities are:
4656
+ * - Their end sequences have a distinct character they start with.
4657
+ * - That character is then repeated, so we have to check multiple repeats.
4658
+ * - All characters but the start character of the sequence can be skipped.
4659
+ * @param c Current character code point.
4660
+ */
4661
+ stateInCommentLike(c) {
4662
+ if (!this.xmlMode && this.currentSequence === Sequences.CommentEnd && this.sequenceIndex <= 1 && this.index === this.sectionStart + this.sequenceIndex && c === CharCodes.Gt) this.emitComment(this.sequenceIndex);
4663
+ else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === 2 && c === CharCodes.Gt) this.emitComment(2);
4664
+ else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === this.currentSequence.length - 1 && c !== CharCodes.Gt) this.sequenceIndex = Number(c === CharCodes.Dash);
4665
+ else if (c === this.currentSequence[this.sequenceIndex]) {
4666
+ if (++this.sequenceIndex === this.currentSequence.length) {
4667
+ if (this.currentSequence === Sequences.CdataEnd) this.cbs.oncdata(this.sectionStart, this.index, 2);
4668
+ else this.cbs.oncomment(this.sectionStart, this.index, 3);
4669
+ this.sequenceIndex = 0;
4670
+ this.sectionStart = this.index + 1;
4671
+ this.state = State.Text;
4672
+ }
4673
+ } else if (this.sequenceIndex === 0) {
4674
+ if (this.fastForwardTo(this.currentSequence[0])) this.sequenceIndex = 1;
4675
+ } else if (c !== this.currentSequence[this.sequenceIndex - 1]) this.sequenceIndex = 0;
4676
+ }
4677
+ /**
4678
+ * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
4679
+ *
4680
+ * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
4681
+ * We allow anything that wouldn't end the tag.
4682
+ * @param c Current character code point.
4683
+ */
4684
+ isTagStartChar(c) {
4685
+ return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
4686
+ }
4687
+ /**
4688
+ * Scan raw-text / RCDATA content for the matching end tag.
4689
+ *
4690
+ * For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline.
4691
+ * For raw-text tags (`<script>`, `<style>`, etc.) we fast-forward to `<`.
4692
+ * @param c Current character code point.
4693
+ */
4694
+ stateInSpecialTag(c) {
4695
+ if (this.sequenceIndex === this.currentSequence.length) {
4696
+ if (isEndOfTagSection(c)) {
4697
+ const endOfText = this.index - this.currentSequence.length;
4698
+ if (this.sectionStart < endOfText) {
4699
+ const actualIndex = this.index;
4700
+ this.index = endOfText;
4701
+ this.cbs.ontext(this.sectionStart, endOfText);
4702
+ this.index = actualIndex;
4703
+ }
4704
+ this.isSpecial = false;
4705
+ this.sectionStart = endOfText + 2;
4706
+ this.stateInClosingTagName(c);
4707
+ return;
4708
+ }
4709
+ this.sequenceIndex = 0;
4710
+ }
4711
+ if ((c | 32) === this.currentSequence[this.sequenceIndex]) this.sequenceIndex += 1;
4712
+ else if (this.sequenceIndex === 0) {
4713
+ if (this.currentSequence === Sequences.TitleEnd || this.currentSequence === Sequences.TextareaEnd) {
4714
+ if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
4715
+ } else if (this.fastForwardTo(CharCodes.Lt)) this.sequenceIndex = 1;
4716
+ } else this.sequenceIndex = Number(c === CharCodes.Lt);
4717
+ }
4718
+ stateBeforeTagName(c) {
4719
+ if (c === CharCodes.ExclamationMark) {
4720
+ this.state = State.BeforeDeclaration;
4721
+ this.sectionStart = this.index + 1;
4722
+ } else if (c === CharCodes.Questionmark) if (this.xmlMode) {
4723
+ this.state = State.InProcessingInstruction;
4724
+ this.sequenceIndex = 0;
4725
+ this.sectionStart = this.index + 1;
4726
+ } else {
4727
+ this.state = State.InSpecialComment;
4728
+ this.sectionStart = this.index;
4729
+ }
4730
+ else if (this.isTagStartChar(c)) {
4731
+ this.sectionStart = this.index;
4732
+ const special = this.xmlMode || this.cbs.isInForeignContext?.() ? void 0 : specialStartSequences.get(c | 32);
4733
+ if (special === void 0) this.state = State.InTagName;
4734
+ else {
4735
+ this.isSpecial = true;
4736
+ this.currentSequence = special;
4737
+ this.sequenceIndex = 3;
4738
+ this.state = State.SpecialStartSequence;
4739
+ }
4740
+ } else if (c === CharCodes.Slash) this.state = State.BeforeClosingTagName;
4741
+ else {
4742
+ this.state = State.Text;
4743
+ this.stateText(c);
4744
+ }
4745
+ }
4746
+ stateInTagName(c) {
4747
+ if (isEndOfTagSection(c)) {
4748
+ this.cbs.onopentagname(this.sectionStart, this.index);
4749
+ this.sectionStart = -1;
4750
+ this.state = State.BeforeAttributeName;
4751
+ this.stateBeforeAttributeName(c);
4752
+ }
4753
+ }
4754
+ stateBeforeClosingTagName(c) {
4755
+ if (isWhitespace$1(c)) if (this.xmlMode) {} else {
4756
+ this.state = State.InSpecialComment;
4757
+ this.sectionStart = this.index;
4758
+ }
4759
+ else if (c === CharCodes.Gt) {
4760
+ this.state = State.Text;
4761
+ if (!this.xmlMode) this.sectionStart = this.index + 1;
4762
+ } else {
4763
+ this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment;
4764
+ this.sectionStart = this.index;
4765
+ }
4766
+ }
4767
+ stateInClosingTagName(c) {
4768
+ if (isEndOfTagSection(c)) {
4769
+ this.cbs.onclosetag(this.sectionStart, this.index);
4770
+ this.sectionStart = -1;
4771
+ this.state = State.AfterClosingTagName;
4772
+ this.stateAfterClosingTagName(c);
4773
+ }
4774
+ }
4775
+ stateAfterClosingTagName(c) {
4776
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
4777
+ this.state = State.Text;
4778
+ this.sectionStart = this.index + 1;
4779
+ }
4780
+ }
4781
+ stateBeforeAttributeName(c) {
4782
+ if (c === CharCodes.Gt) {
4783
+ this.cbs.onopentagend(this.index);
4784
+ this.enterTagBody();
4785
+ this.sectionStart = this.index + 1;
4786
+ } else if (c === CharCodes.Slash) this.state = State.InSelfClosingTag;
4787
+ else if (!isWhitespace$1(c)) {
4788
+ this.state = State.InAttributeName;
4789
+ this.sectionStart = this.index;
4790
+ }
4791
+ }
4792
+ /**
4793
+ * Handle `/` before `>` in an opening tag.
4794
+ *
4795
+ * In HTML mode, text-only tags ignore the self-closing flag and still enter
4796
+ * their raw-text/RCDATA/plaintext state unless self-closing tags are being
4797
+ * recognized. In XML mode, or for ordinary tags, the tokenizer returns to
4798
+ * regular text parsing after emitting the self-closing callback.
4799
+ * @param c Current character code point.
4800
+ */
4801
+ stateInSelfClosingTag(c) {
4802
+ if (c === CharCodes.Gt) {
4803
+ this.cbs.onselfclosingtag(this.index);
4804
+ this.sectionStart = this.index + 1;
4805
+ if (!this.recognizeSelfClosing) {
4806
+ this.enterTagBody();
4807
+ return;
4808
+ }
4809
+ this.state = State.Text;
4810
+ this.isSpecial = false;
4811
+ this.currentSequence = Sequences.Empty;
4812
+ } else if (!isWhitespace$1(c)) {
4813
+ this.state = State.BeforeAttributeName;
4814
+ this.stateBeforeAttributeName(c);
4815
+ }
4816
+ }
4817
+ stateInAttributeName(c) {
4818
+ if (c === CharCodes.Eq || isEndOfTagSection(c)) {
4819
+ this.cbs.onattribname(this.sectionStart, this.index);
4820
+ this.sectionStart = this.index;
4821
+ this.state = State.AfterAttributeName;
4822
+ this.stateAfterAttributeName(c);
4823
+ }
4824
+ }
4825
+ stateAfterAttributeName(c) {
4826
+ if (c === CharCodes.Eq) this.state = State.BeforeAttributeValue;
4827
+ else if (c === CharCodes.Slash || c === CharCodes.Gt) {
4828
+ this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
4829
+ this.sectionStart = -1;
4830
+ this.state = State.BeforeAttributeName;
4831
+ this.stateBeforeAttributeName(c);
4832
+ } else if (!isWhitespace$1(c)) {
4833
+ this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
4834
+ this.state = State.InAttributeName;
4835
+ this.sectionStart = this.index;
4836
+ }
4837
+ }
4838
+ stateBeforeAttributeValue(c) {
4839
+ if (c === CharCodes.DoubleQuote) {
4840
+ this.state = State.InAttributeValueDq;
4841
+ this.sectionStart = this.index + 1;
4842
+ } else if (c === CharCodes.SingleQuote) {
4843
+ this.state = State.InAttributeValueSq;
4844
+ this.sectionStart = this.index + 1;
4845
+ } else if (!isWhitespace$1(c)) {
4846
+ this.sectionStart = this.index;
4847
+ this.state = State.InAttributeValueNq;
4848
+ this.stateInAttributeValueNoQuotes(c);
4849
+ }
4850
+ }
4851
+ handleInAttributeValue(c, quote) {
4852
+ if (c === quote || !this.decodeEntities && this.fastForwardTo(quote)) {
4853
+ this.cbs.onattribdata(this.sectionStart, this.index);
4854
+ this.sectionStart = -1;
4855
+ this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1);
4856
+ this.state = State.BeforeAttributeName;
4857
+ } else if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
4858
+ }
4859
+ stateInAttributeValueDoubleQuotes(c) {
4860
+ this.handleInAttributeValue(c, CharCodes.DoubleQuote);
4861
+ }
4862
+ stateInAttributeValueSingleQuotes(c) {
4863
+ this.handleInAttributeValue(c, CharCodes.SingleQuote);
4864
+ }
4865
+ stateInAttributeValueNoQuotes(c) {
4866
+ if (isWhitespace$1(c) || c === CharCodes.Gt) {
4867
+ this.cbs.onattribdata(this.sectionStart, this.index);
4868
+ this.sectionStart = -1;
4869
+ this.cbs.onattribend(QuoteType.Unquoted, this.index);
4870
+ this.state = State.BeforeAttributeName;
4871
+ this.stateBeforeAttributeName(c);
4872
+ } else if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
4873
+ }
4874
+ /**
4875
+ * Distinguish between CDATA, declarations, HTML comments, and HTML bogus
4876
+ * comments after `<!`.
4877
+ *
4878
+ * In HTML mode, only real comments and doctypes stay on declaration paths;
4879
+ * everything else becomes a bogus comment terminated by the next `>`.
4880
+ * @param c Current character code point.
4881
+ */
4882
+ stateBeforeDeclaration(c) {
4883
+ if (c === CharCodes.OpeningSquareBracket) {
4884
+ this.state = State.CDATASequence;
4885
+ this.sequenceIndex = 0;
4886
+ } else if (this.xmlMode) this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration;
4887
+ else if ((c | 32) === Sequences.Doctype[0]) {
4888
+ this.state = State.DeclarationSequence;
4889
+ this.currentSequence = Sequences.Doctype;
4890
+ this.sequenceIndex = 1;
4891
+ } else if (c === CharCodes.Gt) {
4892
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
4893
+ this.state = State.Text;
4894
+ this.sectionStart = this.index + 1;
4895
+ } else if (c === CharCodes.Dash) this.state = State.BeforeComment;
4896
+ else this.state = State.InSpecialComment;
4897
+ }
4898
+ /**
4899
+ * Continue matching `doctype` after `<!d`.
4900
+ *
4901
+ * A full `doctype` match stays on the declaration path; any other name falls
4902
+ * back to an HTML bogus comment, which matches browser behavior for
4903
+ * non-doctype `<!...>` constructs.
4904
+ * @param c Current character code point.
4905
+ */
4906
+ stateDeclarationSequence(c) {
4907
+ if (this.sequenceIndex === this.currentSequence.length) {
4908
+ this.state = State.InDeclaration;
4909
+ this.stateInDeclaration(c);
4910
+ } else if ((c | 32) === this.currentSequence[this.sequenceIndex]) this.sequenceIndex += 1;
4911
+ else if (c === CharCodes.Gt) {
4912
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
4913
+ this.state = State.Text;
4914
+ this.sectionStart = this.index + 1;
4915
+ } else this.state = State.InSpecialComment;
4916
+ }
4917
+ stateInDeclaration(c) {
4918
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
4919
+ this.cbs.ondeclaration(this.sectionStart, this.index);
4920
+ this.state = State.Text;
4921
+ this.sectionStart = this.index + 1;
4922
+ }
4923
+ }
4924
+ /**
4925
+ * XML processing instructions (`<?...?>`).
4926
+ *
4927
+ * In HTML mode `<?` is routed to `InSpecialComment` instead, so this
4928
+ * state is only reachable in XML mode.
4929
+ * @param c Current character code point.
4930
+ */
4931
+ stateInProcessingInstruction(c) {
4932
+ if (c === CharCodes.Questionmark) this.sequenceIndex = 1;
4933
+ else if (c === CharCodes.Gt && this.sequenceIndex === 1) {
4934
+ this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);
4935
+ this.sequenceIndex = 0;
4936
+ this.state = State.Text;
4937
+ this.sectionStart = this.index + 1;
4938
+ } else this.sequenceIndex = Number(this.fastForwardTo(CharCodes.Questionmark));
4939
+ }
4940
+ stateBeforeComment(c) {
4941
+ if (c === CharCodes.Dash) {
4942
+ this.state = State.InCommentLike;
4943
+ this.currentSequence = Sequences.CommentEnd;
4944
+ this.sequenceIndex = 0;
4945
+ this.sectionStart = this.index + 1;
4946
+ } else if (this.xmlMode) this.state = State.InDeclaration;
4947
+ else if (c === CharCodes.Gt) {
4948
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
4949
+ this.state = State.Text;
4950
+ this.sectionStart = this.index + 1;
4951
+ } else this.state = State.InSpecialComment;
4952
+ }
4953
+ stateInSpecialComment(c) {
4954
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
4955
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
4956
+ this.state = State.Text;
4957
+ this.sectionStart = this.index + 1;
4958
+ }
4959
+ }
4960
+ startEntity() {
4961
+ this.baseState = this.state;
4962
+ this.state = State.InEntity;
4963
+ this.entityStart = this.index;
4964
+ this.entityDecoder.startEntity(this.xmlMode ? DecodingMode.Strict : this.baseState === State.Text || this.baseState === State.InSpecialTag ? DecodingMode.Legacy : DecodingMode.Attribute);
4965
+ }
4966
+ stateInEntity() {
4967
+ const indexInBuffer = this.index - this.offset;
4968
+ const length = this.entityDecoder.write(this.buffer, indexInBuffer);
4969
+ if (length >= 0) {
4970
+ this.state = this.baseState;
4971
+ if (length === 0) this.index -= 1;
4972
+ } else {
4973
+ if (indexInBuffer < this.buffer.length && this.buffer.charCodeAt(indexInBuffer) === CharCodes.Amp) {
4974
+ this.state = this.baseState;
4975
+ this.index -= 1;
4976
+ return;
4977
+ }
4978
+ this.index = this.offset + this.buffer.length - 1;
4979
+ }
4980
+ }
4981
+ /**
4982
+ * Remove data that has already been consumed from the buffer.
4983
+ */
4984
+ cleanup() {
4985
+ if (this.running && this.sectionStart !== this.index) {
4986
+ if (this.state === State.Text || this.state === State.InPlainText || this.state === State.InSpecialTag && this.sequenceIndex === 0) {
4987
+ this.cbs.ontext(this.sectionStart, this.index);
4988
+ this.sectionStart = this.index;
4989
+ } else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) {
4990
+ this.cbs.onattribdata(this.sectionStart, this.index);
4991
+ this.sectionStart = this.index;
4992
+ }
4993
+ }
4994
+ }
4995
+ shouldContinue() {
4996
+ return this.index < this.buffer.length + this.offset && this.running;
4997
+ }
4998
+ /**
4999
+ * Iterates through the buffer, calling the function corresponding to the current state.
5000
+ *
5001
+ * States that are more likely to be hit are higher up, as a performance improvement.
5002
+ */
5003
+ parse() {
5004
+ while (this.shouldContinue()) {
5005
+ const c = this.buffer.charCodeAt(this.index - this.offset);
5006
+ switch (this.state) {
5007
+ case State.Text:
5008
+ this.stateText(c);
5009
+ break;
5010
+ case State.InPlainText:
5011
+ this.index = this.buffer.length + this.offset - 1;
5012
+ break;
5013
+ case State.SpecialStartSequence:
5014
+ this.stateSpecialStartSequence(c);
5015
+ break;
5016
+ case State.InSpecialTag:
5017
+ this.stateInSpecialTag(c);
5018
+ break;
5019
+ case State.CDATASequence:
5020
+ this.stateCDATASequence(c);
5021
+ break;
5022
+ case State.DeclarationSequence:
5023
+ this.stateDeclarationSequence(c);
5024
+ break;
5025
+ case State.InAttributeValueDq:
5026
+ this.stateInAttributeValueDoubleQuotes(c);
5027
+ break;
5028
+ case State.InAttributeName:
5029
+ this.stateInAttributeName(c);
5030
+ break;
5031
+ case State.InCommentLike:
5032
+ this.stateInCommentLike(c);
5033
+ break;
5034
+ case State.InSpecialComment:
5035
+ this.stateInSpecialComment(c);
5036
+ break;
5037
+ case State.BeforeAttributeName:
5038
+ this.stateBeforeAttributeName(c);
5039
+ break;
5040
+ case State.InTagName:
5041
+ this.stateInTagName(c);
5042
+ break;
5043
+ case State.InClosingTagName:
5044
+ this.stateInClosingTagName(c);
5045
+ break;
5046
+ case State.BeforeTagName:
5047
+ this.stateBeforeTagName(c);
5048
+ break;
5049
+ case State.AfterAttributeName:
5050
+ this.stateAfterAttributeName(c);
5051
+ break;
5052
+ case State.InAttributeValueSq:
5053
+ this.stateInAttributeValueSingleQuotes(c);
5054
+ break;
5055
+ case State.BeforeAttributeValue:
5056
+ this.stateBeforeAttributeValue(c);
5057
+ break;
5058
+ case State.BeforeClosingTagName:
5059
+ this.stateBeforeClosingTagName(c);
5060
+ break;
5061
+ case State.AfterClosingTagName:
5062
+ this.stateAfterClosingTagName(c);
5063
+ break;
5064
+ case State.InAttributeValueNq:
5065
+ this.stateInAttributeValueNoQuotes(c);
5066
+ break;
5067
+ case State.InSelfClosingTag:
5068
+ this.stateInSelfClosingTag(c);
5069
+ break;
5070
+ case State.InDeclaration:
5071
+ this.stateInDeclaration(c);
5072
+ break;
5073
+ case State.BeforeDeclaration:
5074
+ this.stateBeforeDeclaration(c);
5075
+ break;
5076
+ case State.BeforeComment:
5077
+ this.stateBeforeComment(c);
5078
+ break;
5079
+ case State.InProcessingInstruction:
5080
+ this.stateInProcessingInstruction(c);
5081
+ break;
5082
+ case State.InEntity:
5083
+ this.stateInEntity();
5084
+ break;
5085
+ }
5086
+ this.index++;
5087
+ }
5088
+ this.cleanup();
5089
+ }
5090
+ finish() {
5091
+ if (this.state === State.InEntity) {
5092
+ this.entityDecoder.end();
5093
+ this.state = this.baseState;
5094
+ }
5095
+ this.handleTrailingData();
5096
+ this.cbs.onend();
5097
+ }
5098
+ handleTrailingCommentLikeData(endIndex) {
5099
+ if (this.state !== State.InCommentLike) return false;
5100
+ if (this.currentSequence === Sequences.CdataEnd) if (this.xmlMode) {
5101
+ if (this.sectionStart < endIndex) this.cbs.oncdata(this.sectionStart, endIndex, 0);
5102
+ } else {
5103
+ const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;
5104
+ this.cbs.oncomment(cdataStart, endIndex, 0);
5105
+ }
5106
+ else {
5107
+ const offset = this.xmlMode ? 0 : Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);
5108
+ this.cbs.oncomment(this.sectionStart, endIndex, offset);
5109
+ }
5110
+ return true;
5111
+ }
5112
+ handleTrailingMarkupDeclaration(endIndex) {
5113
+ if (this.xmlMode) switch (this.state) {
5114
+ case State.InSpecialComment:
5115
+ case State.BeforeComment:
5116
+ case State.CDATASequence:
5117
+ case State.DeclarationSequence:
5118
+ case State.InDeclaration:
5119
+ this.cbs.ontext(this.sectionStart, endIndex);
5120
+ return true;
5121
+ default: return false;
5122
+ }
5123
+ switch (this.state) {
5124
+ case State.BeforeDeclaration:
5125
+ case State.InSpecialComment:
5126
+ case State.BeforeComment:
5127
+ case State.CDATASequence:
5128
+ this.cbs.oncomment(this.sectionStart, endIndex, 0);
5129
+ return true;
5130
+ case State.DeclarationSequence:
5131
+ if (this.sequenceIndex !== Sequences.Doctype.length) this.cbs.oncomment(this.sectionStart, endIndex, 0);
5132
+ return true;
5133
+ case State.InDeclaration: return true;
5134
+ default: return false;
5135
+ }
5136
+ }
5137
+ /** Handle any trailing data. */
5138
+ handleTrailingData() {
5139
+ const endIndex = this.buffer.length + this.offset;
5140
+ if (this.handleTrailingCommentLikeData(endIndex) || this.handleTrailingMarkupDeclaration(endIndex)) return;
5141
+ if (this.sectionStart >= endIndex) return;
5142
+ switch (this.state) {
5143
+ case State.InTagName:
5144
+ case State.BeforeAttributeName:
5145
+ case State.BeforeAttributeValue:
5146
+ case State.AfterAttributeName:
5147
+ case State.InAttributeName:
5148
+ case State.InAttributeValueSq:
5149
+ case State.InAttributeValueDq:
5150
+ case State.InAttributeValueNq:
5151
+ case State.InClosingTagName: break;
5152
+ default: this.cbs.ontext(this.sectionStart, endIndex);
5153
+ }
5154
+ }
5155
+ emitCodePoint(cp, consumed) {
5156
+ if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) {
5157
+ if (this.sectionStart < this.entityStart) this.cbs.onattribdata(this.sectionStart, this.entityStart);
5158
+ this.sectionStart = this.entityStart + consumed;
5159
+ this.index = this.sectionStart - 1;
5160
+ this.cbs.onattribentity(cp);
5161
+ } else {
5162
+ if (this.sectionStart < this.entityStart) this.cbs.ontext(this.sectionStart, this.entityStart);
5163
+ this.sectionStart = this.entityStart + consumed;
5164
+ this.index = this.sectionStart - 1;
5165
+ this.cbs.ontextentity(cp, this.sectionStart);
5166
+ }
5167
+ }
5168
+ };
5169
+ //#endregion
5170
+ //#region ../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Parser.js
5171
+ const { fromCodePoint } = String;
5172
+ const formTags = /* @__PURE__ */ new Set([
5173
+ "input",
5174
+ "option",
5175
+ "optgroup",
5176
+ "select",
5177
+ "button",
5178
+ "datalist",
5179
+ "textarea"
5180
+ ]);
5181
+ const pTag = /* @__PURE__ */ new Set(["p"]);
5182
+ const headingTags = /* @__PURE__ */ new Set([
5183
+ "h1",
5184
+ "h2",
5185
+ "h3",
5186
+ "h4",
5187
+ "h5",
5188
+ "h6",
5189
+ "p"
5190
+ ]);
5191
+ const tableSectionTags = /* @__PURE__ */ new Set(["thead", "tbody"]);
5192
+ const ddtTags = /* @__PURE__ */ new Set(["dd", "dt"]);
5193
+ const rtpTags = /* @__PURE__ */ new Set(["rt", "rp"]);
5194
+ const openImpliesClose = /* @__PURE__ */ new Map([
5195
+ ["tr", /* @__PURE__ */ new Set([
5196
+ "tr",
5197
+ "th",
5198
+ "td"
5199
+ ])],
5200
+ ["th", /* @__PURE__ */ new Set(["th"])],
5201
+ ["td", /* @__PURE__ */ new Set([
5202
+ "thead",
5203
+ "th",
5204
+ "td"
5205
+ ])],
5206
+ ["body", /* @__PURE__ */ new Set([
5207
+ "head",
5208
+ "link",
5209
+ "script"
5210
+ ])],
5211
+ ["a", /* @__PURE__ */ new Set(["a"])],
5212
+ ["li", /* @__PURE__ */ new Set(["li"])],
5213
+ ["p", pTag],
5214
+ ["h1", headingTags],
5215
+ ["h2", headingTags],
5216
+ ["h3", headingTags],
5217
+ ["h4", headingTags],
5218
+ ["h5", headingTags],
5219
+ ["h6", headingTags],
5220
+ ["select", formTags],
5221
+ ["input", formTags],
5222
+ ["output", formTags],
5223
+ ["button", formTags],
5224
+ ["datalist", formTags],
5225
+ ["textarea", formTags],
5226
+ ["option", /* @__PURE__ */ new Set(["option"])],
5227
+ ["optgroup", /* @__PURE__ */ new Set(["optgroup", "option"])],
5228
+ ["dd", ddtTags],
5229
+ ["dt", ddtTags],
5230
+ ["address", pTag],
5231
+ ["article", pTag],
5232
+ ["aside", pTag],
5233
+ ["blockquote", pTag],
5234
+ ["details", pTag],
5235
+ ["div", pTag],
5236
+ ["dl", pTag],
5237
+ ["fieldset", pTag],
5238
+ ["figcaption", pTag],
5239
+ ["figure", pTag],
5240
+ ["footer", pTag],
5241
+ ["form", pTag],
5242
+ ["header", pTag],
5243
+ ["hr", pTag],
5244
+ ["main", pTag],
5245
+ ["nav", pTag],
5246
+ ["ol", pTag],
5247
+ ["pre", pTag],
5248
+ ["section", pTag],
5249
+ ["table", pTag],
5250
+ ["ul", pTag],
5251
+ ["rt", rtpTags],
5252
+ ["rp", rtpTags],
5253
+ ["tbody", tableSectionTags],
5254
+ ["tfoot", tableSectionTags]
5255
+ ]);
5256
+ const DOCUMENT_TYPE = "doctype";
5257
+ const voidElements = /* @__PURE__ */ new Set([
5258
+ "area",
5259
+ "base",
5260
+ "basefont",
5261
+ "br",
5262
+ "col",
5263
+ "command",
5264
+ "embed",
5265
+ "frame",
5266
+ "hr",
5267
+ "img",
5268
+ "input",
5269
+ "isindex",
5270
+ "keygen",
5271
+ "link",
5272
+ "meta",
5273
+ "param",
5274
+ "source",
5275
+ "track",
5276
+ "wbr"
5277
+ ]);
5278
+ const foreignContextElements = /* @__PURE__ */ new Set(["math", "svg"]);
5279
+ /**
5280
+ * Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML).
5281
+ *
5282
+ * Entries must use the SVG-adjusted casing (e.g. "foreignObject" not
5283
+ * "foreignobject") since they are compared against adjusted tag names.
5284
+ */
5285
+ const htmlIntegrationElements = /* @__PURE__ */ new Set([
5286
+ "mi",
5287
+ "mo",
5288
+ "mn",
5289
+ "ms",
5290
+ "mtext",
5291
+ "annotation-xml",
5292
+ "foreignObject",
5293
+ "desc",
5294
+ "title"
5295
+ ]);
5296
+ const svgTagNameAdjustments = /* @__PURE__ */ new Map([
5297
+ ["altglyph", "altGlyph"],
5298
+ ["altglyphdef", "altGlyphDef"],
5299
+ ["altglyphitem", "altGlyphItem"],
5300
+ ["animatecolor", "animateColor"],
5301
+ ["animatemotion", "animateMotion"],
5302
+ ["animatetransform", "animateTransform"],
5303
+ ["clippath", "clipPath"],
5304
+ ["feblend", "feBlend"],
5305
+ ["fecolormatrix", "feColorMatrix"],
5306
+ ["fecomponenttransfer", "feComponentTransfer"],
5307
+ ["fecomposite", "feComposite"],
5308
+ ["feconvolvematrix", "feConvolveMatrix"],
5309
+ ["fediffuselighting", "feDiffuseLighting"],
5310
+ ["fedisplacementmap", "feDisplacementMap"],
5311
+ ["fedistantlight", "feDistantLight"],
5312
+ ["fedropshadow", "feDropShadow"],
5313
+ ["feflood", "feFlood"],
5314
+ ["fefunca", "feFuncA"],
5315
+ ["fefuncb", "feFuncB"],
5316
+ ["fefuncg", "feFuncG"],
5317
+ ["fefuncr", "feFuncR"],
5318
+ ["fegaussianblur", "feGaussianBlur"],
5319
+ ["feimage", "feImage"],
5320
+ ["femerge", "feMerge"],
5321
+ ["femergenode", "feMergeNode"],
5322
+ ["femorphology", "feMorphology"],
5323
+ ["feoffset", "feOffset"],
5324
+ ["fepointlight", "fePointLight"],
5325
+ ["fespecularlighting", "feSpecularLighting"],
5326
+ ["fespotlight", "feSpotLight"],
5327
+ ["fetile", "feTile"],
5328
+ ["feturbulence", "feTurbulence"],
5329
+ ["foreignobject", "foreignObject"],
5330
+ ["glyphref", "glyphRef"],
5331
+ ["lineargradient", "linearGradient"],
5332
+ ["radialgradient", "radialGradient"],
5333
+ ["textpath", "textPath"]
5334
+ ]);
5335
+ var ForeignContext;
5336
+ (function(ForeignContext) {
5337
+ ForeignContext[ForeignContext["None"] = 0] = "None";
5338
+ ForeignContext[ForeignContext["Svg"] = 1] = "Svg";
5339
+ ForeignContext[ForeignContext["MathML"] = 2] = "MathML";
5340
+ })(ForeignContext || (ForeignContext = {}));
5341
+ const reNameEnd = /\s|\//;
5342
+ /**
5343
+ * Incremental parser implementation.
5344
+ */
5345
+ var Parser = class {
5346
+ options;
5347
+ /** The start index of the last event. */
5348
+ startIndex = 0;
5349
+ /** The end index of the last event. */
5350
+ endIndex = 0;
5351
+ /**
5352
+ * Store the start index of the current open tag,
5353
+ * so we can update the start index for attributes.
5354
+ */
5355
+ openTagStart = 0;
5356
+ tagname = "";
5357
+ attribname = "";
5358
+ attribvalue = "";
5359
+ attribs = null;
5360
+ stack = [];
5361
+ foreignContext;
5362
+ cbs;
5363
+ lowerCaseTagNames;
5364
+ lowerCaseAttributeNames;
5365
+ recognizeSelfClosing;
5366
+ /** We are parsing HTML. Inverse of the `xmlMode` option. */
5367
+ htmlMode;
5368
+ tokenizer;
5369
+ buffers = [];
5370
+ bufferOffset = 0;
5371
+ /** The index of the last written buffer. Used when resuming after a `pause()`. */
5372
+ writeIndex = 0;
5373
+ /** Indicates whether the parser has finished running / `.end` has been called. */
5374
+ ended = false;
5375
+ constructor(cbs, options = {}) {
5376
+ this.options = options;
5377
+ this.cbs = cbs ?? {};
5378
+ this.htmlMode = !this.options.xmlMode;
5379
+ this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode;
5380
+ this.lowerCaseAttributeNames = options.lowerCaseAttributeNames ?? this.htmlMode;
5381
+ this.recognizeSelfClosing = options.recognizeSelfClosing ?? !this.htmlMode;
5382
+ this.tokenizer = new (options.Tokenizer ?? Tokenizer$1)(this.options, this);
5383
+ this.foreignContext = [ForeignContext.None];
5384
+ this.cbs.onparserinit?.(this);
5385
+ }
5386
+ /**
5387
+ * @param start Start index for the current parser event.
5388
+ * @param endIndex End index for the current parser event.
5389
+ * @internal
5390
+ */
5391
+ ontext(start, endIndex) {
5392
+ const data = this.getSlice(start, endIndex);
5393
+ this.endIndex = endIndex - 1;
5394
+ this.cbs.ontext?.(data);
5395
+ this.startIndex = endIndex;
5396
+ }
5397
+ /**
5398
+ * @param cp Current Unicode code point.
5399
+ * @param endIndex End index for the current parser event.
5400
+ * @internal
5401
+ */
5402
+ ontextentity(cp, endIndex) {
5403
+ this.endIndex = endIndex - 1;
5404
+ this.cbs.ontext?.(fromCodePoint(cp));
5405
+ this.startIndex = endIndex;
5406
+ }
5407
+ /** @internal */
5408
+ isInForeignContext() {
5409
+ return this.foreignContext[0] !== ForeignContext.None;
5410
+ }
5411
+ /**
5412
+ * Checks if the current tag is a void element. Override this if you want
5413
+ * to specify your own additional void elements.
5414
+ * @param name Name of the pseudo selector.
5415
+ */
5416
+ isVoidElement(name) {
5417
+ return this.htmlMode && voidElements.has(name);
5418
+ }
5419
+ /**
5420
+ * Read a tag name from the buffer.
5421
+ *
5422
+ * When `lowerCaseTagNames` is enabled (the default in HTML mode), the name
5423
+ * is lowercased and may be adjusted for SVG casing or the `image` → `img`
5424
+ * alias.
5425
+ * @param start Start index of the tag name in the buffer.
5426
+ * @param endIndex End index of the tag name in the buffer.
5427
+ */
5428
+ readTagName(start, endIndex) {
5429
+ const name = this.lowerCaseTagNames ? this.getSlice(start, endIndex).toLowerCase() : this.getSlice(start, endIndex);
5430
+ if (!(this.lowerCaseTagNames && this.htmlMode)) return name;
5431
+ if (this.foreignContext[0] === ForeignContext.Svg) return svgTagNameAdjustments.get(name) ?? name;
5432
+ if (this.foreignContext.length > 1) {
5433
+ const adjusted = svgTagNameAdjustments.get(name);
5434
+ if (adjusted !== void 0 && this.stack.includes(adjusted)) return adjusted;
5435
+ }
5436
+ if (!this.isInForeignContext()) return name === "image" ? "img" : name;
5437
+ return name;
5438
+ }
5439
+ /**
5440
+ * @param start Start index for the current parser event.
5441
+ * @param endIndex End index for the current parser event.
5442
+ * @internal
5443
+ */
5444
+ onopentagname(start, endIndex) {
5445
+ this.endIndex = endIndex;
5446
+ this.emitOpenTag(this.readTagName(start, endIndex));
5447
+ }
5448
+ emitOpenTag(name) {
5449
+ this.openTagStart = this.startIndex;
5450
+ this.tagname = name;
5451
+ if (this.htmlMode && name === "form" && this.stack.includes("form")) {
5452
+ this.tagname = "";
5453
+ return;
5454
+ }
5455
+ const impliesClose = this.htmlMode && openImpliesClose.get(name);
5456
+ if (impliesClose) while (this.stack.length > 0 && impliesClose.has(this.stack[0])) this.popElement(true);
5457
+ if (!this.isVoidElement(name)) {
5458
+ this.stack.unshift(name);
5459
+ if (this.htmlMode) {
5460
+ if (name === "svg") this.foreignContext.unshift(ForeignContext.Svg);
5461
+ else if (name === "math") this.foreignContext.unshift(ForeignContext.MathML);
5462
+ else if (htmlIntegrationElements.has(name)) this.foreignContext.unshift(ForeignContext.None);
5463
+ }
5464
+ }
5465
+ this.cbs.onopentagname?.(name);
5466
+ if (this.cbs.onopentag) this.attribs = {};
5467
+ }
5468
+ endOpenTag(isImplied) {
5469
+ this.startIndex = this.openTagStart;
5470
+ if (this.attribs) {
5471
+ this.cbs.onopentag?.(this.tagname, this.attribs, isImplied);
5472
+ this.attribs = null;
5473
+ }
5474
+ if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) this.cbs.onclosetag(this.tagname, true);
5475
+ this.tagname = "";
5476
+ }
5477
+ /**
5478
+ * @param endIndex End index for the current parser event.
5479
+ * @internal
5480
+ */
5481
+ onopentagend(endIndex) {
5482
+ this.endIndex = endIndex;
5483
+ this.endOpenTag(false);
5484
+ this.startIndex = endIndex + 1;
5485
+ }
5486
+ /**
5487
+ * @param start Start index for the current parser event.
5488
+ * @param endIndex End index for the current parser event.
5489
+ * @internal
5490
+ */
5491
+ onclosetag(start, endIndex) {
5492
+ this.endIndex = endIndex;
5493
+ const name = this.readTagName(start, endIndex);
5494
+ if (!this.isVoidElement(name)) {
5495
+ const pos = this.stack.indexOf(name);
5496
+ if (pos !== -1) {
5497
+ for (let index = 0; index < pos; index++) this.popElement(true);
5498
+ this.popElement(false);
5499
+ } else if (this.htmlMode && name === "p") {
5500
+ this.emitOpenTag("p");
5501
+ this.closeCurrentTag(true);
5502
+ }
5503
+ } else if (this.htmlMode && name === "br") {
5504
+ this.cbs.onopentagname?.("br");
5505
+ this.cbs.onopentag?.("br", {}, true);
5506
+ this.cbs.onclosetag?.("br", false);
5507
+ }
5508
+ this.startIndex = endIndex + 1;
5509
+ }
5510
+ /**
5511
+ * @param endIndex End index for the current parser event.
5512
+ * @internal
5513
+ */
5514
+ onselfclosingtag(endIndex) {
5515
+ this.endIndex = endIndex;
5516
+ if (this.recognizeSelfClosing || this.isInForeignContext()) {
5517
+ this.closeCurrentTag(false);
5518
+ this.startIndex = endIndex + 1;
5519
+ } else this.onopentagend(endIndex);
5520
+ }
5521
+ /**
5522
+ * Pop the top element off the stack, emit a close event, and maintain
5523
+ * the foreign context stack.
5524
+ * @param implied Whether this close is implied (not from an explicit end tag).
5525
+ */
5526
+ popElement(implied) {
5527
+ const element = this.stack.shift();
5528
+ if (this.htmlMode && (foreignContextElements.has(element) || htmlIntegrationElements.has(element))) this.foreignContext.shift();
5529
+ this.cbs.onclosetag?.(element, implied);
5530
+ }
5531
+ closeCurrentTag(isOpenImplied) {
5532
+ const name = this.tagname;
5533
+ this.endOpenTag(isOpenImplied);
5534
+ if (this.stack[0] === name) this.popElement(!isOpenImplied);
5535
+ }
5536
+ /**
5537
+ * @param start Start index for the current parser event.
5538
+ * @param endIndex End index for the current parser event.
5539
+ * @internal
5540
+ */
5541
+ onattribname(start, endIndex) {
5542
+ this.startIndex = start;
5543
+ const name = this.getSlice(start, endIndex);
5544
+ this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name;
5545
+ }
5546
+ /**
5547
+ * @param start Start index for the current parser event.
5548
+ * @param endIndex End index for the current parser event.
5549
+ * @internal
5550
+ */
5551
+ onattribdata(start, endIndex) {
5552
+ this.attribvalue += this.getSlice(start, endIndex);
5553
+ }
5554
+ /**
5555
+ * @param cp Current Unicode code point.
5556
+ * @internal
5557
+ */
5558
+ onattribentity(cp) {
5559
+ this.attribvalue += fromCodePoint(cp);
5560
+ }
5561
+ /**
5562
+ * @param quote Quote type used for the current attribute.
5563
+ * @param endIndex End index for the current parser event.
5564
+ * @internal
5565
+ */
5566
+ onattribend(quote, endIndex) {
5567
+ this.endIndex = endIndex;
5568
+ this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double ? "\"" : quote === QuoteType.Single ? "'" : quote === QuoteType.NoValue ? void 0 : null);
5569
+ if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) this.attribs[this.attribname] = this.attribvalue;
5570
+ this.attribvalue = "";
5571
+ }
5572
+ getInstructionName(value) {
5573
+ const index = value.search(reNameEnd);
5574
+ let name = index < 0 ? value : value.substr(0, index);
5575
+ if (this.lowerCaseTagNames) name = name.toLowerCase();
5576
+ return name;
5577
+ }
5578
+ /**
5579
+ * @param start Start index for the current parser event.
5580
+ * @param endIndex End index for the current parser event.
5581
+ * @internal
5582
+ */
5583
+ ondeclaration(start, endIndex) {
5584
+ this.endIndex = endIndex;
5585
+ const value = this.getSlice(start, endIndex);
5586
+ if (this.cbs.onprocessinginstruction) {
5587
+ const name = this.htmlMode ? this.lowerCaseTagNames ? DOCUMENT_TYPE : value.slice(0, 7) : this.getInstructionName(value);
5588
+ this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);
5589
+ }
5590
+ this.startIndex = endIndex + 1;
5591
+ }
5592
+ /**
5593
+ * @param start Start index for the current parser event.
5594
+ * @param endIndex End index for the current parser event.
5595
+ * @internal
5596
+ */
5597
+ onprocessinginstruction(start, endIndex) {
5598
+ this.endIndex = endIndex;
5599
+ const value = this.getSlice(start, endIndex);
5600
+ if (this.cbs.onprocessinginstruction) {
5601
+ const name = this.getInstructionName(value);
5602
+ this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);
5603
+ }
5604
+ this.startIndex = endIndex + 1;
5605
+ }
5606
+ /**
5607
+ * @param start Start index for the current parser event.
5608
+ * @param endIndex End index for the current parser event.
5609
+ * @param offset Offset applied when computing parser indices.
5610
+ * @internal
5611
+ */
5612
+ oncomment(start, endIndex, offset) {
5613
+ this.endIndex = endIndex;
5614
+ this.cbs.oncomment?.(this.getSlice(start, endIndex - offset));
5615
+ this.cbs.oncommentend?.();
5616
+ this.startIndex = endIndex + 1;
5617
+ }
5618
+ /**
5619
+ * @param start Start index for the current parser event.
5620
+ * @param endIndex End index for the current parser event.
5621
+ * @param offset Offset applied when computing parser indices.
5622
+ * @internal
5623
+ */
5624
+ oncdata(start, endIndex, offset) {
5625
+ this.endIndex = endIndex;
5626
+ const value = this.getSlice(start, endIndex - offset);
5627
+ if (!this.htmlMode || this.options.recognizeCDATA) {
5628
+ this.cbs.oncdatastart?.();
5629
+ this.cbs.ontext?.(value);
5630
+ this.cbs.oncdataend?.();
5631
+ } else if (this.isInForeignContext()) this.cbs.ontext?.(value);
5632
+ else {
5633
+ this.cbs.oncomment?.(`[CDATA[${value}]]`);
5634
+ this.cbs.oncommentend?.();
5635
+ }
5636
+ this.startIndex = endIndex + 1;
5637
+ }
5638
+ /** @internal */
5639
+ onend() {
5640
+ if (this.cbs.onclosetag) {
5641
+ this.endIndex = this.startIndex;
5642
+ for (let index = 0; index < this.stack.length; index++) this.cbs.onclosetag(this.stack[index], true);
5643
+ }
5644
+ this.cbs.onend?.();
5645
+ }
5646
+ /**
5647
+ * Resets the parser to a blank state, ready to parse a new HTML document
5648
+ */
5649
+ reset() {
5650
+ this.cbs.onreset?.();
5651
+ this.tokenizer.reset();
5652
+ this.tagname = "";
5653
+ this.attribname = "";
5654
+ this.attribvalue = "";
5655
+ this.attribs = null;
5656
+ this.stack.length = 0;
5657
+ this.startIndex = 0;
5658
+ this.endIndex = 0;
5659
+ this.cbs.onparserinit?.(this);
5660
+ this.buffers.length = 0;
5661
+ this.foreignContext.length = 0;
5662
+ this.foreignContext.unshift(ForeignContext.None);
5663
+ this.bufferOffset = 0;
5664
+ this.writeIndex = 0;
5665
+ this.ended = false;
5666
+ }
5667
+ /**
5668
+ * Resets the parser, then parses a complete document and
5669
+ * pushes it to the handler.
5670
+ * @param data Document to parse.
5671
+ */
5672
+ parseComplete(data) {
5673
+ this.reset();
5674
+ this.end(data);
5675
+ }
5676
+ getSlice(start, end) {
5677
+ if (start === end) return "";
5678
+ while (start - this.bufferOffset >= this.buffers[0].length) this.shiftBuffer();
5679
+ let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);
5680
+ while (end - this.bufferOffset > this.buffers[0].length) {
5681
+ this.shiftBuffer();
5682
+ slice += this.buffers[0].slice(0, end - this.bufferOffset);
5683
+ }
5684
+ return slice;
5685
+ }
5686
+ shiftBuffer() {
5687
+ this.bufferOffset += this.buffers[0].length;
5688
+ this.writeIndex--;
5689
+ this.buffers.shift();
5690
+ }
5691
+ /**
5692
+ * Parses a chunk of data and calls the corresponding callbacks.
5693
+ * @param chunk Chunk to parse.
5694
+ */
5695
+ write(chunk) {
5696
+ if (this.ended) {
5697
+ this.cbs.onerror?.(/* @__PURE__ */ new Error(".write() after done!"));
5698
+ return;
5699
+ }
5700
+ this.buffers.push(chunk);
5701
+ if (this.tokenizer.running) {
5702
+ this.tokenizer.write(chunk);
5703
+ this.writeIndex++;
5704
+ }
5705
+ }
5706
+ /**
5707
+ * Parses the end of the buffer and clears the stack, calls onend.
5708
+ * @param chunk Optional final chunk to parse.
5709
+ */
5710
+ end(chunk) {
5711
+ if (this.ended) {
5712
+ this.cbs.onerror?.(/* @__PURE__ */ new Error(".end() after done!"));
5713
+ return;
5714
+ }
5715
+ if (chunk) this.write(chunk);
5716
+ this.ended = true;
5717
+ this.tokenizer.end();
5718
+ }
5719
+ /**
5720
+ * Pauses parsing. The parser won't emit events until `resume` is called.
5721
+ */
5722
+ pause() {
5723
+ this.tokenizer.pause();
5724
+ }
5725
+ /**
5726
+ * Resumes parsing after `pause` was called.
5727
+ */
5728
+ resume() {
5729
+ this.tokenizer.resume();
5730
+ while (this.tokenizer.running && this.writeIndex < this.buffers.length) this.tokenizer.write(this.buffers[this.writeIndex++]);
5731
+ if (this.ended) this.tokenizer.end();
5732
+ }
5733
+ };
5734
+ //#endregion
3783
5735
  //#region src/wxml/whitespace.ts
3784
5736
  const WHITESPACE_CODES = /* @__PURE__ */ new Set([
3785
5737
  9,
@@ -5278,7 +7230,8 @@ async function resolveGeneratorSource(_majorVersion, runtimeState, rawSource, fi
5278
7230
  index: 0,
5279
7231
  matched: true
5280
7232
  }) : void 0;
5281
- const configuredCssSource = normalizedSourceOptions && hasConfiguredTailwindV4CssSource(normalizedSourceOptions) && hasTailwindGeneratedCssMarkers(rawSource) ? matchedCssSource ?? candidateMatchedCssSource ?? singleConfiguredCssSource ?? await resolveTailwindV4Source(normalizedSourceOptions) : void 0;
7233
+ const canResolveCombinedConfiguredCssSources = (normalizedSourceOptions?.cssSources?.length ?? 0) <= 1 || hasTailwindGeneratedCss(rawSource);
7234
+ const configuredCssSource = normalizedSourceOptions && hasConfiguredTailwindV4CssSource(normalizedSourceOptions) && hasTailwindGeneratedCssMarkers(rawSource) ? matchedCssSource ?? candidateMatchedCssSource ?? singleConfiguredCssSource ?? (canResolveCombinedConfiguredCssSources ? await resolveTailwindV4Source(normalizedSourceOptions) : void 0) : void 0;
5282
7235
  if (configuredCssSource) return generatorOptions?.config ? {
5283
7236
  ...configuredCssSource,
5284
7237
  css: prependConfigDirective(configuredCssSource.css, generatorOptions.config)
@@ -6176,6 +8129,8 @@ async function generateCssByGenerator(options) {
6176
8129
  }
6177
8130
  debug("tailwind direct css generation prefix mismatch, append transformed bundle css %s", file);
6178
8131
  let css = generatedCss;
8132
+ const distinctUserLayerParts = hasDistinctUserRawSource && hasUserCssLayerBlocks(generatedUserCssRawSource) ? splitUserCssLayerBlocks(generatedUserCssRawSource) : void 0;
8133
+ let restoredDistinctUserLayerCss = false;
6179
8134
  if (generated.target === "weapp" && generatorRawSource.includes("weapp-tailwindcss generator-placeholder") && !hasUserCssLayerBlocks(generatorRawSource)) css = createCssSourceOrderAppend$1(await transformGeneratorUserCss(generatedUserCssRawSource, {
6180
8135
  generatorTarget: generated.target,
6181
8136
  generatorStyleOptions,
@@ -6205,10 +8160,26 @@ async function generateCssByGenerator(options) {
6205
8160
  if (shouldFinalizeMarkedUserLayerComponentsCss(file)) css = reorderMarkedUserLayerComponentsCss(css);
6206
8161
  }
6207
8162
  }
8163
+ if (hasDistinctUserRawSource && distinctUserLayerParts) {
8164
+ const layerUserCss = await transformGeneratorUserCss(distinctUserLayerParts.layer, {
8165
+ generatorTarget: generated.target,
8166
+ generatorStyleOptions,
8167
+ cssUserHandlerOptions,
8168
+ styleHandler,
8169
+ importFallback: generatorOptions.importFallback,
8170
+ processed: userRawSourceProcessed
8171
+ });
8172
+ if ((0, _weapp_tailwindcss_postcss.filterExistingCssRules)(css, layerUserCss).trim().length > 0) {
8173
+ css = createCssSourceOrderAppend$1(wrapUserLayerComponentsCss(layerUserCss), css);
8174
+ restoredDistinctUserLayerCss = true;
8175
+ if (shouldFinalizeMarkedUserLayerComponentsCss(file)) css = reorderMarkedUserLayerComponentsCss(css);
8176
+ }
8177
+ }
6208
8178
  }
6209
8179
  if (hasMatchedCssSourceFile || generated.target === "web") {
6210
8180
  if (generated.target === "weapp" && !hasGeneratedCss && !hasGeneratedMarkers) {
6211
- const userCss = await transformGeneratorUserCss(generatedUserCssRawSource, {
8181
+ const distinctUserCssRawSource = restoredDistinctUserLayerCss ? distinctUserLayerParts?.rest ?? generatedUserCssRawSource : generatedUserCssRawSource;
8182
+ const userCss = await transformGeneratorUserCss(distinctUserCssRawSource, {
6212
8183
  generatorTarget: generated.target,
6213
8184
  generatorStyleOptions,
6214
8185
  cssUserHandlerOptions,
@@ -6216,10 +8187,11 @@ async function generateCssByGenerator(options) {
6216
8187
  importFallback: generatorOptions.importFallback,
6217
8188
  processed: userRawSourceProcessed
6218
8189
  });
6219
- const missingUserCss = isCssAlreadyRepresentedByMarkers(css, generatedUserCssRawSource) ? (0, _weapp_tailwindcss_postcss.filterExistingCssRules)(css, userCss) : userCss;
8190
+ const missingUserCss = isCssAlreadyRepresentedByMarkers(css, distinctUserCssRawSource) ? (0, _weapp_tailwindcss_postcss.filterExistingCssRules)(css, userCss) : userCss;
6220
8191
  css = createCssSourceOrderAppend$1(css, missingUserCss);
6221
8192
  } else if (hasMatchedCssSourceFile && generated.target === "weapp" && hasGeneratedMarkers && !hasGeneratedCss) {
6222
- const userCss = await transformGeneratorUserCss(removeTailwindV4GeneratedUserCssArtifacts(userCssRawSource), {
8193
+ const cleanedUserCssRawSource = removeTailwindV4GeneratedUserCssArtifacts(userCssRawSource);
8194
+ const userCss = await transformGeneratorUserCss(restoredDistinctUserLayerCss && hasUserCssLayerBlocks(cleanedUserCssRawSource) ? splitUserCssLayerBlocks(cleanedUserCssRawSource).rest : cleanedUserCssRawSource, {
6223
8195
  generatorTarget: generated.target,
6224
8196
  generatorStyleOptions,
6225
8197
  cssUserHandlerOptions,
@@ -6284,7 +8256,8 @@ async function generateCssByGenerator(options) {
6284
8256
  css = await appendLegacyContainerCompatCss(css, generatedUserCssRawSource, file, runtime, configuredContainerCompat, generated.target, styleHandler, cssHandlerOptions, generatorStyleOptions);
6285
8257
  }
6286
8258
  if (generated.target === "weapp" && hasDistinctUserRawSource && !hasGeneratedCss && !hasGeneratedMarkers && !hasTailwindApplyDirective(generatedUserCssRawSource)) {
6287
- const userCss = await transformGeneratorUserCss(generatedUserCssRawSource, {
8259
+ const distinctUserCssRawSource = restoredDistinctUserLayerCss ? distinctUserLayerParts?.rest ?? generatedUserCssRawSource : generatedUserCssRawSource;
8260
+ const userCss = await transformGeneratorUserCss(distinctUserCssRawSource, {
6288
8261
  generatorTarget: generated.target,
6289
8262
  generatorStyleOptions,
6290
8263
  cssUserHandlerOptions,
@@ -6292,7 +8265,7 @@ async function generateCssByGenerator(options) {
6292
8265
  importFallback: generatorOptions.importFallback,
6293
8266
  processed: userRawSourceProcessed
6294
8267
  });
6295
- const missingUserCss = isCssAlreadyRepresentedByMarkers(css, generatedUserCssRawSource) ? (0, _weapp_tailwindcss_postcss.filterExistingCssRules)(css, userCss) : userCss;
8268
+ const missingUserCss = isCssAlreadyRepresentedByMarkers(css, distinctUserCssRawSource) ? (0, _weapp_tailwindcss_postcss.filterExistingCssRules)(css, userCss) : userCss;
6296
8269
  css = createCssSourceOrderAppend$1(css, missingUserCss);
6297
8270
  }
6298
8271
  const finalCss = finalizeGeneratorCss(css, generated.target, {
@@ -7350,10 +9323,66 @@ const SCRIPT_SOURCE_CANDIDATE_EXTENSIONS = /* @__PURE__ */ new Set([
7350
9323
  "mts",
7351
9324
  "cts"
7352
9325
  ]);
9326
+ const TEMPLATE_SOURCE_CANDIDATE_EXTENSIONS = /* @__PURE__ */ new Set([
9327
+ "html",
9328
+ "wxml",
9329
+ "axml",
9330
+ "jxml",
9331
+ "ksml",
9332
+ "ttml",
9333
+ "qml",
9334
+ "tyml",
9335
+ "xhsml",
9336
+ "swan",
9337
+ "vue",
9338
+ "uvue",
9339
+ "nvue",
9340
+ "mpx"
9341
+ ]);
7353
9342
  async function extractCandidatesFromSource(source, extension, options = {}) {
7354
9343
  const candidates = options.extractor ? new Set(await options.extractor(source, extension)) : new Set(await (0, _tailwindcss_mangle_engine.extractSourceCandidates)(source, extension, { ...options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues } }));
7355
9344
  const scriptCandidates = await extractScriptStringCandidates(source, extension, options);
7356
9345
  for (const candidate of scriptCandidates) candidates.add(candidate);
9346
+ const templateAttributeCandidates = await extractTemplateAttributeCandidates(source, extension, options);
9347
+ for (const candidate of templateAttributeCandidates) candidates.add(candidate);
9348
+ return candidates;
9349
+ }
9350
+ function isDefaultTemplateAttribute(name) {
9351
+ if (name === "class" || name === "hover-class" || name === "virtualhostclass") return true;
9352
+ const lowerName = name.toLowerCase();
9353
+ return lowerName === "class" || lowerName === "hover-class" || lowerName === "virtualhostclass";
9354
+ }
9355
+ async function extractCandidateTokensFromTemplateAttributeValue(value, options) {
9356
+ return options.extractor ? await options.extractor(value, "html") : await (0, _tailwindcss_mangle_engine.extractSourceCandidates)(value, "html", { ...options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues } });
9357
+ }
9358
+ async function extractTemplateAttributeCandidates(source, extension, options) {
9359
+ if (!TEMPLATE_SOURCE_CANDIDATE_EXTENSIONS.has(extension)) return [];
9360
+ if (!options.customAttributesEntities?.length) return [];
9361
+ const candidates = /* @__PURE__ */ new Set();
9362
+ const matchCustomAttribute = createAttributeMatcher(options.customAttributesEntities);
9363
+ const defaultTemplateHandlerEnabled = !options.disabledDefaultTemplateHandler;
9364
+ let tag = "";
9365
+ const tasks = [];
9366
+ const parser = new Parser({
9367
+ onopentagname(name) {
9368
+ tag = name;
9369
+ },
9370
+ onattribute(name, value) {
9371
+ if (!value) return;
9372
+ const shouldHandleDefault = defaultTemplateHandlerEnabled && isDefaultTemplateAttribute(name);
9373
+ const shouldHandleCustom = matchCustomAttribute?.(tag, name) ?? false;
9374
+ if (!shouldHandleDefault && !shouldHandleCustom) return;
9375
+ tasks.push((async () => {
9376
+ for (const candidate of await extractCandidateTokensFromTemplateAttributeValue(value, options)) candidates.add(candidate);
9377
+ })());
9378
+ },
9379
+ onclosetag() {
9380
+ tag = "";
9381
+ }
9382
+ }, { xmlMode: true });
9383
+ parser.write(source);
9384
+ parser.end();
9385
+ await Promise.all(tasks);
7357
9386
  return candidates;
7358
9387
  }
7359
9388
  async function extractScriptStringCandidates(source, extension, options) {
@@ -7503,8 +9532,21 @@ function resolveSourceCandidateExtension(id) {
7503
9532
  const normalized = cleanUrl(id);
7504
9533
  return /\.([^.\\/]+)$/.exec(normalized)?.[1] ?? "html";
7505
9534
  }
7506
- function createSourceCandidateContentCacheKey(extension, source, bareArbitraryValues, extractor) {
7507
- return `${extension}\0${JSON.stringify(bareArbitraryValues ?? false)}\0${extractor ? "custom" : "default"}\0${(0, _weapp_tailwindcss_shared_node.md5)(source)}`;
9535
+ function createSourceCandidateContentCacheKey(extension, source, bareArbitraryValues, customAttributesEntities, disabledDefaultTemplateHandler, extractor) {
9536
+ return [
9537
+ extension,
9538
+ JSON.stringify(bareArbitraryValues ?? false),
9539
+ createCustomAttributesCacheSignature(customAttributesEntities),
9540
+ disabledDefaultTemplateHandler === true ? "default-template:off" : "default-template:on",
9541
+ extractor ? "custom" : "default",
9542
+ (0, _weapp_tailwindcss_shared_node.md5)(source)
9543
+ ].join("\0");
9544
+ }
9545
+ function createCustomAttributesCacheSignature(customAttributesEntities) {
9546
+ return JSON.stringify((customAttributesEntities ?? []).map(([selector, props]) => [stringifyCustomAttributeToken(selector), Array.isArray(props) ? props.map(stringifyCustomAttributeToken) : stringifyCustomAttributeToken(props)]));
9547
+ }
9548
+ function stringifyCustomAttributeToken(token) {
9549
+ return typeof token === "string" ? `s:${token}` : `r:${token.source}/${token.flags}`;
7508
9550
  }
7509
9551
  async function extractCandidates(source, extension, options) {
7510
9552
  return extractCandidatesFromSource(source, extension, options);
@@ -7551,7 +9593,7 @@ function createSourceCandidateStore(options = {}) {
7551
9593
  const normalizedId = cleanUrl(id);
7552
9594
  scanSourceById.set(normalizedId, source);
7553
9595
  const extension = resolveSourceCandidateExtension(normalizedId);
7554
- const contentCacheKey = createSourceCandidateContentCacheKey(extension, source, options.bareArbitraryValues, options.extractor);
9596
+ const contentCacheKey = createSourceCandidateContentCacheKey(extension, source, options.bareArbitraryValues, options.customAttributesEntities, options.disabledDefaultTemplateHandler, options.extractor);
7555
9597
  const cachedCandidates = sourceCandidateContentCache.get(contentCacheKey);
7556
9598
  if (cachedCandidates) {
7557
9599
  replaceScanLayer(normalizedId, new Set(cachedCandidates));
@@ -7564,7 +9606,7 @@ function createSourceCandidateStore(options = {}) {
7564
9606
  async function syncCss(id, source) {
7565
9607
  const normalizedId = cleanUrl(id);
7566
9608
  cssSourceById.set(normalizedId, source);
7567
- const contentCacheKey = createSourceCandidateContentCacheKey("css", source, options.bareArbitraryValues, options.extractor);
9609
+ const contentCacheKey = createSourceCandidateContentCacheKey("css", source, options.bareArbitraryValues, options.customAttributesEntities, options.disabledDefaultTemplateHandler, options.extractor);
7568
9610
  const cachedCandidates = sourceCandidateContentCache.get(contentCacheKey);
7569
9611
  if (cachedCandidates) {
7570
9612
  replaceCssLayer(normalizedId, new Set(cachedCandidates));
@@ -7578,7 +9620,7 @@ function createSourceCandidateStore(options = {}) {
7578
9620
  const normalizedId = cleanUrl(id);
7579
9621
  transformSourceById.set(normalizedId, source);
7580
9622
  const extension = resolveSourceCandidateExtension(normalizedId);
7581
- const contentCacheKey = createSourceCandidateContentCacheKey(extension, source, options.bareArbitraryValues, options.extractor);
9623
+ const contentCacheKey = createSourceCandidateContentCacheKey(extension, source, options.bareArbitraryValues, options.customAttributesEntities, options.disabledDefaultTemplateHandler, options.extractor);
7582
9624
  const cachedCandidates = sourceCandidateContentCache.get(contentCacheKey);
7583
9625
  const extractedCandidates = cachedCandidates ? new Set(cachedCandidates) : await extractCandidates(source, extension, options);
7584
9626
  if (!cachedCandidates) sourceCandidateContentCache.set(contentCacheKey, [...extractedCandidates]);
@@ -8086,7 +10128,11 @@ async function resolveWebpackLoaderSourceCandidates(source, loaderContext, optio
8086
10128
  const file = loaderContext.resourcePath;
8087
10129
  const resolved = await resolveTailwindV4EntriesFromCssCached(source, node_path.default.dirname(file));
8088
10130
  if (!resolved) return;
8089
- const collector = createSourceCandidateStore({ bareArbitraryValues: compilerOptions.arbitraryValues?.bareArbitraryValues });
10131
+ const collector = createSourceCandidateStore({
10132
+ bareArbitraryValues: compilerOptions.arbitraryValues?.bareArbitraryValues,
10133
+ customAttributesEntities: compilerOptions.customAttributesEntities,
10134
+ disabledDefaultTemplateHandler: compilerOptions.disabledDefaultTemplateHandler
10135
+ });
8090
10136
  collector.syncInline(resolved.inlineCandidates);
8091
10137
  const outDir = loaderContext.rootContext ? node_path.default.resolve(loaderContext.rootContext, "dist") : void 0;
8092
10138
  const scanFiles = await resolveSourceCandidateScanFiles({