ember-repl 6.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +2 -404
  3. package/config/.try.mjs +87 -0
  4. package/config/addon-main.cjs +7 -0
  5. package/config/attw.json +7 -0
  6. package/config/babel.publish.config.cjs +29 -0
  7. package/config/ember-cli-update.json +21 -0
  8. package/config/rollup.config.mjs +44 -0
  9. package/config/testem.cjs +35 -0
  10. package/config/tsconfig.publish.json +18 -0
  11. package/config/vite.config.mjs +36 -0
  12. package/declarations/compile/Compiled.d.ts +7 -0
  13. package/declarations/compile/Compiled.d.ts.map +1 -0
  14. package/declarations/compile/compile.d.ts +17 -0
  15. package/declarations/compile/compile.d.ts.map +1 -0
  16. package/declarations/compile/state.d.ts +43 -0
  17. package/declarations/compile/state.d.ts.map +1 -0
  18. package/declarations/compile/types.d.ts +5 -12
  19. package/declarations/compile/types.d.ts.map +1 -1
  20. package/declarations/index.d.ts +6 -2
  21. package/declarations/index.d.ts.map +1 -1
  22. package/declarations/services/compiler.d.ts +94 -0
  23. package/declarations/services/compiler.d.ts.map +1 -0
  24. package/declarations/services/known-modules.d.ts +7 -0
  25. package/declarations/services/known-modules.d.ts.map +1 -0
  26. package/declarations/setup.d.ts +7 -0
  27. package/declarations/setup.d.ts.map +1 -0
  28. package/declarations/test-support.d.ts +20 -0
  29. package/declarations/test-support.d.ts.map +1 -0
  30. package/dist/_commonjsHelpers-BAGoDD49.js +37 -0
  31. package/dist/_commonjsHelpers-BAGoDD49.js.map +1 -0
  32. package/dist/babel-8wMrbxkT.js +110427 -0
  33. package/dist/babel-8wMrbxkT.js.map +1 -0
  34. package/dist/blank-line-Bzg2Qt4K.js +482 -0
  35. package/dist/blank-line-Bzg2Qt4K.js.map +1 -0
  36. package/dist/compile/Compiled.js +26 -0
  37. package/dist/compile/Compiled.js.map +1 -0
  38. package/dist/compile/compile.js +62 -0
  39. package/dist/compile/compile.js.map +1 -0
  40. package/dist/compile/state.js +75 -0
  41. package/dist/compile/state.js.map +1 -0
  42. package/dist/compile/utils.js +213 -2
  43. package/dist/compile/utils.js.map +1 -1
  44. package/dist/default-CoqAuVeH.js +4 -0
  45. package/dist/default-CoqAuVeH.js.map +1 -0
  46. package/dist/index-BTx1k6gT.js +323 -0
  47. package/dist/index-BTx1k6gT.js.map +1 -0
  48. package/dist/index-Bxzjtr16.js +87 -0
  49. package/dist/index-Bxzjtr16.js.map +1 -0
  50. package/dist/index-C371bO_b.js +1553 -0
  51. package/dist/index-C371bO_b.js.map +1 -0
  52. package/dist/index-C4AyeeIa.js +5721 -0
  53. package/dist/index-C4AyeeIa.js.map +1 -0
  54. package/dist/index-C8S2G0FH.js +1953 -0
  55. package/dist/index-C8S2G0FH.js.map +1 -0
  56. package/dist/index-CCcIVEUK.js +409 -0
  57. package/dist/index-CCcIVEUK.js.map +1 -0
  58. package/dist/index-CDSIcg03.js +9070 -0
  59. package/dist/index-CDSIcg03.js.map +1 -0
  60. package/dist/index-D8szzCn3.js +2 -0
  61. package/dist/index-D8szzCn3.js.map +1 -0
  62. package/dist/index-DBBNT106.js +2644 -0
  63. package/dist/index-DBBNT106.js.map +1 -0
  64. package/dist/index-DP_Su7Zc.js +362 -0
  65. package/dist/index-DP_Su7Zc.js.map +1 -0
  66. package/dist/index-DejgrVqh.js +11299 -0
  67. package/dist/index-DejgrVqh.js.map +1 -0
  68. package/dist/index-Dr5iYoKt.js +1551 -0
  69. package/dist/index-Dr5iYoKt.js.map +1 -0
  70. package/dist/index-DxolpiGq.js +3336 -0
  71. package/dist/index-DxolpiGq.js.map +1 -0
  72. package/dist/index-ZyJlPFQY.js +249 -0
  73. package/dist/index-ZyJlPFQY.js.map +1 -0
  74. package/dist/index-k6CfLgeq.js +26 -0
  75. package/dist/index-k6CfLgeq.js.map +1 -0
  76. package/dist/index.js +4 -1
  77. package/dist/index.js.map +1 -1
  78. package/dist/services/compiler.js +329 -0
  79. package/dist/services/compiler.js.map +1 -0
  80. package/dist/services/known-modules.js +123 -0
  81. package/dist/services/known-modules.js.map +1 -0
  82. package/dist/setup.js +15 -0
  83. package/dist/setup.js.map +1 -0
  84. package/dist/test-support.js +33 -0
  85. package/dist/test-support.js.map +1 -0
  86. package/package.json +117 -138
  87. package/src/compile/Compiled.ts +45 -0
  88. package/src/compile/compile.ts +89 -0
  89. package/src/compile/state.ts +88 -0
  90. package/src/compile/types.ts +14 -13
  91. package/src/index.ts +6 -2
  92. package/src/services/compiler.ts +401 -0
  93. package/src/services/known-modules.ts +130 -0
  94. package/src/setup.ts +26 -0
  95. package/src/test-support.ts +64 -0
  96. package/addon-main.cjs +0 -5
  97. package/declarations/__PRIVATE__.d.ts +0 -2
  98. package/declarations/__PRIVATE__.d.ts.map +0 -1
  99. package/declarations/compile/formats/gjs/babel.d.ts +0 -7
  100. package/declarations/compile/formats/gjs/babel.d.ts.map +0 -1
  101. package/declarations/compile/formats/gjs/eval.d.ts +0 -8
  102. package/declarations/compile/formats/gjs/eval.d.ts.map +0 -1
  103. package/declarations/compile/formats/gjs/index.d.ts +0 -24
  104. package/declarations/compile/formats/gjs/index.d.ts.map +0 -1
  105. package/declarations/compile/formats/gjs/known-modules.d.ts +0 -48
  106. package/declarations/compile/formats/gjs/known-modules.d.ts.map +0 -1
  107. package/declarations/compile/formats/hbs.d.ts +0 -17
  108. package/declarations/compile/formats/hbs.d.ts.map +0 -1
  109. package/declarations/compile/formats/markdown.d.ts +0 -22
  110. package/declarations/compile/formats/markdown.d.ts.map +0 -1
  111. package/declarations/compile/formats.d.ts +0 -17
  112. package/declarations/compile/formats.d.ts.map +0 -1
  113. package/declarations/compile/index.d.ts +0 -80
  114. package/declarations/compile/index.d.ts.map +0 -1
  115. package/declarations/test-support/index.d.ts +0 -2
  116. package/declarations/test-support/index.d.ts.map +0 -1
  117. package/dist/__PRIVATE__.js +0 -2
  118. package/dist/__PRIVATE__.js.map +0 -1
  119. package/dist/compile/formats/gjs/babel.js +0 -2
  120. package/dist/compile/formats/gjs/babel.js.map +0 -1
  121. package/dist/compile/formats/gjs/eval.js +0 -19
  122. package/dist/compile/formats/gjs/eval.js.map +0 -1
  123. package/dist/compile/formats/gjs/index.js +0 -122
  124. package/dist/compile/formats/gjs/index.js.map +0 -1
  125. package/dist/compile/formats/gjs/known-modules.js +0 -52
  126. package/dist/compile/formats/gjs/known-modules.js.map +0 -1
  127. package/dist/compile/formats/hbs.js +0 -93
  128. package/dist/compile/formats/hbs.js.map +0 -1
  129. package/dist/compile/formats/markdown.js +0 -266
  130. package/dist/compile/formats/markdown.js.map +0 -1
  131. package/dist/compile/formats.js +0 -173
  132. package/dist/compile/formats.js.map +0 -1
  133. package/dist/compile/index.js +0 -113
  134. package/dist/compile/index.js.map +0 -1
  135. package/dist/test-support/index.js +0 -8
  136. package/dist/test-support/index.js.map +0 -1
  137. package/src/__PRIVATE__.ts +0 -1
  138. package/src/compile/formats/gjs/babel.ts +0 -7
  139. package/src/compile/formats/gjs/eval.ts +0 -29
  140. package/src/compile/formats/gjs/index.ts +0 -153
  141. package/src/compile/formats/gjs/known-modules.ts +0 -49
  142. package/src/compile/formats/hbs.ts +0 -100
  143. package/src/compile/formats/markdown.ts +0 -345
  144. package/src/compile/formats.ts +0 -178
  145. package/src/compile/index.ts +0 -219
  146. package/src/test-support/index.ts +0 -5
@@ -0,0 +1,1553 @@
1
+ import { s as svg, f as find, b as stringify, c as stringify$1, z as zwitch, h as html$2, d as htmlVoidElements } from './index-Dr5iYoKt.js';
2
+ import { c as ccount } from './index-k6CfLgeq.js';
3
+
4
+ /**
5
+ * @typedef CoreOptions
6
+ * @property {ReadonlyArray<string>} [subset=[]]
7
+ * Whether to only escape the given subset of characters.
8
+ * @property {boolean} [escapeOnly=false]
9
+ * Whether to only escape possibly dangerous characters.
10
+ * Those characters are `"`, `&`, `'`, `<`, `>`, and `` ` ``.
11
+ *
12
+ * @typedef FormatOptions
13
+ * @property {(code: number, next: number, options: CoreWithFormatOptions) => string} format
14
+ * Format strategy.
15
+ *
16
+ * @typedef {CoreOptions & FormatOptions & import('./util/format-smart.js').FormatSmartOptions} CoreWithFormatOptions
17
+ */
18
+
19
+ const defaultSubsetRegex = /["&'<>`]/g;
20
+ const surrogatePairsRegex = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
21
+ const controlCharactersRegex =
22
+ // eslint-disable-next-line no-control-regex, unicorn/no-hex-escape
23
+ /[\x01-\t\v\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g;
24
+ const regexEscapeRegex = /[|\\{}()[\]^$+*?.]/g;
25
+
26
+ /** @type {WeakMap<ReadonlyArray<string>, RegExp>} */
27
+ const subsetToRegexCache = new WeakMap();
28
+
29
+ /**
30
+ * Encode certain characters in `value`.
31
+ *
32
+ * @param {string} value
33
+ * @param {CoreWithFormatOptions} options
34
+ * @returns {string}
35
+ */
36
+ function core(value, options) {
37
+ value = value.replace(options.subset ? charactersToExpressionCached(options.subset) : defaultSubsetRegex, basic);
38
+ if (options.subset || options.escapeOnly) {
39
+ return value;
40
+ }
41
+ return value
42
+ // Surrogate pairs.
43
+ .replace(surrogatePairsRegex, surrogate)
44
+ // BMP control characters (C0 except for LF, CR, SP; DEL; and some more
45
+ // non-ASCII ones).
46
+ .replace(controlCharactersRegex, basic);
47
+
48
+ /**
49
+ * @param {string} pair
50
+ * @param {number} index
51
+ * @param {string} all
52
+ */
53
+ function surrogate(pair, index, all) {
54
+ return options.format((pair.charCodeAt(0) - 0xd800) * 0x400 + pair.charCodeAt(1) - 0xdc00 + 0x10000, all.charCodeAt(index + 2), options);
55
+ }
56
+
57
+ /**
58
+ * @param {string} character
59
+ * @param {number} index
60
+ * @param {string} all
61
+ */
62
+ function basic(character, index, all) {
63
+ return options.format(character.charCodeAt(0), all.charCodeAt(index + 1), options);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * A wrapper function that caches the result of `charactersToExpression` with a WeakMap.
69
+ * This can improve performance when tooling calls `charactersToExpression` repeatedly
70
+ * with the same subset.
71
+ *
72
+ * @param {ReadonlyArray<string>} subset
73
+ * @returns {RegExp}
74
+ */
75
+ function charactersToExpressionCached(subset) {
76
+ let cached = subsetToRegexCache.get(subset);
77
+ if (!cached) {
78
+ cached = charactersToExpression(subset);
79
+ subsetToRegexCache.set(subset, cached);
80
+ }
81
+ return cached;
82
+ }
83
+
84
+ /**
85
+ * @param {ReadonlyArray<string>} subset
86
+ * @returns {RegExp}
87
+ */
88
+ function charactersToExpression(subset) {
89
+ /** @type {Array<string>} */
90
+ const groups = [];
91
+ let index = -1;
92
+ while (++index < subset.length) {
93
+ groups.push(subset[index].replace(regexEscapeRegex, '\\$&'));
94
+ }
95
+ return new RegExp('(?:' + groups.join('|') + ')', 'g');
96
+ }
97
+
98
+ const hexadecimalRegex = /[\dA-Fa-f]/;
99
+
100
+ /**
101
+ * Configurable ways to encode characters as hexadecimal references.
102
+ *
103
+ * @param {number} code
104
+ * @param {number} next
105
+ * @param {boolean|undefined} omit
106
+ * @returns {string}
107
+ */
108
+ function toHexadecimal(code, next, omit) {
109
+ const value = '&#x' + code.toString(16).toUpperCase();
110
+ return omit && next && !hexadecimalRegex.test(String.fromCharCode(next)) ? value : value + ';';
111
+ }
112
+
113
+ const decimalRegex = /\d/;
114
+
115
+ /**
116
+ * Configurable ways to encode characters as decimal references.
117
+ *
118
+ * @param {number} code
119
+ * @param {number} next
120
+ * @param {boolean|undefined} omit
121
+ * @returns {string}
122
+ */
123
+ function toDecimal(code, next, omit) {
124
+ const value = '&#' + String(code);
125
+ return omit && next && !decimalRegex.test(String.fromCharCode(next)) ? value : value + ';';
126
+ }
127
+
128
+ /**
129
+ * List of legacy HTML named character references that don’t need a trailing semicolon.
130
+ *
131
+ * @type {Array<string>}
132
+ */
133
+ const characterEntitiesLegacy = ['AElig', 'AMP', 'Aacute', 'Acirc', 'Agrave', 'Aring', 'Atilde', 'Auml', 'COPY', 'Ccedil', 'ETH', 'Eacute', 'Ecirc', 'Egrave', 'Euml', 'GT', 'Iacute', 'Icirc', 'Igrave', 'Iuml', 'LT', 'Ntilde', 'Oacute', 'Ocirc', 'Ograve', 'Oslash', 'Otilde', 'Ouml', 'QUOT', 'REG', 'THORN', 'Uacute', 'Ucirc', 'Ugrave', 'Uuml', 'Yacute', 'aacute', 'acirc', 'acute', 'aelig', 'agrave', 'amp', 'aring', 'atilde', 'auml', 'brvbar', 'ccedil', 'cedil', 'cent', 'copy', 'curren', 'deg', 'divide', 'eacute', 'ecirc', 'egrave', 'eth', 'euml', 'frac12', 'frac14', 'frac34', 'gt', 'iacute', 'icirc', 'iexcl', 'igrave', 'iquest', 'iuml', 'laquo', 'lt', 'macr', 'micro', 'middot', 'nbsp', 'not', 'ntilde', 'oacute', 'ocirc', 'ograve', 'ordf', 'ordm', 'oslash', 'otilde', 'ouml', 'para', 'plusmn', 'pound', 'quot', 'raquo', 'reg', 'sect', 'shy', 'sup1', 'sup2', 'sup3', 'szlig', 'thorn', 'times', 'uacute', 'ucirc', 'ugrave', 'uml', 'uuml', 'yacute', 'yen', 'yuml'];
134
+
135
+ /**
136
+ * Map of named character references from HTML 4.
137
+ *
138
+ * @type {Record<string, string>}
139
+ */
140
+ const characterEntitiesHtml4 = {
141
+ nbsp: ' ',
142
+ iexcl: '¡',
143
+ cent: '¢',
144
+ pound: '£',
145
+ curren: '¤',
146
+ yen: '¥',
147
+ brvbar: '¦',
148
+ sect: '§',
149
+ uml: '¨',
150
+ copy: '©',
151
+ ordf: 'ª',
152
+ laquo: '«',
153
+ not: '¬',
154
+ shy: '­',
155
+ reg: '®',
156
+ macr: '¯',
157
+ deg: '°',
158
+ plusmn: '±',
159
+ sup2: '²',
160
+ sup3: '³',
161
+ acute: '´',
162
+ micro: 'µ',
163
+ para: '¶',
164
+ middot: '·',
165
+ cedil: '¸',
166
+ sup1: '¹',
167
+ ordm: 'º',
168
+ raquo: '»',
169
+ frac14: '¼',
170
+ frac12: '½',
171
+ frac34: '¾',
172
+ iquest: '¿',
173
+ Agrave: 'À',
174
+ Aacute: 'Á',
175
+ Acirc: 'Â',
176
+ Atilde: 'Ã',
177
+ Auml: 'Ä',
178
+ Aring: 'Å',
179
+ AElig: 'Æ',
180
+ Ccedil: 'Ç',
181
+ Egrave: 'È',
182
+ Eacute: 'É',
183
+ Ecirc: 'Ê',
184
+ Euml: 'Ë',
185
+ Igrave: 'Ì',
186
+ Iacute: 'Í',
187
+ Icirc: 'Î',
188
+ Iuml: 'Ï',
189
+ ETH: 'Ð',
190
+ Ntilde: 'Ñ',
191
+ Ograve: 'Ò',
192
+ Oacute: 'Ó',
193
+ Ocirc: 'Ô',
194
+ Otilde: 'Õ',
195
+ Ouml: 'Ö',
196
+ times: '×',
197
+ Oslash: 'Ø',
198
+ Ugrave: 'Ù',
199
+ Uacute: 'Ú',
200
+ Ucirc: 'Û',
201
+ Uuml: 'Ü',
202
+ Yacute: 'Ý',
203
+ THORN: 'Þ',
204
+ szlig: 'ß',
205
+ agrave: 'à',
206
+ aacute: 'á',
207
+ acirc: 'â',
208
+ atilde: 'ã',
209
+ auml: 'ä',
210
+ aring: 'å',
211
+ aelig: 'æ',
212
+ ccedil: 'ç',
213
+ egrave: 'è',
214
+ eacute: 'é',
215
+ ecirc: 'ê',
216
+ euml: 'ë',
217
+ igrave: 'ì',
218
+ iacute: 'í',
219
+ icirc: 'î',
220
+ iuml: 'ï',
221
+ eth: 'ð',
222
+ ntilde: 'ñ',
223
+ ograve: 'ò',
224
+ oacute: 'ó',
225
+ ocirc: 'ô',
226
+ otilde: 'õ',
227
+ ouml: 'ö',
228
+ divide: '÷',
229
+ oslash: 'ø',
230
+ ugrave: 'ù',
231
+ uacute: 'ú',
232
+ ucirc: 'û',
233
+ uuml: 'ü',
234
+ yacute: 'ý',
235
+ thorn: 'þ',
236
+ yuml: 'ÿ',
237
+ fnof: 'ƒ',
238
+ Alpha: 'Α',
239
+ Beta: 'Β',
240
+ Gamma: 'Γ',
241
+ Delta: 'Δ',
242
+ Epsilon: 'Ε',
243
+ Zeta: 'Ζ',
244
+ Eta: 'Η',
245
+ Theta: 'Θ',
246
+ Iota: 'Ι',
247
+ Kappa: 'Κ',
248
+ Lambda: 'Λ',
249
+ Mu: 'Μ',
250
+ Nu: 'Ν',
251
+ Xi: 'Ξ',
252
+ Omicron: 'Ο',
253
+ Pi: 'Π',
254
+ Rho: 'Ρ',
255
+ Sigma: 'Σ',
256
+ Tau: 'Τ',
257
+ Upsilon: 'Υ',
258
+ Phi: 'Φ',
259
+ Chi: 'Χ',
260
+ Psi: 'Ψ',
261
+ Omega: 'Ω',
262
+ alpha: 'α',
263
+ beta: 'β',
264
+ gamma: 'γ',
265
+ delta: 'δ',
266
+ epsilon: 'ε',
267
+ zeta: 'ζ',
268
+ eta: 'η',
269
+ theta: 'θ',
270
+ iota: 'ι',
271
+ kappa: 'κ',
272
+ lambda: 'λ',
273
+ mu: 'μ',
274
+ nu: 'ν',
275
+ xi: 'ξ',
276
+ omicron: 'ο',
277
+ pi: 'π',
278
+ rho: 'ρ',
279
+ sigmaf: 'ς',
280
+ sigma: 'σ',
281
+ tau: 'τ',
282
+ upsilon: 'υ',
283
+ phi: 'φ',
284
+ chi: 'χ',
285
+ psi: 'ψ',
286
+ omega: 'ω',
287
+ thetasym: 'ϑ',
288
+ upsih: 'ϒ',
289
+ piv: 'ϖ',
290
+ bull: '•',
291
+ hellip: '…',
292
+ prime: '′',
293
+ Prime: '″',
294
+ oline: '‾',
295
+ frasl: '⁄',
296
+ weierp: '℘',
297
+ image: 'ℑ',
298
+ real: 'ℜ',
299
+ trade: '™',
300
+ alefsym: 'ℵ',
301
+ larr: '←',
302
+ uarr: '↑',
303
+ rarr: '→',
304
+ darr: '↓',
305
+ harr: '↔',
306
+ crarr: '↵',
307
+ lArr: '⇐',
308
+ uArr: '⇑',
309
+ rArr: '⇒',
310
+ dArr: '⇓',
311
+ hArr: '⇔',
312
+ forall: '∀',
313
+ part: '∂',
314
+ exist: '∃',
315
+ empty: '∅',
316
+ nabla: '∇',
317
+ isin: '∈',
318
+ notin: '∉',
319
+ ni: '∋',
320
+ prod: '∏',
321
+ sum: '∑',
322
+ minus: '−',
323
+ lowast: '∗',
324
+ radic: '√',
325
+ prop: '∝',
326
+ infin: '∞',
327
+ ang: '∠',
328
+ and: '∧',
329
+ or: '∨',
330
+ cap: '∩',
331
+ cup: '∪',
332
+ int: '∫',
333
+ there4: '∴',
334
+ sim: '∼',
335
+ cong: '≅',
336
+ asymp: '≈',
337
+ ne: '≠',
338
+ equiv: '≡',
339
+ le: '≤',
340
+ ge: '≥',
341
+ sub: '⊂',
342
+ sup: '⊃',
343
+ nsub: '⊄',
344
+ sube: '⊆',
345
+ supe: '⊇',
346
+ oplus: '⊕',
347
+ otimes: '⊗',
348
+ perp: '⊥',
349
+ sdot: '⋅',
350
+ lceil: '⌈',
351
+ rceil: '⌉',
352
+ lfloor: '⌊',
353
+ rfloor: '⌋',
354
+ lang: '〈',
355
+ rang: '〉',
356
+ loz: '◊',
357
+ spades: '♠',
358
+ clubs: '♣',
359
+ hearts: '♥',
360
+ diams: '♦',
361
+ quot: '"',
362
+ amp: '&',
363
+ lt: '<',
364
+ gt: '>',
365
+ OElig: 'Œ',
366
+ oelig: 'œ',
367
+ Scaron: 'Š',
368
+ scaron: 'š',
369
+ Yuml: 'Ÿ',
370
+ circ: 'ˆ',
371
+ tilde: '˜',
372
+ ensp: ' ',
373
+ emsp: ' ',
374
+ thinsp: ' ',
375
+ zwnj: '‌',
376
+ zwj: '‍',
377
+ lrm: '‎',
378
+ rlm: '‏',
379
+ ndash: '–',
380
+ mdash: '—',
381
+ lsquo: '‘',
382
+ rsquo: '’',
383
+ sbquo: '‚',
384
+ ldquo: '“',
385
+ rdquo: '”',
386
+ bdquo: '„',
387
+ dagger: '†',
388
+ Dagger: '‡',
389
+ permil: '‰',
390
+ lsaquo: '‹',
391
+ rsaquo: '›',
392
+ euro: '€'
393
+ };
394
+
395
+ /**
396
+ * List of legacy (that don’t need a trailing `;`) named references which could,
397
+ * depending on what follows them, turn into a different meaning
398
+ *
399
+ * @type {Array<string>}
400
+ */
401
+ const dangerous = ['cent', 'copy', 'divide', 'gt', 'lt', 'not', 'para', 'times'];
402
+
403
+ const own$1 = {}.hasOwnProperty;
404
+
405
+ /**
406
+ * `characterEntitiesHtml4` but inverted.
407
+ *
408
+ * @type {Record<string, string>}
409
+ */
410
+ const characters = {};
411
+
412
+ /** @type {string} */
413
+ let key;
414
+ for (key in characterEntitiesHtml4) {
415
+ if (own$1.call(characterEntitiesHtml4, key)) {
416
+ characters[characterEntitiesHtml4[key]] = key;
417
+ }
418
+ }
419
+ const notAlphanumericRegex = /[^\dA-Za-z]/;
420
+
421
+ /**
422
+ * Configurable ways to encode characters as named references.
423
+ *
424
+ * @param {number} code
425
+ * @param {number} next
426
+ * @param {boolean|undefined} omit
427
+ * @param {boolean|undefined} attribute
428
+ * @returns {string}
429
+ */
430
+ function toNamed(code, next, omit, attribute) {
431
+ const character = String.fromCharCode(code);
432
+ if (own$1.call(characters, character)) {
433
+ const name = characters[character];
434
+ const value = '&' + name;
435
+ if (omit && characterEntitiesLegacy.includes(name) && !dangerous.includes(name) && (!attribute || next && next !== 61 /* `=` */ && notAlphanumericRegex.test(String.fromCharCode(next)))) {
436
+ return value;
437
+ }
438
+ return value + ';';
439
+ }
440
+ return '';
441
+ }
442
+
443
+ /**
444
+ * @typedef FormatSmartOptions
445
+ * @property {boolean} [useNamedReferences=false]
446
+ * Prefer named character references (`&amp;`) where possible.
447
+ * @property {boolean} [useShortestReferences=false]
448
+ * Prefer the shortest possible reference, if that results in less bytes.
449
+ * **Note**: `useNamedReferences` can be omitted when using `useShortestReferences`.
450
+ * @property {boolean} [omitOptionalSemicolons=false]
451
+ * Whether to omit semicolons when possible.
452
+ * **Note**: This creates what HTML calls “parse errors” but is otherwise still valid HTML — don’t use this except when building a minifier.
453
+ * Omitting semicolons is possible for certain named and numeric references in some cases.
454
+ * @property {boolean} [attribute=false]
455
+ * Create character references which don’t fail in attributes.
456
+ * **Note**: `attribute` only applies when operating dangerously with
457
+ * `omitOptionalSemicolons: true`.
458
+ */
459
+
460
+
461
+ /**
462
+ * Configurable ways to encode a character yielding pretty or small results.
463
+ *
464
+ * @param {number} code
465
+ * @param {number} next
466
+ * @param {FormatSmartOptions} options
467
+ * @returns {string}
468
+ */
469
+ function formatSmart(code, next, options) {
470
+ let numeric = toHexadecimal(code, next, options.omitOptionalSemicolons);
471
+ /** @type {string|undefined} */
472
+ let named;
473
+ if (options.useNamedReferences || options.useShortestReferences) {
474
+ named = toNamed(code, next, options.omitOptionalSemicolons, options.attribute);
475
+ }
476
+
477
+ // Use the shortest numeric reference when requested.
478
+ // A simple algorithm would use decimal for all code points under 100, as
479
+ // those are shorter than hexadecimal:
480
+ //
481
+ // * `&#99;` vs `&#x63;` (decimal shorter)
482
+ // * `&#100;` vs `&#x64;` (equal)
483
+ //
484
+ // However, because we take `next` into consideration when `omit` is used,
485
+ // And it would be possible that decimals are shorter on bigger values as
486
+ // well if `next` is hexadecimal but not decimal, we instead compare both.
487
+ if ((options.useShortestReferences || !named) && options.useShortestReferences) {
488
+ const decimal = toDecimal(code, next, options.omitOptionalSemicolons);
489
+ if (decimal.length < numeric.length) {
490
+ numeric = decimal;
491
+ }
492
+ }
493
+ return named && (!options.useShortestReferences || named.length < numeric.length) ? named : numeric;
494
+ }
495
+
496
+ /**
497
+ * @typedef {import('./core.js').CoreOptions & import('./util/format-smart.js').FormatSmartOptions} Options
498
+ * @typedef {import('./core.js').CoreOptions} LightOptions
499
+ */
500
+
501
+
502
+ /**
503
+ * Encode special characters in `value`.
504
+ *
505
+ * @param {string} value
506
+ * Value to encode.
507
+ * @param {Options} [options]
508
+ * Configuration.
509
+ * @returns {string}
510
+ * Encoded value.
511
+ */
512
+ function stringifyEntities(value, options) {
513
+ return core(value, Object.assign({
514
+ format: formatSmart
515
+ }, options));
516
+ }
517
+
518
+ /**
519
+ * @import {Comment, Parents} from 'hast'
520
+ * @import {State} from '../index.js'
521
+ */
522
+
523
+ const htmlCommentRegex = /^>|^->|<!--|-->|--!>|<!-$/g;
524
+
525
+ // Declare arrays as variables so it can be cached by `stringifyEntities`
526
+ const bogusCommentEntitySubset = ['>'];
527
+ const commentEntitySubset = ['<', '>'];
528
+
529
+ /**
530
+ * Serialize a comment.
531
+ *
532
+ * @param {Comment} node
533
+ * Node to handle.
534
+ * @param {number | undefined} _1
535
+ * Index of `node` in `parent.
536
+ * @param {Parents | undefined} _2
537
+ * Parent of `node`.
538
+ * @param {State} state
539
+ * Info passed around about the current state.
540
+ * @returns {string}
541
+ * Serialized node.
542
+ */
543
+ function comment(node, _1, _2, state) {
544
+ // See: <https://html.spec.whatwg.org/multipage/syntax.html#comments>
545
+ return state.settings.bogusComments ? '<?' + stringifyEntities(node.value, Object.assign({}, state.settings.characterReferences, {
546
+ subset: bogusCommentEntitySubset
547
+ })) + '>' : '<!--' + node.value.replace(htmlCommentRegex, encode) + '-->';
548
+
549
+ /**
550
+ * @param {string} $0
551
+ */
552
+ function encode($0) {
553
+ return stringifyEntities($0, Object.assign({}, state.settings.characterReferences, {
554
+ subset: commentEntitySubset
555
+ }));
556
+ }
557
+ }
558
+
559
+ /**
560
+ * @import {Doctype, Parents} from 'hast'
561
+ * @import {State} from '../index.js'
562
+ */
563
+
564
+ /**
565
+ * Serialize a doctype.
566
+ *
567
+ * @param {Doctype} _1
568
+ * Node to handle.
569
+ * @param {number | undefined} _2
570
+ * Index of `node` in `parent.
571
+ * @param {Parents | undefined} _3
572
+ * Parent of `node`.
573
+ * @param {State} state
574
+ * Info passed around about the current state.
575
+ * @returns {string}
576
+ * Serialized node.
577
+ */
578
+ function doctype(_1, _2, _3, state) {
579
+ return '<!' + (state.settings.upperDoctype ? 'DOCTYPE' : 'doctype') + (state.settings.tightDoctype ? '' : ' ') + 'html>';
580
+ }
581
+
582
+ /**
583
+ * @typedef {import('hast').Nodes} Nodes
584
+ */
585
+
586
+ // HTML whitespace expression.
587
+ // See <https://infra.spec.whatwg.org/#ascii-whitespace>.
588
+ const re = /[ \t\n\f\r]/g;
589
+
590
+ /**
591
+ * Check if the given value is *inter-element whitespace*.
592
+ *
593
+ * @param {Nodes | string} thing
594
+ * Thing to check (`Node` or `string`).
595
+ * @returns {boolean}
596
+ * Whether the `value` is inter-element whitespace (`boolean`): consisting of
597
+ * zero or more of space, tab (`\t`), line feed (`\n`), carriage return
598
+ * (`\r`), or form feed (`\f`); if a node is passed it must be a `Text` node,
599
+ * whose `value` field is checked.
600
+ */
601
+ function whitespace(thing) {
602
+ return typeof thing === 'object' ? thing.type === 'text' ? empty(thing.value) : false : empty(thing);
603
+ }
604
+
605
+ /**
606
+ * @param {string} value
607
+ * @returns {boolean}
608
+ */
609
+ function empty(value) {
610
+ return value.replace(re, '') === '';
611
+ }
612
+
613
+ /**
614
+ * @import {Parents, RootContent} from 'hast'
615
+ */
616
+
617
+ const siblingAfter = siblings(1);
618
+ const siblingBefore = siblings(-1);
619
+
620
+ /** @type {Array<RootContent>} */
621
+ const emptyChildren$1 = [];
622
+
623
+ /**
624
+ * Factory to check siblings in a direction.
625
+ *
626
+ * @param {number} increment
627
+ */
628
+ function siblings(increment) {
629
+ return sibling;
630
+
631
+ /**
632
+ * Find applicable siblings in a direction.
633
+ *
634
+ * @template {Parents} Parent
635
+ * Parent type.
636
+ * @param {Parent | undefined} parent
637
+ * Parent.
638
+ * @param {number | undefined} index
639
+ * Index of child in `parent`.
640
+ * @param {boolean | undefined} [includeWhitespace=false]
641
+ * Whether to include whitespace (default: `false`).
642
+ * @returns {Parent extends {children: Array<infer Child>} ? Child | undefined : never}
643
+ * Child of parent.
644
+ */
645
+ function sibling(parent, index, includeWhitespace) {
646
+ const siblings = parent ? parent.children : emptyChildren$1;
647
+ let offset = (index || 0) + increment;
648
+ let next = siblings[offset];
649
+ if (!includeWhitespace) {
650
+ while (next && whitespace(next)) {
651
+ offset += increment;
652
+ next = siblings[offset];
653
+ }
654
+ }
655
+
656
+ // @ts-expect-error: it’s a correct child.
657
+ return next;
658
+ }
659
+ }
660
+
661
+ /**
662
+ * @import {Element, Parents} from 'hast'
663
+ */
664
+
665
+ /**
666
+ * @callback OmitHandle
667
+ * Check if a tag can be omitted.
668
+ * @param {Element} element
669
+ * Element to check.
670
+ * @param {number | undefined} index
671
+ * Index of element in parent.
672
+ * @param {Parents | undefined} parent
673
+ * Parent of element.
674
+ * @returns {boolean}
675
+ * Whether to omit a tag.
676
+ *
677
+ */
678
+
679
+ const own = {}.hasOwnProperty;
680
+
681
+ /**
682
+ * Factory to check if a given node can have a tag omitted.
683
+ *
684
+ * @param {Record<string, OmitHandle>} handlers
685
+ * Omission handlers, where each key is a tag name, and each value is the
686
+ * corresponding handler.
687
+ * @returns {OmitHandle}
688
+ * Whether to omit a tag of an element.
689
+ */
690
+ function omission(handlers) {
691
+ return omit;
692
+
693
+ /**
694
+ * Check if a given node can have a tag omitted.
695
+ *
696
+ * @type {OmitHandle}
697
+ */
698
+ function omit(node, index, parent) {
699
+ return own.call(handlers, node.tagName) && handlers[node.tagName](node, index, parent);
700
+ }
701
+ }
702
+
703
+ /**
704
+ * @import {Element, Parents} from 'hast'
705
+ */
706
+
707
+ const closing = omission({
708
+ body: body$1,
709
+ caption: headOrColgroupOrCaption,
710
+ colgroup: headOrColgroupOrCaption,
711
+ dd,
712
+ dt,
713
+ head: headOrColgroupOrCaption,
714
+ html: html$1,
715
+ li,
716
+ optgroup,
717
+ option,
718
+ p,
719
+ rp: rubyElement,
720
+ rt: rubyElement,
721
+ tbody: tbody$1,
722
+ td: cells,
723
+ tfoot,
724
+ th: cells,
725
+ thead,
726
+ tr
727
+ });
728
+
729
+ /**
730
+ * Macro for `</head>`, `</colgroup>`, and `</caption>`.
731
+ *
732
+ * @param {Element} _
733
+ * Element.
734
+ * @param {number | undefined} index
735
+ * Index of element in parent.
736
+ * @param {Parents | undefined} parent
737
+ * Parent of element.
738
+ * @returns {boolean}
739
+ * Whether the closing tag can be omitted.
740
+ */
741
+ function headOrColgroupOrCaption(_, index, parent) {
742
+ const next = siblingAfter(parent, index, true);
743
+ return !next || next.type !== 'comment' && !(next.type === 'text' && whitespace(next.value.charAt(0)));
744
+ }
745
+
746
+ /**
747
+ * Whether to omit `</html>`.
748
+ *
749
+ * @param {Element} _
750
+ * Element.
751
+ * @param {number | undefined} index
752
+ * Index of element in parent.
753
+ * @param {Parents | undefined} parent
754
+ * Parent of element.
755
+ * @returns {boolean}
756
+ * Whether the closing tag can be omitted.
757
+ */
758
+ function html$1(_, index, parent) {
759
+ const next = siblingAfter(parent, index);
760
+ return !next || next.type !== 'comment';
761
+ }
762
+
763
+ /**
764
+ * Whether to omit `</body>`.
765
+ *
766
+ * @param {Element} _
767
+ * Element.
768
+ * @param {number | undefined} index
769
+ * Index of element in parent.
770
+ * @param {Parents | undefined} parent
771
+ * Parent of element.
772
+ * @returns {boolean}
773
+ * Whether the closing tag can be omitted.
774
+ */
775
+ function body$1(_, index, parent) {
776
+ const next = siblingAfter(parent, index);
777
+ return !next || next.type !== 'comment';
778
+ }
779
+
780
+ /**
781
+ * Whether to omit `</p>`.
782
+ *
783
+ * @param {Element} _
784
+ * Element.
785
+ * @param {number | undefined} index
786
+ * Index of element in parent.
787
+ * @param {Parents | undefined} parent
788
+ * Parent of element.
789
+ * @returns {boolean}
790
+ * Whether the closing tag can be omitted.
791
+ */
792
+ function p(_, index, parent) {
793
+ const next = siblingAfter(parent, index);
794
+ return next ? next.type === 'element' && (next.tagName === 'address' || next.tagName === 'article' || next.tagName === 'aside' || next.tagName === 'blockquote' || next.tagName === 'details' || next.tagName === 'div' || next.tagName === 'dl' || next.tagName === 'fieldset' || next.tagName === 'figcaption' || next.tagName === 'figure' || next.tagName === 'footer' || next.tagName === 'form' || next.tagName === 'h1' || next.tagName === 'h2' || next.tagName === 'h3' || next.tagName === 'h4' || next.tagName === 'h5' || next.tagName === 'h6' || next.tagName === 'header' || next.tagName === 'hgroup' || next.tagName === 'hr' || next.tagName === 'main' || next.tagName === 'menu' || next.tagName === 'nav' || next.tagName === 'ol' || next.tagName === 'p' || next.tagName === 'pre' || next.tagName === 'section' || next.tagName === 'table' || next.tagName === 'ul') : !parent ||
795
+ // Confusing parent.
796
+ !(parent.type === 'element' && (parent.tagName === 'a' || parent.tagName === 'audio' || parent.tagName === 'del' || parent.tagName === 'ins' || parent.tagName === 'map' || parent.tagName === 'noscript' || parent.tagName === 'video'));
797
+ }
798
+
799
+ /**
800
+ * Whether to omit `</li>`.
801
+ *
802
+ * @param {Element} _
803
+ * Element.
804
+ * @param {number | undefined} index
805
+ * Index of element in parent.
806
+ * @param {Parents | undefined} parent
807
+ * Parent of element.
808
+ * @returns {boolean}
809
+ * Whether the closing tag can be omitted.
810
+ */
811
+ function li(_, index, parent) {
812
+ const next = siblingAfter(parent, index);
813
+ return !next || next.type === 'element' && next.tagName === 'li';
814
+ }
815
+
816
+ /**
817
+ * Whether to omit `</dt>`.
818
+ *
819
+ * @param {Element} _
820
+ * Element.
821
+ * @param {number | undefined} index
822
+ * Index of element in parent.
823
+ * @param {Parents | undefined} parent
824
+ * Parent of element.
825
+ * @returns {boolean}
826
+ * Whether the closing tag can be omitted.
827
+ */
828
+ function dt(_, index, parent) {
829
+ const next = siblingAfter(parent, index);
830
+ return Boolean(next && next.type === 'element' && (next.tagName === 'dt' || next.tagName === 'dd'));
831
+ }
832
+
833
+ /**
834
+ * Whether to omit `</dd>`.
835
+ *
836
+ * @param {Element} _
837
+ * Element.
838
+ * @param {number | undefined} index
839
+ * Index of element in parent.
840
+ * @param {Parents | undefined} parent
841
+ * Parent of element.
842
+ * @returns {boolean}
843
+ * Whether the closing tag can be omitted.
844
+ */
845
+ function dd(_, index, parent) {
846
+ const next = siblingAfter(parent, index);
847
+ return !next || next.type === 'element' && (next.tagName === 'dt' || next.tagName === 'dd');
848
+ }
849
+
850
+ /**
851
+ * Whether to omit `</rt>` or `</rp>`.
852
+ *
853
+ * @param {Element} _
854
+ * Element.
855
+ * @param {number | undefined} index
856
+ * Index of element in parent.
857
+ * @param {Parents | undefined} parent
858
+ * Parent of element.
859
+ * @returns {boolean}
860
+ * Whether the closing tag can be omitted.
861
+ */
862
+ function rubyElement(_, index, parent) {
863
+ const next = siblingAfter(parent, index);
864
+ return !next || next.type === 'element' && (next.tagName === 'rp' || next.tagName === 'rt');
865
+ }
866
+
867
+ /**
868
+ * Whether to omit `</optgroup>`.
869
+ *
870
+ * @param {Element} _
871
+ * Element.
872
+ * @param {number | undefined} index
873
+ * Index of element in parent.
874
+ * @param {Parents | undefined} parent
875
+ * Parent of element.
876
+ * @returns {boolean}
877
+ * Whether the closing tag can be omitted.
878
+ */
879
+ function optgroup(_, index, parent) {
880
+ const next = siblingAfter(parent, index);
881
+ return !next || next.type === 'element' && next.tagName === 'optgroup';
882
+ }
883
+
884
+ /**
885
+ * Whether to omit `</option>`.
886
+ *
887
+ * @param {Element} _
888
+ * Element.
889
+ * @param {number | undefined} index
890
+ * Index of element in parent.
891
+ * @param {Parents | undefined} parent
892
+ * Parent of element.
893
+ * @returns {boolean}
894
+ * Whether the closing tag can be omitted.
895
+ */
896
+ function option(_, index, parent) {
897
+ const next = siblingAfter(parent, index);
898
+ return !next || next.type === 'element' && (next.tagName === 'option' || next.tagName === 'optgroup');
899
+ }
900
+
901
+ /**
902
+ * Whether to omit `</thead>`.
903
+ *
904
+ * @param {Element} _
905
+ * Element.
906
+ * @param {number | undefined} index
907
+ * Index of element in parent.
908
+ * @param {Parents | undefined} parent
909
+ * Parent of element.
910
+ * @returns {boolean}
911
+ * Whether the closing tag can be omitted.
912
+ */
913
+ function thead(_, index, parent) {
914
+ const next = siblingAfter(parent, index);
915
+ return Boolean(next && next.type === 'element' && (next.tagName === 'tbody' || next.tagName === 'tfoot'));
916
+ }
917
+
918
+ /**
919
+ * Whether to omit `</tbody>`.
920
+ *
921
+ * @param {Element} _
922
+ * Element.
923
+ * @param {number | undefined} index
924
+ * Index of element in parent.
925
+ * @param {Parents | undefined} parent
926
+ * Parent of element.
927
+ * @returns {boolean}
928
+ * Whether the closing tag can be omitted.
929
+ */
930
+ function tbody$1(_, index, parent) {
931
+ const next = siblingAfter(parent, index);
932
+ return !next || next.type === 'element' && (next.tagName === 'tbody' || next.tagName === 'tfoot');
933
+ }
934
+
935
+ /**
936
+ * Whether to omit `</tfoot>`.
937
+ *
938
+ * @param {Element} _
939
+ * Element.
940
+ * @param {number | undefined} index
941
+ * Index of element in parent.
942
+ * @param {Parents | undefined} parent
943
+ * Parent of element.
944
+ * @returns {boolean}
945
+ * Whether the closing tag can be omitted.
946
+ */
947
+ function tfoot(_, index, parent) {
948
+ return !siblingAfter(parent, index);
949
+ }
950
+
951
+ /**
952
+ * Whether to omit `</tr>`.
953
+ *
954
+ * @param {Element} _
955
+ * Element.
956
+ * @param {number | undefined} index
957
+ * Index of element in parent.
958
+ * @param {Parents | undefined} parent
959
+ * Parent of element.
960
+ * @returns {boolean}
961
+ * Whether the closing tag can be omitted.
962
+ */
963
+ function tr(_, index, parent) {
964
+ const next = siblingAfter(parent, index);
965
+ return !next || next.type === 'element' && next.tagName === 'tr';
966
+ }
967
+
968
+ /**
969
+ * Whether to omit `</td>` or `</th>`.
970
+ *
971
+ * @param {Element} _
972
+ * Element.
973
+ * @param {number | undefined} index
974
+ * Index of element in parent.
975
+ * @param {Parents | undefined} parent
976
+ * Parent of element.
977
+ * @returns {boolean}
978
+ * Whether the closing tag can be omitted.
979
+ */
980
+ function cells(_, index, parent) {
981
+ const next = siblingAfter(parent, index);
982
+ return !next || next.type === 'element' && (next.tagName === 'td' || next.tagName === 'th');
983
+ }
984
+
985
+ /**
986
+ * @import {Element, Parents} from 'hast'
987
+ */
988
+
989
+ const opening = omission({
990
+ body,
991
+ colgroup,
992
+ head,
993
+ html,
994
+ tbody
995
+ });
996
+
997
+ /**
998
+ * Whether to omit `<html>`.
999
+ *
1000
+ * @param {Element} node
1001
+ * Element.
1002
+ * @returns {boolean}
1003
+ * Whether the opening tag can be omitted.
1004
+ */
1005
+ function html(node) {
1006
+ const head = siblingAfter(node, -1);
1007
+ return !head || head.type !== 'comment';
1008
+ }
1009
+
1010
+ /**
1011
+ * Whether to omit `<head>`.
1012
+ *
1013
+ * @param {Element} node
1014
+ * Element.
1015
+ * @returns {boolean}
1016
+ * Whether the opening tag can be omitted.
1017
+ */
1018
+ function head(node) {
1019
+ /** @type {Set<string>} */
1020
+ const seen = new Set();
1021
+
1022
+ // Whether `srcdoc` or not,
1023
+ // make sure the content model at least doesn’t have too many `base`s/`title`s.
1024
+ for (const child of node.children) {
1025
+ if (child.type === 'element' && (child.tagName === 'base' || child.tagName === 'title')) {
1026
+ if (seen.has(child.tagName)) return false;
1027
+ seen.add(child.tagName);
1028
+ }
1029
+ }
1030
+
1031
+ // “May be omitted if the element is empty,
1032
+ // or if the first thing inside the head element is an element.”
1033
+ const child = node.children[0];
1034
+ return !child || child.type === 'element';
1035
+ }
1036
+
1037
+ /**
1038
+ * Whether to omit `<body>`.
1039
+ *
1040
+ * @param {Element} node
1041
+ * Element.
1042
+ * @returns {boolean}
1043
+ * Whether the opening tag can be omitted.
1044
+ */
1045
+ function body(node) {
1046
+ const head = siblingAfter(node, -1, true);
1047
+ return !head || head.type !== 'comment' && !(head.type === 'text' && whitespace(head.value.charAt(0))) && !(head.type === 'element' && (head.tagName === 'meta' || head.tagName === 'link' || head.tagName === 'script' || head.tagName === 'style' || head.tagName === 'template'));
1048
+ }
1049
+
1050
+ /**
1051
+ * Whether to omit `<colgroup>`.
1052
+ * The spec describes some logic for the opening tag, but it’s easier to
1053
+ * implement in the closing tag, to the same effect, so we handle it there
1054
+ * instead.
1055
+ *
1056
+ * @param {Element} node
1057
+ * Element.
1058
+ * @param {number | undefined} index
1059
+ * Index of element in parent.
1060
+ * @param {Parents | undefined} parent
1061
+ * Parent of element.
1062
+ * @returns {boolean}
1063
+ * Whether the opening tag can be omitted.
1064
+ */
1065
+ function colgroup(node, index, parent) {
1066
+ const previous = siblingBefore(parent, index);
1067
+ const head = siblingAfter(node, -1, true);
1068
+
1069
+ // Previous colgroup was already omitted.
1070
+ if (parent && previous && previous.type === 'element' && previous.tagName === 'colgroup' && closing(previous, parent.children.indexOf(previous), parent)) {
1071
+ return false;
1072
+ }
1073
+ return Boolean(head && head.type === 'element' && head.tagName === 'col');
1074
+ }
1075
+
1076
+ /**
1077
+ * Whether to omit `<tbody>`.
1078
+ *
1079
+ * @param {Element} node
1080
+ * Element.
1081
+ * @param {number | undefined} index
1082
+ * Index of element in parent.
1083
+ * @param {Parents | undefined} parent
1084
+ * Parent of element.
1085
+ * @returns {boolean}
1086
+ * Whether the opening tag can be omitted.
1087
+ */
1088
+ function tbody(node, index, parent) {
1089
+ const previous = siblingBefore(parent, index);
1090
+ const head = siblingAfter(node, -1);
1091
+
1092
+ // Previous table section was already omitted.
1093
+ if (parent && previous && previous.type === 'element' && (previous.tagName === 'thead' || previous.tagName === 'tbody') && closing(previous, parent.children.indexOf(previous), parent)) {
1094
+ return false;
1095
+ }
1096
+ return Boolean(head && head.type === 'element' && head.tagName === 'tr');
1097
+ }
1098
+
1099
+ /**
1100
+ * @import {Element, Parents, Properties} from 'hast'
1101
+ * @import {State} from '../index.js'
1102
+ */
1103
+
1104
+
1105
+ /**
1106
+ * Maps of subsets.
1107
+ *
1108
+ * Each value is a matrix of tuples.
1109
+ * The value at `0` causes parse errors, the value at `1` is valid.
1110
+ * Of both, the value at `0` is unsafe, and the value at `1` is safe.
1111
+ *
1112
+ * @type {Record<'double' | 'name' | 'single' | 'unquoted', Array<[Array<string>, Array<string>]>>}
1113
+ */
1114
+ const constants = {
1115
+ // See: <https://html.spec.whatwg.org/#attribute-name-state>.
1116
+ name: [['\t\n\f\r &/=>'.split(''), '\t\n\f\r "&\'/=>`'.split('')], ['\0\t\n\f\r "&\'/<=>'.split(''), '\0\t\n\f\r "&\'/<=>`'.split('')]],
1117
+ // See: <https://html.spec.whatwg.org/#attribute-value-(unquoted)-state>.
1118
+ unquoted: [['\t\n\f\r &>'.split(''), '\0\t\n\f\r "&\'<=>`'.split('')], ['\0\t\n\f\r "&\'<=>`'.split(''), '\0\t\n\f\r "&\'<=>`'.split('')]],
1119
+ // See: <https://html.spec.whatwg.org/#attribute-value-(single-quoted)-state>.
1120
+ single: [["&'".split(''), '"&\'`'.split('')], ["\0&'".split(''), '\0"&\'`'.split('')]],
1121
+ // See: <https://html.spec.whatwg.org/#attribute-value-(double-quoted)-state>.
1122
+ double: [['"&'.split(''), '"&\'`'.split('')], ['\0"&'.split(''), '\0"&\'`'.split('')]]
1123
+ };
1124
+
1125
+ /**
1126
+ * Serialize an element node.
1127
+ *
1128
+ * @param {Element} node
1129
+ * Node to handle.
1130
+ * @param {number | undefined} index
1131
+ * Index of `node` in `parent.
1132
+ * @param {Parents | undefined} parent
1133
+ * Parent of `node`.
1134
+ * @param {State} state
1135
+ * Info passed around about the current state.
1136
+ * @returns {string}
1137
+ * Serialized node.
1138
+ */
1139
+ function element(node, index, parent, state) {
1140
+ const schema = state.schema;
1141
+ const omit = schema.space === 'svg' ? false : state.settings.omitOptionalTags;
1142
+ let selfClosing = schema.space === 'svg' ? state.settings.closeEmptyElements : state.settings.voids.includes(node.tagName.toLowerCase());
1143
+ /** @type {Array<string>} */
1144
+ const parts = [];
1145
+ /** @type {string} */
1146
+ let last;
1147
+ if (schema.space === 'html' && node.tagName === 'svg') {
1148
+ state.schema = svg;
1149
+ }
1150
+ const attributes = serializeAttributes(state, node.properties);
1151
+ const content = state.all(schema.space === 'html' && node.tagName === 'template' ? node.content : node);
1152
+ state.schema = schema;
1153
+
1154
+ // If the node is categorised as void, but it has children, remove the
1155
+ // categorisation.
1156
+ // This enables for example `menuitem`s, which are void in W3C HTML but not
1157
+ // void in WHATWG HTML, to be stringified properly.
1158
+ // Note: `menuitem` has since been removed from the HTML spec, and so is no
1159
+ // longer void.
1160
+ if (content) selfClosing = false;
1161
+ if (attributes || !omit || !opening(node, index, parent)) {
1162
+ parts.push('<', node.tagName, attributes ? ' ' + attributes : '');
1163
+ if (selfClosing && (schema.space === 'svg' || state.settings.closeSelfClosing)) {
1164
+ last = attributes.charAt(attributes.length - 1);
1165
+ if (!state.settings.tightSelfClosing || last === '/' || last && last !== '"' && last !== "'") {
1166
+ parts.push(' ');
1167
+ }
1168
+ parts.push('/');
1169
+ }
1170
+ parts.push('>');
1171
+ }
1172
+ parts.push(content);
1173
+ if (!selfClosing && (!omit || !closing(node, index, parent))) {
1174
+ parts.push('</' + node.tagName + '>');
1175
+ }
1176
+ return parts.join('');
1177
+ }
1178
+
1179
+ /**
1180
+ * @param {State} state
1181
+ * @param {Properties | null | undefined} properties
1182
+ * @returns {string}
1183
+ */
1184
+ function serializeAttributes(state, properties) {
1185
+ /** @type {Array<string>} */
1186
+ const values = [];
1187
+ let index = -1;
1188
+ /** @type {string} */
1189
+ let key;
1190
+ if (properties) {
1191
+ for (key in properties) {
1192
+ if (properties[key] !== null && properties[key] !== undefined) {
1193
+ const value = serializeAttribute(state, key, properties[key]);
1194
+ if (value) values.push(value);
1195
+ }
1196
+ }
1197
+ }
1198
+ while (++index < values.length) {
1199
+ const last = state.settings.tightAttributes ? values[index].charAt(values[index].length - 1) : undefined;
1200
+
1201
+ // In tight mode, don’t add a space after quoted attributes.
1202
+ if (index !== values.length - 1 && last !== '"' && last !== "'") {
1203
+ values[index] += ' ';
1204
+ }
1205
+ }
1206
+ return values.join('');
1207
+ }
1208
+
1209
+ /**
1210
+ * @param {State} state
1211
+ * @param {string} key
1212
+ * @param {Properties[keyof Properties]} value
1213
+ * @returns {string}
1214
+ */
1215
+ function serializeAttribute(state, key, value) {
1216
+ const info = find(state.schema, key);
1217
+ const x = state.settings.allowParseErrors && state.schema.space === 'html' ? 0 : 1;
1218
+ const y = state.settings.allowDangerousCharacters ? 0 : 1;
1219
+ let quote = state.quote;
1220
+ /** @type {string | undefined} */
1221
+ let result;
1222
+ if (info.overloadedBoolean && (value === info.attribute || value === '')) {
1223
+ value = true;
1224
+ } else if ((info.boolean || info.overloadedBoolean) && (typeof value !== 'string' || value === info.attribute || value === '')) {
1225
+ value = Boolean(value);
1226
+ }
1227
+ if (value === null || value === undefined || value === false || typeof value === 'number' && Number.isNaN(value)) {
1228
+ return '';
1229
+ }
1230
+ const name = stringifyEntities(info.attribute, Object.assign({}, state.settings.characterReferences, {
1231
+ // Always encode without parse errors in non-HTML.
1232
+ subset: constants.name[x][y]
1233
+ }));
1234
+
1235
+ // No value.
1236
+ // There is currently only one boolean property in SVG: `[download]` on
1237
+ // `<a>`.
1238
+ // This property does not seem to work in browsers (Firefox, Safari, Chrome),
1239
+ // so I can’t test if dropping the value works.
1240
+ // But I assume that it should:
1241
+ //
1242
+ // ```html
1243
+ // <!doctype html>
1244
+ // <svg viewBox="0 0 100 100">
1245
+ // <a href=https://example.com download>
1246
+ // <circle cx=50 cy=40 r=35 />
1247
+ // </a>
1248
+ // </svg>
1249
+ // ```
1250
+ //
1251
+ // See: <https://github.com/wooorm/property-information/blob/main/lib/svg.js>
1252
+ if (value === true) return name;
1253
+
1254
+ // `spaces` doesn’t accept a second argument, but it’s given here just to
1255
+ // keep the code cleaner.
1256
+ value = Array.isArray(value) ? (info.commaSeparated ? stringify : stringify$1)(value, {
1257
+ padLeft: !state.settings.tightCommaSeparatedLists
1258
+ }) : String(value);
1259
+ if (state.settings.collapseEmptyAttributes && !value) return name;
1260
+
1261
+ // Check unquoted value.
1262
+ if (state.settings.preferUnquoted) {
1263
+ result = stringifyEntities(value, Object.assign({}, state.settings.characterReferences, {
1264
+ attribute: true,
1265
+ subset: constants.unquoted[x][y]
1266
+ }));
1267
+ }
1268
+
1269
+ // If we don’t want unquoted, or if `value` contains character references when
1270
+ // unquoted…
1271
+ if (result !== value) {
1272
+ // If the alternative is less common than `quote`, switch.
1273
+ if (state.settings.quoteSmart && ccount(value, quote) > ccount(value, state.alternative)) {
1274
+ quote = state.alternative;
1275
+ }
1276
+ result = quote + stringifyEntities(value, Object.assign({}, state.settings.characterReferences, {
1277
+ // Always encode without parse errors in non-HTML.
1278
+ subset: (quote === "'" ? constants.single : constants.double)[x][y],
1279
+ attribute: true
1280
+ })) + quote;
1281
+ }
1282
+
1283
+ // Don’t add a `=` for unquoted empties.
1284
+ return name + (result ? '=' + result : result);
1285
+ }
1286
+
1287
+ /**
1288
+ * @import {Parents, Text} from 'hast'
1289
+ * @import {Raw} from 'mdast-util-to-hast'
1290
+ * @import {State} from '../index.js'
1291
+ */
1292
+
1293
+
1294
+ // Declare array as variable so it can be cached by `stringifyEntities`
1295
+ const textEntitySubset = ['<', '&'];
1296
+
1297
+ /**
1298
+ * Serialize a text node.
1299
+ *
1300
+ * @param {Raw | Text} node
1301
+ * Node to handle.
1302
+ * @param {number | undefined} _
1303
+ * Index of `node` in `parent.
1304
+ * @param {Parents | undefined} parent
1305
+ * Parent of `node`.
1306
+ * @param {State} state
1307
+ * Info passed around about the current state.
1308
+ * @returns {string}
1309
+ * Serialized node.
1310
+ */
1311
+ function text(node, _, parent, state) {
1312
+ // Check if content of `node` should be escaped.
1313
+ return parent && parent.type === 'element' && (parent.tagName === 'script' || parent.tagName === 'style') ? node.value : stringifyEntities(node.value, Object.assign({}, state.settings.characterReferences, {
1314
+ subset: textEntitySubset
1315
+ }));
1316
+ }
1317
+
1318
+ /**
1319
+ * @import {Parents} from 'hast'
1320
+ * @import {Raw} from 'mdast-util-to-hast'
1321
+ * @import {State} from '../index.js'
1322
+ */
1323
+
1324
+
1325
+ /**
1326
+ * Serialize a raw node.
1327
+ *
1328
+ * @param {Raw} node
1329
+ * Node to handle.
1330
+ * @param {number | undefined} index
1331
+ * Index of `node` in `parent.
1332
+ * @param {Parents | undefined} parent
1333
+ * Parent of `node`.
1334
+ * @param {State} state
1335
+ * Info passed around about the current state.
1336
+ * @returns {string}
1337
+ * Serialized node.
1338
+ */
1339
+ function raw(node, index, parent, state) {
1340
+ return state.settings.allowDangerousHtml ? node.value : text(node, index, parent, state);
1341
+ }
1342
+
1343
+ /**
1344
+ * @import {Parents, Root} from 'hast'
1345
+ * @import {State} from '../index.js'
1346
+ */
1347
+
1348
+ /**
1349
+ * Serialize a root.
1350
+ *
1351
+ * @param {Root} node
1352
+ * Node to handle.
1353
+ * @param {number | undefined} _1
1354
+ * Index of `node` in `parent.
1355
+ * @param {Parents | undefined} _2
1356
+ * Parent of `node`.
1357
+ * @param {State} state
1358
+ * Info passed around about the current state.
1359
+ * @returns {string}
1360
+ * Serialized node.
1361
+ */
1362
+ function root(node, _1, _2, state) {
1363
+ return state.all(node);
1364
+ }
1365
+
1366
+ /**
1367
+ * @import {Nodes, Parents} from 'hast'
1368
+ * @import {State} from '../index.js'
1369
+ */
1370
+
1371
+
1372
+ /**
1373
+ * @type {(node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string}
1374
+ */
1375
+ const handle = zwitch('type', {
1376
+ invalid,
1377
+ unknown,
1378
+ handlers: {
1379
+ comment,
1380
+ doctype,
1381
+ element,
1382
+ raw,
1383
+ root,
1384
+ text
1385
+ }
1386
+ });
1387
+
1388
+ /**
1389
+ * Fail when a non-node is found in the tree.
1390
+ *
1391
+ * @param {unknown} node
1392
+ * Unknown value.
1393
+ * @returns {never}
1394
+ * Never.
1395
+ */
1396
+ function invalid(node) {
1397
+ throw new Error('Expected node, not `' + node + '`');
1398
+ }
1399
+
1400
+ /**
1401
+ * Fail when a node with an unknown type is found in the tree.
1402
+ *
1403
+ * @param {unknown} node_
1404
+ * Unknown node.
1405
+ * @returns {never}
1406
+ * Never.
1407
+ */
1408
+ function unknown(node_) {
1409
+ // `type` is guaranteed by runtime JS.
1410
+ const node = /** @type {Nodes} */node_;
1411
+ throw new Error('Cannot compile unknown node `' + node.type + '`');
1412
+ }
1413
+
1414
+ /**
1415
+ * @import {Nodes, Parents, RootContent} from 'hast'
1416
+ * @import {Schema} from 'property-information'
1417
+ * @import {Options as StringifyEntitiesOptions} from 'stringify-entities'
1418
+ */
1419
+
1420
+
1421
+ /** @type {Options} */
1422
+ const emptyOptions = {};
1423
+
1424
+ /** @type {CharacterReferences} */
1425
+ const emptyCharacterReferences = {};
1426
+
1427
+ /** @type {Array<never>} */
1428
+ const emptyChildren = [];
1429
+
1430
+ /**
1431
+ * Serialize hast as HTML.
1432
+ *
1433
+ * @param {Array<RootContent> | Nodes} tree
1434
+ * Tree to serialize.
1435
+ * @param {Options | null | undefined} [options]
1436
+ * Configuration (optional).
1437
+ * @returns {string}
1438
+ * Serialized HTML.
1439
+ */
1440
+ function toHtml(tree, options) {
1441
+ const options_ = options || emptyOptions;
1442
+ const quote = options_.quote || '"';
1443
+ const alternative = quote === '"' ? "'" : '"';
1444
+ if (quote !== '"' && quote !== "'") {
1445
+ throw new Error('Invalid quote `' + quote + '`, expected `\'` or `"`');
1446
+ }
1447
+
1448
+ /** @type {State} */
1449
+ const state = {
1450
+ one,
1451
+ all,
1452
+ settings: {
1453
+ omitOptionalTags: options_.omitOptionalTags || false,
1454
+ allowParseErrors: options_.allowParseErrors || false,
1455
+ allowDangerousCharacters: options_.allowDangerousCharacters || false,
1456
+ quoteSmart: options_.quoteSmart || false,
1457
+ preferUnquoted: options_.preferUnquoted || false,
1458
+ tightAttributes: options_.tightAttributes || false,
1459
+ upperDoctype: options_.upperDoctype || false,
1460
+ tightDoctype: options_.tightDoctype || false,
1461
+ bogusComments: options_.bogusComments || false,
1462
+ tightCommaSeparatedLists: options_.tightCommaSeparatedLists || false,
1463
+ tightSelfClosing: options_.tightSelfClosing || false,
1464
+ collapseEmptyAttributes: options_.collapseEmptyAttributes || false,
1465
+ allowDangerousHtml: options_.allowDangerousHtml || false,
1466
+ voids: options_.voids || htmlVoidElements,
1467
+ characterReferences: options_.characterReferences || emptyCharacterReferences,
1468
+ closeSelfClosing: options_.closeSelfClosing || false,
1469
+ closeEmptyElements: options_.closeEmptyElements || false
1470
+ },
1471
+ schema: options_.space === 'svg' ? svg : html$2,
1472
+ quote,
1473
+ alternative
1474
+ };
1475
+ return state.one(Array.isArray(tree) ? {
1476
+ type: 'root',
1477
+ children: tree
1478
+ } : tree, undefined, undefined);
1479
+ }
1480
+
1481
+ /**
1482
+ * Serialize a node.
1483
+ *
1484
+ * @this {State}
1485
+ * Info passed around about the current state.
1486
+ * @param {Nodes} node
1487
+ * Node to handle.
1488
+ * @param {number | undefined} index
1489
+ * Index of `node` in `parent.
1490
+ * @param {Parents | undefined} parent
1491
+ * Parent of `node`.
1492
+ * @returns {string}
1493
+ * Serialized node.
1494
+ */
1495
+ function one(node, index, parent) {
1496
+ return handle(node, index, parent, this);
1497
+ }
1498
+
1499
+ /**
1500
+ * Serialize all children of `parent`.
1501
+ *
1502
+ * @this {State}
1503
+ * Info passed around about the current state.
1504
+ * @param {Parents | undefined} parent
1505
+ * Parent whose children to serialize.
1506
+ * @returns {string}
1507
+ */
1508
+ function all(parent) {
1509
+ /** @type {Array<string>} */
1510
+ const results = [];
1511
+ const children = parent && parent.children || emptyChildren;
1512
+ let index = -1;
1513
+ while (++index < children.length) {
1514
+ results[index] = this.one(children[index], index, parent);
1515
+ }
1516
+ return results.join('');
1517
+ }
1518
+
1519
+ /**
1520
+ * @import {Root} from 'hast'
1521
+ * @import {Options} from 'hast-util-to-html'
1522
+ * @import {Compiler, Processor} from 'unified'
1523
+ */
1524
+
1525
+
1526
+ /**
1527
+ * Plugin to add support for serializing as HTML.
1528
+ *
1529
+ * @param {Options | null | undefined} [options]
1530
+ * Configuration (optional).
1531
+ * @returns {undefined}
1532
+ * Nothing.
1533
+ */
1534
+ function rehypeStringify(options) {
1535
+ /** @type {Processor<undefined, undefined, undefined, Root, string>} */
1536
+ // @ts-expect-error: TS in JSDoc generates wrong types if `this` is typed regularly.
1537
+ const self = this;
1538
+ const settings = {
1539
+ ...self.data('settings'),
1540
+ ...options
1541
+ };
1542
+ self.compiler = compiler;
1543
+
1544
+ /**
1545
+ * @type {Compiler<Root, string>}
1546
+ */
1547
+ function compiler(tree) {
1548
+ return toHtml(tree, settings);
1549
+ }
1550
+ }
1551
+
1552
+ export { rehypeStringify as default };
1553
+ //# sourceMappingURL=index-C371bO_b.js.map