html-minifier-next 2.1.4 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/htmlminifier.cjs +62 -25
- package/dist/htmlminifier.esm.bundle.js +62 -25
- package/dist/htmlminifier.umd.bundle.js +62 -25
- package/dist/htmlminifier.umd.bundle.min.js +1 -1
- package/package.json +8 -8
- package/src/htmlminifier.js +17 -15
- package/src/htmlparser.js +45 -10
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# HTML Minifier Next
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/html-minifier-next)
|
|
4
|
-
[](https://github.com/j9t/html-minifier-next/actions)
|
|
5
5
|
|
|
6
6
|
HTML Minifier Next (HMN) is a highly **configurable, well-tested, JavaScript-based HTML minifier**.
|
|
7
7
|
|
package/dist/htmlminifier.cjs
CHANGED
|
@@ -132,7 +132,7 @@ class HTMLParser {
|
|
|
132
132
|
if (!lastTag || !special.has(lastTag)) {
|
|
133
133
|
let textEnd = html.indexOf('<');
|
|
134
134
|
if (textEnd === 0) {
|
|
135
|
-
// Comment
|
|
135
|
+
// Comment
|
|
136
136
|
if (/^<!--/.test(html)) {
|
|
137
137
|
const commentEnd = html.indexOf('-->');
|
|
138
138
|
|
|
@@ -160,7 +160,7 @@ class HTMLParser {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
// Doctype
|
|
163
|
+
// Doctype
|
|
164
164
|
const doctypeMatch = html.match(doctype);
|
|
165
165
|
if (doctypeMatch) {
|
|
166
166
|
if (handler.doctype) {
|
|
@@ -171,7 +171,7 @@ class HTMLParser {
|
|
|
171
171
|
continue;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
// End tag
|
|
174
|
+
// End tag
|
|
175
175
|
const endTagMatch = html.match(endTag);
|
|
176
176
|
if (endTagMatch) {
|
|
177
177
|
html = html.substring(endTagMatch[0].length);
|
|
@@ -180,7 +180,7 @@ class HTMLParser {
|
|
|
180
180
|
continue;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
// Start tag
|
|
183
|
+
// Start tag
|
|
184
184
|
const startTagMatch = parseStartTag(html);
|
|
185
185
|
if (startTagMatch) {
|
|
186
186
|
html = startTagMatch.rest;
|
|
@@ -273,11 +273,41 @@ class HTMLParser {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
function findTagInCurrentTable(tagName) {
|
|
277
|
+
let pos;
|
|
278
|
+
const needle = tagName.toLowerCase();
|
|
279
|
+
for (pos = stack.length - 1; pos >= 0; pos--) {
|
|
280
|
+
const currentTag = stack[pos].tag.toLowerCase();
|
|
281
|
+
if (currentTag === needle) {
|
|
282
|
+
return pos;
|
|
283
|
+
}
|
|
284
|
+
// Stop searching if we hit a table boundary
|
|
285
|
+
if (currentTag === 'table') {
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return -1;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async function parseEndTagAt(pos) {
|
|
293
|
+
// Close all open elements up to pos (mirrors parseEndTag’s core branch)
|
|
294
|
+
for (let i = stack.length - 1; i >= pos; i--) {
|
|
295
|
+
if (handler.end) {
|
|
296
|
+
await handler.end(stack[i].tag, stack[i].attrs, true);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
stack.length = pos;
|
|
300
|
+
lastTag = pos && stack[pos - 1].tag;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
async function closeIfFoundInCurrentTable(tagName) {
|
|
304
|
+
const pos = findTagInCurrentTable(tagName);
|
|
305
|
+
if (pos >= 0) {
|
|
306
|
+
// Close at the specific index to avoid re-searching
|
|
307
|
+
await parseEndTagAt(pos);
|
|
279
308
|
return true;
|
|
280
309
|
}
|
|
310
|
+
return false;
|
|
281
311
|
}
|
|
282
312
|
|
|
283
313
|
async function handleStartTag(match) {
|
|
@@ -288,10 +318,15 @@ class HTMLParser {
|
|
|
288
318
|
if (lastTag === 'p' && nonPhrasing.has(tagName)) {
|
|
289
319
|
await parseEndTag('', lastTag);
|
|
290
320
|
} else if (tagName === 'tbody') {
|
|
291
|
-
await
|
|
321
|
+
await closeIfFoundInCurrentTable('thead');
|
|
292
322
|
} else if (tagName === 'tfoot') {
|
|
293
|
-
if (!await
|
|
294
|
-
await
|
|
323
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
324
|
+
await closeIfFoundInCurrentTable('thead');
|
|
325
|
+
}
|
|
326
|
+
} else if (tagName === 'thead') {
|
|
327
|
+
// If a `tbody` or `tfoot` is open in the current table, close it
|
|
328
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
329
|
+
await closeIfFoundInCurrentTable('tfoot');
|
|
295
330
|
}
|
|
296
331
|
}
|
|
297
332
|
if (tagName === 'col' && findTag('colgroup') < 0) {
|
|
@@ -549,9 +584,9 @@ function collapseWhitespace(str, options, trimLeft, trimRight, collapseAll) {
|
|
|
549
584
|
}
|
|
550
585
|
|
|
551
586
|
// Non-empty elements that will maintain whitespace around them
|
|
552
|
-
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
587
|
+
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
553
588
|
// Non-empty elements that will maintain whitespace within them
|
|
554
|
-
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', '
|
|
589
|
+
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'time', 'tt', 'u', 'var']);
|
|
555
590
|
// Elements that will always maintain whitespace around them
|
|
556
591
|
const inlineElementsToKeepWhitespace = new Set(['comment', 'img', 'input', 'wbr']);
|
|
557
592
|
|
|
@@ -904,19 +939,18 @@ async function processScript(text, options, currentAttrs) {
|
|
|
904
939
|
return text;
|
|
905
940
|
}
|
|
906
941
|
|
|
907
|
-
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
|
908
|
-
// with the following deviations:
|
|
942
|
+
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags with the following extensions:
|
|
909
943
|
// - retain <body> if followed by <noscript>
|
|
910
|
-
// -
|
|
944
|
+
// - <rb>, <rt>, <rtc>, <rp> follow HTML Ruby Markup Extensions draft (https://www.w3.org/TR/html-ruby-extensions/)
|
|
911
945
|
// - retain all tags which are adjacent to non-standard HTML tags
|
|
912
946
|
const optionalStartTags = new Set(['html', 'head', 'body', 'colgroup', 'tbody']);
|
|
913
947
|
const optionalEndTags = new Set(['html', 'head', 'body', 'li', 'dt', 'dd', 'p', 'rb', 'rt', 'rtc', 'rp', 'optgroup', 'option', 'colgroup', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th']);
|
|
914
948
|
const headerTags = new Set(['meta', 'link', 'script', 'style', 'template', 'noscript']);
|
|
915
949
|
const descriptionTags = new Set(['dt', 'dd']);
|
|
916
|
-
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']);
|
|
950
|
+
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'dialog', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'search', 'section', 'table', 'ul']);
|
|
917
951
|
const pInlineTags = new Set(['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']);
|
|
918
|
-
const
|
|
919
|
-
const
|
|
952
|
+
const rubyEndTagOmission = new Set(['rb', 'rt', 'rtc', 'rp']); // </rb>, </rt>, </rp> can be omitted if followed by <rb>, <rt>, <rtc>, or <rp>
|
|
953
|
+
const rubyRtcEndTagOmission = new Set(['rb', 'rtc']); // </rtc> can be omitted if followed by <rb> or <rtc> (not <rt> or <rp>)
|
|
920
954
|
const optionTag = new Set(['option', 'optgroup']);
|
|
921
955
|
const tableContentTags = new Set(['tbody', 'tfoot']);
|
|
922
956
|
const tableSectionTags = new Set(['thead', 'tbody', 'tfoot']);
|
|
@@ -972,9 +1006,9 @@ function canRemovePrecedingTag(optionalEndTag, tag) {
|
|
|
972
1006
|
case 'rb':
|
|
973
1007
|
case 'rt':
|
|
974
1008
|
case 'rp':
|
|
975
|
-
return
|
|
1009
|
+
return rubyEndTagOmission.has(tag);
|
|
976
1010
|
case 'rtc':
|
|
977
|
-
return
|
|
1011
|
+
return rubyRtcEndTagOmission.has(tag);
|
|
978
1012
|
case 'option':
|
|
979
1013
|
return optionTag.has(tag);
|
|
980
1014
|
case 'thead':
|
|
@@ -1584,7 +1618,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1584
1618
|
let optional = options.removeOptionalTags;
|
|
1585
1619
|
if (optional) {
|
|
1586
1620
|
const htmlTag = htmlTags.has(tag);
|
|
1587
|
-
// <html> may be omitted if first thing inside is not comment
|
|
1621
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
1588
1622
|
// <head> may be omitted if first thing inside is an element
|
|
1589
1623
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
1590
1624
|
// <colgroup> may be omitted if first thing inside is <col>
|
|
@@ -1603,7 +1637,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1603
1637
|
optionalEndTag = '';
|
|
1604
1638
|
}
|
|
1605
1639
|
|
|
1606
|
-
// Set whitespace flags for nested tags (
|
|
1640
|
+
// Set whitespace flags for nested tags (e.g., <code> within a <pre>)
|
|
1607
1641
|
if (options.collapseWhitespace) {
|
|
1608
1642
|
if (!stackNoTrimWhitespace.length) {
|
|
1609
1643
|
squashTrailingWhitespace(tag);
|
|
@@ -1771,7 +1805,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1771
1805
|
text = await options.minifyCSS(text);
|
|
1772
1806
|
}
|
|
1773
1807
|
if (options.removeOptionalTags && text) {
|
|
1774
|
-
// <html> may be omitted if first thing inside is not comment
|
|
1808
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
1775
1809
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
1776
1810
|
if (optionalStartTag === 'html' || (optionalStartTag === 'body' && !/^\s/.test(text))) {
|
|
1777
1811
|
removeStartTag();
|
|
@@ -1782,7 +1816,10 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1782
1816
|
if (compactTags.has(optionalEndTag) || (looseTags.has(optionalEndTag) && !/^\s/.test(text))) {
|
|
1783
1817
|
removeEndTag();
|
|
1784
1818
|
}
|
|
1785
|
-
optionalEndTag
|
|
1819
|
+
// Don’t reset optionalEndTag if text is only whitespace and will be collapsed (not conservatively)
|
|
1820
|
+
if (!/^\s+$/.test(text) || !options.collapseWhitespace || options.conservativeCollapse) {
|
|
1821
|
+
optionalEndTag = '';
|
|
1822
|
+
}
|
|
1786
1823
|
}
|
|
1787
1824
|
charsPrevTag = /^\s*$/.test(text) ? prevTag : 'comment';
|
|
1788
1825
|
if (options.decodeEntities && text && !specialContentTags.has(currentTag)) {
|
|
@@ -1836,7 +1873,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1836
1873
|
await parser.parse();
|
|
1837
1874
|
|
|
1838
1875
|
if (options.removeOptionalTags) {
|
|
1839
|
-
// <html> may be omitted if first thing inside is not comment
|
|
1876
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
1840
1877
|
// <head> or <body> may be omitted if empty
|
|
1841
1878
|
if (topLevelTags.has(optionalStartTag)) {
|
|
1842
1879
|
removeStartTag();
|
|
@@ -60322,7 +60322,7 @@ class HTMLParser {
|
|
|
60322
60322
|
if (!lastTag || !special.has(lastTag)) {
|
|
60323
60323
|
let textEnd = html.indexOf('<');
|
|
60324
60324
|
if (textEnd === 0) {
|
|
60325
|
-
// Comment
|
|
60325
|
+
// Comment
|
|
60326
60326
|
if (/^<!--/.test(html)) {
|
|
60327
60327
|
const commentEnd = html.indexOf('-->');
|
|
60328
60328
|
|
|
@@ -60350,7 +60350,7 @@ class HTMLParser {
|
|
|
60350
60350
|
}
|
|
60351
60351
|
}
|
|
60352
60352
|
|
|
60353
|
-
// Doctype
|
|
60353
|
+
// Doctype
|
|
60354
60354
|
const doctypeMatch = html.match(doctype);
|
|
60355
60355
|
if (doctypeMatch) {
|
|
60356
60356
|
if (handler.doctype) {
|
|
@@ -60361,7 +60361,7 @@ class HTMLParser {
|
|
|
60361
60361
|
continue;
|
|
60362
60362
|
}
|
|
60363
60363
|
|
|
60364
|
-
// End tag
|
|
60364
|
+
// End tag
|
|
60365
60365
|
const endTagMatch = html.match(endTag);
|
|
60366
60366
|
if (endTagMatch) {
|
|
60367
60367
|
html = html.substring(endTagMatch[0].length);
|
|
@@ -60370,7 +60370,7 @@ class HTMLParser {
|
|
|
60370
60370
|
continue;
|
|
60371
60371
|
}
|
|
60372
60372
|
|
|
60373
|
-
// Start tag
|
|
60373
|
+
// Start tag
|
|
60374
60374
|
const startTagMatch = parseStartTag(html);
|
|
60375
60375
|
if (startTagMatch) {
|
|
60376
60376
|
html = startTagMatch.rest;
|
|
@@ -60463,11 +60463,41 @@ class HTMLParser {
|
|
|
60463
60463
|
}
|
|
60464
60464
|
}
|
|
60465
60465
|
|
|
60466
|
-
|
|
60467
|
-
|
|
60468
|
-
|
|
60466
|
+
function findTagInCurrentTable(tagName) {
|
|
60467
|
+
let pos;
|
|
60468
|
+
const needle = tagName.toLowerCase();
|
|
60469
|
+
for (pos = stack.length - 1; pos >= 0; pos--) {
|
|
60470
|
+
const currentTag = stack[pos].tag.toLowerCase();
|
|
60471
|
+
if (currentTag === needle) {
|
|
60472
|
+
return pos;
|
|
60473
|
+
}
|
|
60474
|
+
// Stop searching if we hit a table boundary
|
|
60475
|
+
if (currentTag === 'table') {
|
|
60476
|
+
break;
|
|
60477
|
+
}
|
|
60478
|
+
}
|
|
60479
|
+
return -1;
|
|
60480
|
+
}
|
|
60481
|
+
|
|
60482
|
+
async function parseEndTagAt(pos) {
|
|
60483
|
+
// Close all open elements up to pos (mirrors parseEndTag’s core branch)
|
|
60484
|
+
for (let i = stack.length - 1; i >= pos; i--) {
|
|
60485
|
+
if (handler.end) {
|
|
60486
|
+
await handler.end(stack[i].tag, stack[i].attrs, true);
|
|
60487
|
+
}
|
|
60488
|
+
}
|
|
60489
|
+
stack.length = pos;
|
|
60490
|
+
lastTag = pos && stack[pos - 1].tag;
|
|
60491
|
+
}
|
|
60492
|
+
|
|
60493
|
+
async function closeIfFoundInCurrentTable(tagName) {
|
|
60494
|
+
const pos = findTagInCurrentTable(tagName);
|
|
60495
|
+
if (pos >= 0) {
|
|
60496
|
+
// Close at the specific index to avoid re-searching
|
|
60497
|
+
await parseEndTagAt(pos);
|
|
60469
60498
|
return true;
|
|
60470
60499
|
}
|
|
60500
|
+
return false;
|
|
60471
60501
|
}
|
|
60472
60502
|
|
|
60473
60503
|
async function handleStartTag(match) {
|
|
@@ -60478,10 +60508,15 @@ class HTMLParser {
|
|
|
60478
60508
|
if (lastTag === 'p' && nonPhrasing.has(tagName)) {
|
|
60479
60509
|
await parseEndTag('', lastTag);
|
|
60480
60510
|
} else if (tagName === 'tbody') {
|
|
60481
|
-
await
|
|
60511
|
+
await closeIfFoundInCurrentTable('thead');
|
|
60482
60512
|
} else if (tagName === 'tfoot') {
|
|
60483
|
-
if (!await
|
|
60484
|
-
await
|
|
60513
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
60514
|
+
await closeIfFoundInCurrentTable('thead');
|
|
60515
|
+
}
|
|
60516
|
+
} else if (tagName === 'thead') {
|
|
60517
|
+
// If a `tbody` or `tfoot` is open in the current table, close it
|
|
60518
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
60519
|
+
await closeIfFoundInCurrentTable('tfoot');
|
|
60485
60520
|
}
|
|
60486
60521
|
}
|
|
60487
60522
|
if (tagName === 'col' && findTag('colgroup') < 0) {
|
|
@@ -60739,9 +60774,9 @@ function collapseWhitespace(str, options, trimLeft, trimRight, collapseAll) {
|
|
|
60739
60774
|
}
|
|
60740
60775
|
|
|
60741
60776
|
// Non-empty elements that will maintain whitespace around them
|
|
60742
|
-
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
60777
|
+
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
60743
60778
|
// Non-empty elements that will maintain whitespace within them
|
|
60744
|
-
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', '
|
|
60779
|
+
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'time', 'tt', 'u', 'var']);
|
|
60745
60780
|
// Elements that will always maintain whitespace around them
|
|
60746
60781
|
const inlineElementsToKeepWhitespace = new Set(['comment', 'img', 'input', 'wbr']);
|
|
60747
60782
|
|
|
@@ -61094,19 +61129,18 @@ async function processScript(text, options, currentAttrs) {
|
|
|
61094
61129
|
return text;
|
|
61095
61130
|
}
|
|
61096
61131
|
|
|
61097
|
-
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
|
61098
|
-
// with the following deviations:
|
|
61132
|
+
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags with the following extensions:
|
|
61099
61133
|
// - retain <body> if followed by <noscript>
|
|
61100
|
-
// -
|
|
61134
|
+
// - <rb>, <rt>, <rtc>, <rp> follow HTML Ruby Markup Extensions draft (https://www.w3.org/TR/html-ruby-extensions/)
|
|
61101
61135
|
// - retain all tags which are adjacent to non-standard HTML tags
|
|
61102
61136
|
const optionalStartTags = new Set(['html', 'head', 'body', 'colgroup', 'tbody']);
|
|
61103
61137
|
const optionalEndTags = new Set(['html', 'head', 'body', 'li', 'dt', 'dd', 'p', 'rb', 'rt', 'rtc', 'rp', 'optgroup', 'option', 'colgroup', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th']);
|
|
61104
61138
|
const headerTags = new Set(['meta', 'link', 'script', 'style', 'template', 'noscript']);
|
|
61105
61139
|
const descriptionTags = new Set(['dt', 'dd']);
|
|
61106
|
-
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']);
|
|
61140
|
+
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'dialog', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'search', 'section', 'table', 'ul']);
|
|
61107
61141
|
const pInlineTags = new Set(['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']);
|
|
61108
|
-
const
|
|
61109
|
-
const
|
|
61142
|
+
const rubyEndTagOmission = new Set(['rb', 'rt', 'rtc', 'rp']); // </rb>, </rt>, </rp> can be omitted if followed by <rb>, <rt>, <rtc>, or <rp>
|
|
61143
|
+
const rubyRtcEndTagOmission = new Set(['rb', 'rtc']); // </rtc> can be omitted if followed by <rb> or <rtc> (not <rt> or <rp>)
|
|
61110
61144
|
const optionTag = new Set(['option', 'optgroup']);
|
|
61111
61145
|
const tableContentTags = new Set(['tbody', 'tfoot']);
|
|
61112
61146
|
const tableSectionTags = new Set(['thead', 'tbody', 'tfoot']);
|
|
@@ -61162,9 +61196,9 @@ function canRemovePrecedingTag(optionalEndTag, tag) {
|
|
|
61162
61196
|
case 'rb':
|
|
61163
61197
|
case 'rt':
|
|
61164
61198
|
case 'rp':
|
|
61165
|
-
return
|
|
61199
|
+
return rubyEndTagOmission.has(tag);
|
|
61166
61200
|
case 'rtc':
|
|
61167
|
-
return
|
|
61201
|
+
return rubyRtcEndTagOmission.has(tag);
|
|
61168
61202
|
case 'option':
|
|
61169
61203
|
return optionTag.has(tag);
|
|
61170
61204
|
case 'thead':
|
|
@@ -61774,7 +61808,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
61774
61808
|
let optional = options.removeOptionalTags;
|
|
61775
61809
|
if (optional) {
|
|
61776
61810
|
const htmlTag = htmlTags.has(tag);
|
|
61777
|
-
// <html> may be omitted if first thing inside is not comment
|
|
61811
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
61778
61812
|
// <head> may be omitted if first thing inside is an element
|
|
61779
61813
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
61780
61814
|
// <colgroup> may be omitted if first thing inside is <col>
|
|
@@ -61793,7 +61827,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
61793
61827
|
optionalEndTag = '';
|
|
61794
61828
|
}
|
|
61795
61829
|
|
|
61796
|
-
// Set whitespace flags for nested tags (
|
|
61830
|
+
// Set whitespace flags for nested tags (e.g., <code> within a <pre>)
|
|
61797
61831
|
if (options.collapseWhitespace) {
|
|
61798
61832
|
if (!stackNoTrimWhitespace.length) {
|
|
61799
61833
|
squashTrailingWhitespace(tag);
|
|
@@ -61961,7 +61995,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
61961
61995
|
text = await options.minifyCSS(text);
|
|
61962
61996
|
}
|
|
61963
61997
|
if (options.removeOptionalTags && text) {
|
|
61964
|
-
// <html> may be omitted if first thing inside is not comment
|
|
61998
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
61965
61999
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
61966
62000
|
if (optionalStartTag === 'html' || (optionalStartTag === 'body' && !/^\s/.test(text))) {
|
|
61967
62001
|
removeStartTag();
|
|
@@ -61972,7 +62006,10 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
61972
62006
|
if (compactTags.has(optionalEndTag) || (looseTags.has(optionalEndTag) && !/^\s/.test(text))) {
|
|
61973
62007
|
removeEndTag();
|
|
61974
62008
|
}
|
|
61975
|
-
optionalEndTag
|
|
62009
|
+
// Don’t reset optionalEndTag if text is only whitespace and will be collapsed (not conservatively)
|
|
62010
|
+
if (!/^\s+$/.test(text) || !options.collapseWhitespace || options.conservativeCollapse) {
|
|
62011
|
+
optionalEndTag = '';
|
|
62012
|
+
}
|
|
61976
62013
|
}
|
|
61977
62014
|
charsPrevTag = /^\s*$/.test(text) ? prevTag : 'comment';
|
|
61978
62015
|
if (options.decodeEntities && text && !specialContentTags.has(currentTag)) {
|
|
@@ -62026,7 +62063,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
62026
62063
|
await parser.parse();
|
|
62027
62064
|
|
|
62028
62065
|
if (options.removeOptionalTags) {
|
|
62029
|
-
// <html> may be omitted if first thing inside is not comment
|
|
62066
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
62030
62067
|
// <head> or <body> may be omitted if empty
|
|
62031
62068
|
if (topLevelTags.has(optionalStartTag)) {
|
|
62032
62069
|
removeStartTag();
|
|
@@ -60328,7 +60328,7 @@
|
|
|
60328
60328
|
if (!lastTag || !special.has(lastTag)) {
|
|
60329
60329
|
let textEnd = html.indexOf('<');
|
|
60330
60330
|
if (textEnd === 0) {
|
|
60331
|
-
// Comment
|
|
60331
|
+
// Comment
|
|
60332
60332
|
if (/^<!--/.test(html)) {
|
|
60333
60333
|
const commentEnd = html.indexOf('-->');
|
|
60334
60334
|
|
|
@@ -60356,7 +60356,7 @@
|
|
|
60356
60356
|
}
|
|
60357
60357
|
}
|
|
60358
60358
|
|
|
60359
|
-
// Doctype
|
|
60359
|
+
// Doctype
|
|
60360
60360
|
const doctypeMatch = html.match(doctype);
|
|
60361
60361
|
if (doctypeMatch) {
|
|
60362
60362
|
if (handler.doctype) {
|
|
@@ -60367,7 +60367,7 @@
|
|
|
60367
60367
|
continue;
|
|
60368
60368
|
}
|
|
60369
60369
|
|
|
60370
|
-
// End tag
|
|
60370
|
+
// End tag
|
|
60371
60371
|
const endTagMatch = html.match(endTag);
|
|
60372
60372
|
if (endTagMatch) {
|
|
60373
60373
|
html = html.substring(endTagMatch[0].length);
|
|
@@ -60376,7 +60376,7 @@
|
|
|
60376
60376
|
continue;
|
|
60377
60377
|
}
|
|
60378
60378
|
|
|
60379
|
-
// Start tag
|
|
60379
|
+
// Start tag
|
|
60380
60380
|
const startTagMatch = parseStartTag(html);
|
|
60381
60381
|
if (startTagMatch) {
|
|
60382
60382
|
html = startTagMatch.rest;
|
|
@@ -60469,11 +60469,41 @@
|
|
|
60469
60469
|
}
|
|
60470
60470
|
}
|
|
60471
60471
|
|
|
60472
|
-
|
|
60473
|
-
|
|
60474
|
-
|
|
60472
|
+
function findTagInCurrentTable(tagName) {
|
|
60473
|
+
let pos;
|
|
60474
|
+
const needle = tagName.toLowerCase();
|
|
60475
|
+
for (pos = stack.length - 1; pos >= 0; pos--) {
|
|
60476
|
+
const currentTag = stack[pos].tag.toLowerCase();
|
|
60477
|
+
if (currentTag === needle) {
|
|
60478
|
+
return pos;
|
|
60479
|
+
}
|
|
60480
|
+
// Stop searching if we hit a table boundary
|
|
60481
|
+
if (currentTag === 'table') {
|
|
60482
|
+
break;
|
|
60483
|
+
}
|
|
60484
|
+
}
|
|
60485
|
+
return -1;
|
|
60486
|
+
}
|
|
60487
|
+
|
|
60488
|
+
async function parseEndTagAt(pos) {
|
|
60489
|
+
// Close all open elements up to pos (mirrors parseEndTag’s core branch)
|
|
60490
|
+
for (let i = stack.length - 1; i >= pos; i--) {
|
|
60491
|
+
if (handler.end) {
|
|
60492
|
+
await handler.end(stack[i].tag, stack[i].attrs, true);
|
|
60493
|
+
}
|
|
60494
|
+
}
|
|
60495
|
+
stack.length = pos;
|
|
60496
|
+
lastTag = pos && stack[pos - 1].tag;
|
|
60497
|
+
}
|
|
60498
|
+
|
|
60499
|
+
async function closeIfFoundInCurrentTable(tagName) {
|
|
60500
|
+
const pos = findTagInCurrentTable(tagName);
|
|
60501
|
+
if (pos >= 0) {
|
|
60502
|
+
// Close at the specific index to avoid re-searching
|
|
60503
|
+
await parseEndTagAt(pos);
|
|
60475
60504
|
return true;
|
|
60476
60505
|
}
|
|
60506
|
+
return false;
|
|
60477
60507
|
}
|
|
60478
60508
|
|
|
60479
60509
|
async function handleStartTag(match) {
|
|
@@ -60484,10 +60514,15 @@
|
|
|
60484
60514
|
if (lastTag === 'p' && nonPhrasing.has(tagName)) {
|
|
60485
60515
|
await parseEndTag('', lastTag);
|
|
60486
60516
|
} else if (tagName === 'tbody') {
|
|
60487
|
-
await
|
|
60517
|
+
await closeIfFoundInCurrentTable('thead');
|
|
60488
60518
|
} else if (tagName === 'tfoot') {
|
|
60489
|
-
if (!await
|
|
60490
|
-
await
|
|
60519
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
60520
|
+
await closeIfFoundInCurrentTable('thead');
|
|
60521
|
+
}
|
|
60522
|
+
} else if (tagName === 'thead') {
|
|
60523
|
+
// If a `tbody` or `tfoot` is open in the current table, close it
|
|
60524
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
60525
|
+
await closeIfFoundInCurrentTable('tfoot');
|
|
60491
60526
|
}
|
|
60492
60527
|
}
|
|
60493
60528
|
if (tagName === 'col' && findTag('colgroup') < 0) {
|
|
@@ -60745,9 +60780,9 @@
|
|
|
60745
60780
|
}
|
|
60746
60781
|
|
|
60747
60782
|
// Non-empty elements that will maintain whitespace around them
|
|
60748
|
-
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
60783
|
+
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
60749
60784
|
// Non-empty elements that will maintain whitespace within them
|
|
60750
|
-
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', '
|
|
60785
|
+
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'time', 'tt', 'u', 'var']);
|
|
60751
60786
|
// Elements that will always maintain whitespace around them
|
|
60752
60787
|
const inlineElementsToKeepWhitespace = new Set(['comment', 'img', 'input', 'wbr']);
|
|
60753
60788
|
|
|
@@ -61100,19 +61135,18 @@
|
|
|
61100
61135
|
return text;
|
|
61101
61136
|
}
|
|
61102
61137
|
|
|
61103
|
-
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
|
61104
|
-
// with the following deviations:
|
|
61138
|
+
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags with the following extensions:
|
|
61105
61139
|
// - retain <body> if followed by <noscript>
|
|
61106
|
-
// -
|
|
61140
|
+
// - <rb>, <rt>, <rtc>, <rp> follow HTML Ruby Markup Extensions draft (https://www.w3.org/TR/html-ruby-extensions/)
|
|
61107
61141
|
// - retain all tags which are adjacent to non-standard HTML tags
|
|
61108
61142
|
const optionalStartTags = new Set(['html', 'head', 'body', 'colgroup', 'tbody']);
|
|
61109
61143
|
const optionalEndTags = new Set(['html', 'head', 'body', 'li', 'dt', 'dd', 'p', 'rb', 'rt', 'rtc', 'rp', 'optgroup', 'option', 'colgroup', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th']);
|
|
61110
61144
|
const headerTags = new Set(['meta', 'link', 'script', 'style', 'template', 'noscript']);
|
|
61111
61145
|
const descriptionTags = new Set(['dt', 'dd']);
|
|
61112
|
-
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']);
|
|
61146
|
+
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'dialog', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'search', 'section', 'table', 'ul']);
|
|
61113
61147
|
const pInlineTags = new Set(['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']);
|
|
61114
|
-
const
|
|
61115
|
-
const
|
|
61148
|
+
const rubyEndTagOmission = new Set(['rb', 'rt', 'rtc', 'rp']); // </rb>, </rt>, </rp> can be omitted if followed by <rb>, <rt>, <rtc>, or <rp>
|
|
61149
|
+
const rubyRtcEndTagOmission = new Set(['rb', 'rtc']); // </rtc> can be omitted if followed by <rb> or <rtc> (not <rt> or <rp>)
|
|
61116
61150
|
const optionTag = new Set(['option', 'optgroup']);
|
|
61117
61151
|
const tableContentTags = new Set(['tbody', 'tfoot']);
|
|
61118
61152
|
const tableSectionTags = new Set(['thead', 'tbody', 'tfoot']);
|
|
@@ -61168,9 +61202,9 @@
|
|
|
61168
61202
|
case 'rb':
|
|
61169
61203
|
case 'rt':
|
|
61170
61204
|
case 'rp':
|
|
61171
|
-
return
|
|
61205
|
+
return rubyEndTagOmission.has(tag);
|
|
61172
61206
|
case 'rtc':
|
|
61173
|
-
return
|
|
61207
|
+
return rubyRtcEndTagOmission.has(tag);
|
|
61174
61208
|
case 'option':
|
|
61175
61209
|
return optionTag.has(tag);
|
|
61176
61210
|
case 'thead':
|
|
@@ -61780,7 +61814,7 @@
|
|
|
61780
61814
|
let optional = options.removeOptionalTags;
|
|
61781
61815
|
if (optional) {
|
|
61782
61816
|
const htmlTag = htmlTags.has(tag);
|
|
61783
|
-
// <html> may be omitted if first thing inside is not comment
|
|
61817
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
61784
61818
|
// <head> may be omitted if first thing inside is an element
|
|
61785
61819
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
61786
61820
|
// <colgroup> may be omitted if first thing inside is <col>
|
|
@@ -61799,7 +61833,7 @@
|
|
|
61799
61833
|
optionalEndTag = '';
|
|
61800
61834
|
}
|
|
61801
61835
|
|
|
61802
|
-
// Set whitespace flags for nested tags (
|
|
61836
|
+
// Set whitespace flags for nested tags (e.g., <code> within a <pre>)
|
|
61803
61837
|
if (options.collapseWhitespace) {
|
|
61804
61838
|
if (!stackNoTrimWhitespace.length) {
|
|
61805
61839
|
squashTrailingWhitespace(tag);
|
|
@@ -61967,7 +62001,7 @@
|
|
|
61967
62001
|
text = await options.minifyCSS(text);
|
|
61968
62002
|
}
|
|
61969
62003
|
if (options.removeOptionalTags && text) {
|
|
61970
|
-
// <html> may be omitted if first thing inside is not comment
|
|
62004
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
61971
62005
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
61972
62006
|
if (optionalStartTag === 'html' || (optionalStartTag === 'body' && !/^\s/.test(text))) {
|
|
61973
62007
|
removeStartTag();
|
|
@@ -61978,7 +62012,10 @@
|
|
|
61978
62012
|
if (compactTags.has(optionalEndTag) || (looseTags.has(optionalEndTag) && !/^\s/.test(text))) {
|
|
61979
62013
|
removeEndTag();
|
|
61980
62014
|
}
|
|
61981
|
-
optionalEndTag
|
|
62015
|
+
// Don’t reset optionalEndTag if text is only whitespace and will be collapsed (not conservatively)
|
|
62016
|
+
if (!/^\s+$/.test(text) || !options.collapseWhitespace || options.conservativeCollapse) {
|
|
62017
|
+
optionalEndTag = '';
|
|
62018
|
+
}
|
|
61982
62019
|
}
|
|
61983
62020
|
charsPrevTag = /^\s*$/.test(text) ? prevTag : 'comment';
|
|
61984
62021
|
if (options.decodeEntities && text && !specialContentTags.has(currentTag)) {
|
|
@@ -62032,7 +62069,7 @@
|
|
|
62032
62069
|
await parser.parse();
|
|
62033
62070
|
|
|
62034
62071
|
if (options.removeOptionalTags) {
|
|
62035
|
-
// <html> may be omitted if first thing inside is not comment
|
|
62072
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
62036
62073
|
// <head> or <body> may be omitted if empty
|
|
62037
62074
|
if (topLevelTags.has(optionalStartTag)) {
|
|
62038
62075
|
removeStartTag();
|
|
@@ -6,4 +6,4 @@ var ps=2147483647,ds=/[^\x20-\x7E]/,hs=/[\x2E\u3002\uFF0E\uFF61]/g,As={overflow:
|
|
|
6
6
|
* Modified by Juriy “kangax” Zaytsev
|
|
7
7
|
* Original code by Erik Arvidsson, Mozilla Public License
|
|
8
8
|
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
|
9
|
-
*/class AE extends Set{has(e){return super.has(e.toLowerCase())}}const mE=/([^\s"'<>/=]+)/,gE=[/=/],_E=[/"([^"]*)"+/.source,/'([^']*)'+/.source,/([^ \t\n\f\r"'`=<>]+)/.source],EE=function(){const e="A-Za-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u0131\\u0134-\\u013E\\u0141-\\u0148\\u014A-\\u017E\\u0180-\\u01C3\\u01CD-\\u01F0\\u01F4\\u01F5\\u01FA-\\u0217\\u0250-\\u02A8\\u02BB-\\u02C1\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03CE\\u03D0-\\u03D6\\u03DA\\u03DC\\u03DE\\u03E0\\u03E2-\\u03F3\\u0401-\\u040C\\u040E-\\u044F\\u0451-\\u045C\\u045E-\\u0481\\u0490-\\u04C4\\u04C7\\u04C8\\u04CB\\u04CC\\u04D0-\\u04EB\\u04EE-\\u04F5\\u04F8\\u04F9\\u0531-\\u0556\\u0559\\u0561-\\u0586\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u063A\\u0641-\\u064A\\u0671-\\u06B7\\u06BA-\\u06BE\\u06C0-\\u06CE\\u06D0-\\u06D3\\u06D5\\u06E5\\u06E6\\u0905-\\u0939\\u093D\\u0958-\\u0961\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8B\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AE0\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B36-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB5\\u0BB7-\\u0BB9\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D60\\u0D61\\u0E01-\\u0E2E\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E45\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD\\u0EAE\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0F40-\\u0F47\\u0F49-\\u0F69\\u10A0-\\u10C5\\u10D0-\\u10F6\\u1100\\u1102\\u1103\\u1105-\\u1107\\u1109\\u110B\\u110C\\u110E-\\u1112\\u113C\\u113E\\u1140\\u114C\\u114E\\u1150\\u1154\\u1155\\u1159\\u115F-\\u1161\\u1163\\u1165\\u1167\\u1169\\u116D\\u116E\\u1172\\u1173\\u1175\\u119E\\u11A8\\u11AB\\u11AE\\u11AF\\u11B7\\u11B8\\u11BA\\u11BC-\\u11C2\\u11EB\\u11F0\\u11F9\\u1E00-\\u1E9B\\u1EA0-\\u1EF9\\u1F00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2126\\u212A\\u212B\\u212E\\u2180-\\u2182\\u3007\\u3021-\\u3029\\u3041-\\u3094\\u30A1-\\u30FA\\u3105-\\u312C\\u4E00-\\u9FA5\\uAC00-\\uD7A3",t="["+e+"_]["+e+"0-9\\u0660-\\u0669\\u06F0-\\u06F9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE7-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\.\\-_\\u0300-\\u0345\\u0360\\u0361\\u0483-\\u0486\\u0591-\\u05A1\\u05A3-\\u05B9\\u05BB-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u064B-\\u0652\\u0670\\u06D6-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0901-\\u0903\\u093C\\u093E-\\u094D\\u0951-\\u0954\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A02\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A70\\u0A71\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B43\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B82\\u0B83\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C01-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C82\\u0C83\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D43\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86-\\u0F8B\\u0F90-\\u0F95\\u0F97\\u0F99-\\u0FAD\\u0FB1-\\u0FB7\\u0FB9\\u20D0-\\u20DC\\u20E1\\u302A-\\u302F\\u3099\\u309A\\xB7\\u02D0\\u02D1\\u0387\\u0640\\u0E46\\u0EC6\\u3005\\u3031-\\u3035\\u309D\\u309E\\u30FC-\\u30FE]*";return"((?:"+t+"\\:)?"+t+")"}(),vE=new RegExp("^<"+EE),bE=/^\s*(\/?)>/,yE=new RegExp("^<\\/"+EE+"[^>]*>"),SE=/^<!DOCTYPE\s?[^>]+>/i;let CE=!1;"x".replace(/x(.)?/g,function(e,t){CE=""===t});const DE=new AE(["area","base","basefont","br","col","embed","frame","hr","img","input","isindex","keygen","link","meta","param","source","track","wbr"]),wE=new AE(["a","abbr","acronym","applet","b","basefont","bdo","big","br","button","cite","code","del","dfn","em","font","i","iframe","img","input","ins","kbd","label","map","noscript","object","q","s","samp","script","select","small","span","strike","strong","sub","sup","svg","textarea","tt","u","var"]),RE=new AE(["colgroup","dd","dt","li","option","p","td","tfoot","th","thead","tr","source"]),TE=new AE(["checked","compact","declare","defer","disabled","ismap","multiple","nohref","noresize","noshade","nowrap","readonly","selected"]),OE=new AE(["script","style"]),IE=new AE(["address","article","aside","base","blockquote","body","caption","col","colgroup","dd","details","dialog","div","dl","dt","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","legend","li","menuitem","meta","ol","optgroup","option","param","rp","rt","source","style","summary","tbody","td","tfoot","th","thead","title","tr","track","ul"]),kE={};function FE(e){let t=mE.source+"(?:\\s*("+function(e){return gE.concat(e.customAttrAssign||[]).map(function(e){return"(?:"+e.source+")"}).join("|")}(e)+")[ \\t\\n\\f\\r]*(?:"+_E.join("|")+"))?";if(e.customAttrSurround){const n=[];for(let r=e.customAttrSurround.length-1;r>=0;r--)n[r]="(?:("+e.customAttrSurround[r][0].source+")\\s*"+t+"\\s*("+e.customAttrSurround[r][1].source+"))";n.push("(?:"+t+")"),t="(?:"+n.join("|")+")"}return new RegExp("^\\s*"+t)}class xE{constructor(e,t){this.html=e,this.handler=t}async parse(){let e=this.html;const t=this.handler,n=[];let r;const i=FE(t);let o,a,s;for(;e;){if(o=e,r&&OE.has(r)){const n=r.toLowerCase(),i=kE[n]||(kE[n]=new RegExp("([\\s\\S]*?)</"+n+"[^>]*>","i"));e=await hE(e,i,async(e,r)=>("script"!==n&&"style"!==n&&"noscript"!==n&&(r=r.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)]]>/g,"$1")),t.chars&&await t.chars(r),"")),await p("</"+n+">",n)}else{let n,r=e.indexOf("<");if(0===r){if(/^<!--/.test(e)){const n=e.indexOf("--\x3e");if(n>=0){t.comment&&await t.comment(e.substring(4,n)),e=e.substring(n+3),a="";continue}}if(/^<!\[/.test(e)){const n=e.indexOf("]>");if(n>=0){t.comment&&await t.comment(e.substring(2,n+1),!0),e=e.substring(n+2),a="";continue}}const n=e.match(SE);if(n){t.doctype&&t.doctype(n[0]),e=e.substring(n[0].length),a="";continue}const i=e.match(yE);if(i){e=e.substring(i[0].length),await hE(i[0],yE,p),a="/"+i[1].toLowerCase();continue}const o=u(e);if(o){e=o.rest,await l(o),a=o.tagName.toLowerCase();continue}t.continueOnParseError&&(r=e.indexOf("<",1))}r>=0?(n=e.substring(0,r),e=e.substring(r)):(n=e,e="");let i=u(e);i?s=i.tagName:(i=e.match(yE),s=i?"/"+i[1]:""),t.chars&&await t.chars(n,a,s),a=""}if(e===o)throw new Error("Parse Error: "+e)}function u(e){const t=e.match(vE);if(t){const n={tagName:t[1],attrs:[]};let r,o;for(e=e.slice(t[0].length);!(r=e.match(bE))&&(o=e.match(i));)e=e.slice(o[0].length),n.attrs.push(o);if(r)return n.unarySlash=r[1],n.rest=e.slice(r[0].length),n}}async function c(e){if(f(e)>=0)return await p("",e),!0}async function l(e){const i=e.tagName;let o=e.unarySlash;if(t.html5&&("p"===r&&IE.has(i)?await p("",r):"tbody"===i?await c("thead"):"tfoot"===i&&(await c("tbody")||await c("thead")),"col"===i&&f("colgroup")<0&&(r="colgroup",n.push({tag:r,attrs:[]}),t.start&&await t.start(r,[],!1,""))),!t.html5&&!wE.has(i))for(;r&&wE.has(r);)await p("",r);RE.has(i)&&r===i&&await p("",i);const a=DE.has(i)||"html"===i&&"head"===r||!!o,s=e.attrs.map(function(e){let n,r,i,o,a,s;function u(t){return a=e[t],r=e[t+1],void 0!==r?'"':(r=e[t+2],void 0!==r?"'":(r=e[t+3],void 0===r&&TE.has(n)&&(r=n),""))}CE&&-1===e[0].indexOf('""')&&(""===e[3]&&delete e[3],""===e[4]&&delete e[4],""===e[5]&&delete e[5]);let c=1;if(t.customAttrSurround)for(let r=0,a=t.customAttrSurround.length;r<a;r++,c+=7)if(n=e[c+1],n){s=u(c+2),i=e[c],o=e[c+6];break}return!n&&(n=e[c])&&(s=u(c+1)),{name:n,value:r,customAssign:a||"=",customOpen:i||"",customClose:o||"",quote:s||""}});a||(n.push({tag:i,attrs:s}),r=i,o=""),t.start&&await t.start(i,s,a,o)}function f(e){let t;const r=e.toLowerCase();for(t=n.length-1;t>=0&&n[t].tag.toLowerCase()!==r;t--);return t}async function p(e,i){let o;if(o=i?f(i):0,o>=0){for(let r=n.length-1;r>=o;r--)t.end&&t.end(n[r].tag,n[r].attrs,r>o||!e);n.length=o,r=o&&n[o-1].tag}else"br"===i.toLowerCase()?t.start&&await t.start(i,[],!0,""):"p"===i.toLowerCase()&&(t.start&&await t.start(i,[],!1,"",!0),t.end&&t.end(i,[]))}t.partialMarkup||await p()}}class BE{sort(e,t=0){for(let n=0,r=this.keys.length;n<r;n++){const r=this.keys[n],i=r.slice(1);let o=e.indexOf(i,t);if(-1!==o){do{o!==t&&(e.splice(o,1),e.splice(t,0,i)),t++}while(-1!==(o=e.indexOf(i,t)));return this[r].sort(e,t)}}return e}}class ME{add(e){e.forEach(t=>{const n="$"+t;this[n]||(this[n]=[],this[n].processed=0),this[n].push(e)})}createSorter(){const e=new BE;return e.keys=Object.keys(this).sort((e,t)=>{const n=this[e].length,r=this[t].length;return n<r?1:n>r||e<t?-1:e>t?1:0}).filter(t=>{if(this[t].processed<this[t].length){const n=t.slice(1),r=new ME;return this[t].forEach(e=>{let t;for(;-1!==(t=e.indexOf(n));)e.splice(t,1);e.forEach(e=>{this["$"+e].processed++}),r.add(e.slice(0))}),e[t]=r.createSorter(),!0}return!1}),e}}const NE=e=>e&&e.replace(/^[ \n\r\t\f]+/,"").replace(/[ \n\r\t\f]+$/,"");function LE(e){return e&&e.replace(/[ \n\r\t\f\xA0]+/g,function(e){return"\t"===e?"\t":e.replace(/(^|\xA0+)[^\xA0]+/g,"$1 ")})}function PE(e,t,n,r,i){let o="",a="";return t.preserveLineBreaks&&(e=e.replace(/^[ \n\r\t\f]*?[\n\r][ \n\r\t\f]*/,function(){return o="\n",""}).replace(/[ \n\r\t\f]*?[\n\r][ \n\r\t\f]*$/,function(){return a="\n",""})),n&&(e=e.replace(/^[ \n\r\t\f\xA0]+/,function(e){const n=!o&&t.conservativeCollapse;return n&&"\t"===e?"\t":e.replace(/^[^\xA0]+/,"").replace(/(\xA0+)[^\xA0]+/g,"$1 ")||(n?" ":"")})),r&&(e=e.replace(/[ \n\r\t\f\xA0]+$/,function(e){const n=!a&&t.conservativeCollapse;return n&&"\t"===e?"\t":e.replace(/[^\xA0]+(\xA0+)/g," $1").replace(/[^\xA0]+$/,"")||(n?" ":"")})),i&&(e=LE(e)),o+e+a}const UE=["a","abbr","acronym","b","bdi","bdo","big","button","cite","code","del","dfn","em","font","i","img","input","ins","kbd","label","mark","math","meter","nobr","object","output","progress","q","rp","rt","rtc","ruby","s","samp","select","small","span","strike","strong","sub","sup","svg","textarea","time","tt","u","var","wbr"],VE=new Set(["a","abbr","acronym","b","big","del","em","font","i","ins","kbd","mark","nobr","rp","s","samp","small","span","strike","strong","sub","sup","time","tt","u","var"]),KE=new Set(["comment","img","input","wbr"]);function GE(e,t,n,r,i,o){let a=t&&!KE.has(t);a&&!r.collapseInlineTagWhitespace&&(a="/"===t.charAt(0)?!i.has(t.slice(1)):!o.has(t));let s=n&&!KE.has(n);return s&&!r.collapseInlineTagWhitespace&&(s="/"===n.charAt(0)?!o.has(n.slice(1)):!i.has(n)),PE(e,r,a,s,t&&n)}function HE(e,t){for(let n=e.length;n--;)if(e[n].name.toLowerCase()===t)return!0;return!1}const WE=new Set(["text/javascript","text/ecmascript","text/jscript","application/javascript","application/x-javascript","application/ecmascript","module"]),zE=new Set(["module"]);function YE(e=""){return""===(e=NE(e.split(/;/,2)[0]).toLowerCase())||WE.has(e)}function XE(e=""){return""===(e=NE(e).toLowerCase())||"text/css"===e}function QE(e,t){if("style"!==e)return!1;for(let e=0,n=t.length;e<n;e++){if("type"===t[e].name.toLowerCase())return XE(t[e].value)}return!0}const jE=new Set(["allowfullscreen","async","autofocus","autoplay","checked","compact","controls","declare","default","defaultchecked","defaultmuted","defaultselected","defer","disabled","enabled","formnovalidate","hidden","indeterminate","inert","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","pauseonexit","readonly","required","reversed","scoped","seamless","selected","sortable","truespeed","typemustmatch","visible"]),qE=new Set(["true","false"]);function ZE(e,t,n){if("link"!==e)return!1;const r=String(n).toLowerCase();for(let e=0;e<t.length;e++)if("rel"===t[e].name.toLowerCase()){if(String(t[e].value).toLowerCase().split(/\s+/).includes(r))return!0}return!1}const JE=new Set(["img","source"]);async function $E(e,t,n,r,i,o){if(function(e,t){const n=t.customEventAttributes;if(n){for(let t=n.length;t--;)if(n[t].test(e))return!0;return!1}return/^on[a-z]{3,}$/.test(e)}(t,r))return n=NE(n).replace(/^javascript:\s*/i,""),r.minifyJS(n,!0);if("class"===t)return n=NE(n),n=r.sortClassName?r.sortClassName(n):LE(n);if(function(e,t){return/^(?:a|area|link|base)$/.test(t)&&"href"===e||"img"===t&&/^(?:src|longdesc|usemap)$/.test(e)||"object"===t&&/^(?:classid|codebase|data|usemap)$/.test(e)||"q"===t&&"cite"===e||"blockquote"===t&&"cite"===e||("ins"===t||"del"===t)&&"cite"===e||"form"===t&&"action"===e||"input"===t&&("src"===e||"usemap"===e)||"head"===t&&"profile"===e||"script"===t&&("src"===e||"for"===e)}(t,e)){if(n=NE(n),ZE(e,i,"canonical"))return n;try{const e=await r.minifyURLs(n);return"string"==typeof e?e:n}catch(e){return r.log&&r.log(e),n}}else{if(function(e,t){return/^(?:a|area|object|button)$/.test(t)&&"tabindex"===e||"input"===t&&("maxlength"===e||"tabindex"===e)||"select"===t&&("size"===e||"tabindex"===e)||"textarea"===t&&/^(?:rows|cols|tabindex)$/.test(e)||"colgroup"===t&&"span"===e||"col"===t&&"span"===e||("th"===t||"td"===t)&&("rowspan"===e||"colspan"===e)}(t,e))return NE(n);if("style"===t)return(n=NE(n))&&(/;$/.test(n)&&!/&#?[0-9a-zA-Z]+;$/.test(n)&&(n=n.replace(/\s*;$/,";")),n=await r.minifyCSS(n,"inline")),n;if(function(e,t){return"srcset"===e&&JE.has(t)}(t,e))n=(await Promise.all(NE(n).split(/\s+,\s*|\s*,\s+/).map(async function(e){let t=e,n="";const i=e.match(/\s+([1-9][0-9]*w|[0-9]+(?:\.[0-9]+)?x)$/);if(i){t=t.slice(0,-i[0].length);const e=+i[1].slice(0,-1),r=i[1].slice(-1);1===e&&"x"===r||(n=" "+e+r)}try{const e=await r.minifyURLs(t);return("string"==typeof e?e:t)+n}catch(e){return r.log&&r.log(e),t+n}}))).join(", ");else if(function(e,t){if("meta"!==e)return!1;for(let e=0,n=t.length;e<n;e++)if("name"===t[e].name&&"viewport"===t[e].value)return!0}(e,i)&&"content"===t)n=n.replace(/\s+/g,"").replace(/[0-9]+\.[0-9]+/g,function(e){return(+e).toString()});else{if(function(e,t){if("meta"!==e)return!1;for(let e=0,n=t.length;e<n;e++)if("http-equiv"===t[e].name.toLowerCase()&&"content-security-policy"===t[e].value.toLowerCase())return!0}(e,i)&&"content"===t.toLowerCase())return LE(n);if(r.customAttrCollapse&&r.customAttrCollapse.test(t))n=NE(n.replace(/ ?[\n\r]+ ?/g,"").replace(/\s{2,}/g,r.conservativeCollapse?" ":""));else if("script"===e&&"type"===t)n=NE(n.replace(/\s*;\s*/g,";"));else{if(function(e,t,n){return"media"===n&&(ZE(e,t,"stylesheet")||QE(e,t))}(e,i,t))return n=NE(n),r.minifyCSS(n,"media");if("iframe"===e&&"srcdoc"===t)return function(e){return Boolean(e.collapseWhitespace||e.removeComments||e.removeOptionalTags||e.minifyJS!==Dv||e.minifyCSS!==wv||e.minifyURLs!==Dv)}(r)?o(n,r,!0):n}}}return n}function ev(e){return"/* clean-css ignore:start */"+e+"/* clean-css ignore:end */"}function tv(e,t){switch(t){case"inline":return"*{"+e+"}";case"media":return"@media "+e+"{a{top:0}}";default:return e}}const nv=new Set(["html","head","body","colgroup","tbody"]),rv=new Set(["html","head","body","li","dt","dd","p","rb","rt","rtc","rp","optgroup","option","colgroup","caption","thead","tbody","tfoot","tr","td","th"]),iv=new Set(["meta","link","script","style","template","noscript"]),ov=new Set(["dt","dd"]),av=new Set(["address","article","aside","blockquote","details","div","dl","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","main","menu","nav","ol","p","pre","section","table","ul"]),sv=new Set(["a","audio","del","ins","map","noscript","video"]),uv=new Set(["rb","rt","rtc","rp"]),cv=new Set(["rb","rtc","rp"]),lv=new Set(["option","optgroup"]),fv=new Set(["tbody","tfoot"]),pv=new Set(["thead","tbody","tfoot"]),dv=new Set(["td","th"]),hv=new Set(["html","head","body"]),Av=new Set(["html","body"]),mv=new Set(["head","colgroup","caption"]),gv=new Set(["dt","thead"]),_v=new Set(["a","abbr","acronym","address","applet","area","article","aside","audio","b","base","basefont","bdi","bdo","bgsound","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","command","content","data","datalist","dd","del","details","dfn","dialog","dir","div","dl","dt","element","em","embed","fieldset","figcaption","figure","font","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","image","img","input","ins","isindex","kbd","keygen","label","legend","li","link","listing","main","map","mark","marquee","menu","menuitem","meta","meter","multicol","nav","nobr","noembed","noframes","noscript","object","ol","optgroup","option","output","p","param","picture","plaintext","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr","xmp"]);const Ev=new RegExp("^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(?:down|up|over|move|out)|key(?:press|down|up)))$");function vv(e,t){for(let n=t.length-1;n>=0;n--)if(t[n].name===e)return!0;return!1}function bv(e){return!/^(?:script|style|pre|textarea)$/.test(e)}function yv(e){return!/^(?:pre|textarea)$/.test(e)}async function Sv(e,t,n,r){const i=r.name(e.name);let o=e.value;if(r.decodeEntities&&o&&(o=Jl(o,Ql.Strict)),!(r.removeRedundantAttributes&&function(e,t,n,r){return n=n?NE(n.toLowerCase()):"","script"===e&&"language"===t&&"javascript"===n||"form"===e&&"method"===t&&"get"===n||"input"===e&&"type"===t&&"text"===n||"script"===e&&"charset"===t&&!HE(r,"src")||"a"===e&&"name"===t&&HE(r,"id")||"area"===e&&"shape"===t&&"rect"===n}(n,i,o,t)||r.removeScriptTypeAttributes&&"script"===n&&"type"===i&&YE(o)&&!function(e=""){return e=NE(e.split(/;/,2)[0]).toLowerCase(),zE.has(e)}(o)||r.removeStyleLinkTypeAttributes&&("style"===n||"link"===n)&&"type"===i&&XE(o)||(o&&(o=await $E(n,i,o,r,t,Iv)),r.removeEmptyAttributes&&function(e,t,n,r){return!(n&&!/^\s*$/.test(n))&&("function"==typeof r.removeEmptyAttributes?r.removeEmptyAttributes(t,e):"input"===e&&"value"===t||Ev.test(t))}(n,i,o,r))))return r.decodeEntities&&o&&(o=o.replace(/&(#?[0-9a-zA-Z]+;)/g,"&$1")),{attr:e,name:i,value:o}}function Cv(e,t,n,r,i){const o=e.name;let a=e.value;const s=e.attr;let u,c,l=s.quote;if(void 0===a||n.removeAttributeQuotes&&!~a.indexOf(i)&&/^[^ \t\n\f\r"'`=<>]+$/.test(a))c=!r||t||/\/$/.test(a)?a+" ":a;else{if(!n.preventAttributesEscaping){if(void 0===n.quoteCharacter){l=(a.match(/'/g)||[]).length<(a.match(/"/g)||[]).length?"'":'"'}else l="'"===n.quoteCharacter?"'":'"';a='"'===l?a.replace(/"/g,"""):a.replace(/'/g,"'")}c=l+a+l,r||n.removeTagWhitespace||(c+=" ")}return void 0===a||n.collapseBooleanAttributes&&function(e,t){return jE.has(e)||"draggable"===e&&!qE.has(t)}(o.toLowerCase(),a.toLowerCase())?(u=o,r||(u+=" ")):u=o+s.customAssign+c,s.customOpen+u+s.customClose}function Dv(e){return e}function wv(e){return Promise.resolve(e)}const Rv=e=>{const t={name:function(e){return e.toLowerCase()},canCollapseWhitespace:bv,canTrimWhitespace:yv,html5:!0,ignoreCustomComments:[/^!/,/^\s*#/],ignoreCustomFragments:[/<%[\s\S]*?%>/,/<\?[\s\S]*?\?>/],includeAutoGeneratedTags:!0,log:Dv,minifyCSS:wv,minifyJS:Dv,minifyURLs:Dv};return Object.keys(e).forEach(function(n){const r=e[n];if("caseSensitive"===n)r&&(t.name=Dv);else if("log"===n)"function"==typeof r&&(t.log=r);else if("minifyCSS"===n&&"function"!=typeof r){if(!r)return;const e="object"==typeof r?r:{};t.minifyCSS=async function(n,r){const i=tv(n=await hE(n,/(url\s*\(\s*)(?:"([^"]*)"|'([^']*)'|([^\s)]+))(\s*\))/gi,async function(e,n,r,i,o,a){const s=null!=r?'"':null!=i?"'":"",u=r??i??o??"";try{const e=await t.minifyURLs(u);return n+s+("string"==typeof e?e:u)+s+a}catch(n){return t.log&&t.log(n),e}}),r);return new Promise(o=>{new Ll(e).minify(i,(e,i)=>{i.errors.length>0&&(i.errors.forEach(t.log),o(n));const a=function(e,t){let n;switch(t){case"inline":n=e.match(/^\*\{([\s\S]*)\}$/);break;case"media":n=e.match(/^@media ([\s\S]*?)\s*{[\s\S]*}$/)}return n?n[1]:e}(i.styles,r);o(a)})})}}else if("minifyJS"===n&&"function"!=typeof r){if(!r)return;const e="object"==typeof r?r:{};e.parse={...e.parse,bare_returns:!1},t.minifyJS=async function(n,r){const i=n.match(/^\s*<!--.*/),o=i?n.slice(i[0].length).replace(/\n\s*-->\s*$/,""):n;e.parse.bare_returns=r;try{const t=await async function(e,t){const n=dE(e,t);let r,i;do{i=n.next(await r),r=i.value}while(!i.done);return i.value}(o,e);return t.code.replace(/;$/,"")}catch(e){return t.log(e),n}}}else if("minifyURLs"===n&&"function"!=typeof r){if(!r)return;let e=r;"string"==typeof r?e={site:r}:"object"!=typeof r&&(e={}),t.minifyURLs=function(n){try{return Hf.relate(n,e)}catch(e){return t.log(e),n}}}else t[n]=r}),t};function Tv(e){let t;do{t=Math.random().toString(36).replace(/^0\.[0-9]*/,"")}while(~e.indexOf(t));return t}const Ov=new Set(["script","style"]);async function Iv(e,t,n){if(t.maxInputLength&&e.length>t.maxInputLength)throw new Error(`Input length (${e.length}) exceeds maximum allowed length (${t.maxInputLength})`);t.collapseWhitespace&&(e=PE(e,t,!0,!0));const r=[];let i,o,a="",s="",u=[];const c=[],l=[];let f="",p="";const d=[],h=[];let A,m,g;const _=t.inlineCustomElements??[],E=(Array.isArray(_)?_:Array.from(_)).map(e=>t.name(e)),v=new Set([...VE,...E]),b=new Set([...UE,...E]);e=e.replace(/<!-- htmlmin:ignore -->([\s\S]*?)<!-- htmlmin:ignore -->/g,function(n,r){if(!A){A=Tv(e);const n=new RegExp("^"+A+"([0-9]+)$");t.ignoreCustomComments?t.ignoreCustomComments=t.ignoreCustomComments.slice():t.ignoreCustomComments=[],t.ignoreCustomComments.push(n)}const i="\x3c!--"+A+d.length+"--\x3e";return d.push(r),i});const y=t.ignoreCustomFragments.map(function(e){return e.source});if(y.length){for(let e=0;e<y.length;e++)if(/[*+]/.test(y[e])){t.log("Warning: Custom fragment contains unlimited quantifiers (* or +) which may cause ReDoS vulnerability");break}const n=t.customFragmentQuantifierLimit||200,r=`\\s{0,${n}}`,i=new RegExp(r+"(?:"+y.join("|")+"){1,"+n+"}"+r,"g");e=e.replace(i,function(n){var r;m||(m=Tv(e),g=new RegExp("(\\s*)"+m+"([0-9]+)"+m+"(\\s*)","g"),t.minifyCSS&&(t.minifyCSS=(r=t.minifyCSS,function(e,t){e=e.replace(g,function(e,t,n){const r=h[+n];return r[1]+m+n+m+r[2]});const n=[];return(new Ll).minify(tv(e,t)).warnings.forEach(function(t){const r=g.exec(t);if(r){const t=m+r[2]+m;e=e.replace(t,ev(t)),n.push(t)}}),r(e,t).then(e=>(n.forEach(function(t){e=e.replace(ev(t),t)}),e))})),t.minifyJS&&(t.minifyJS=function(e){return function(t,n){return e(t.replace(g,function(e,t,n){const r=h[+n];return r[1]+m+n+m+r[2]}),n)}}(t.minifyJS)));const i=m+h.length+m;return h.push(/^(\s*)[\s\S]*?(\s*)$/.exec(n)),"\t"+i+"\t"})}function S(e,n){return t.canTrimWhitespace(e,n,yv)}function C(){let e=r.length-1;for(;e>0&&!/^<[^/!]/.test(r[e]);)e--;r.length=Math.max(0,e)}function D(){let e=r.length-1;for(;e>0&&!/^<\//.test(r[e]);)e--;r.length=Math.max(0,e)}function w(e,n){for(let i=null;e>=0&&S(i);e--){const o=r[e],a=o.match(/^<\/([\w:-]+)>$/);if(a)i=a[1];else if(/>$/.test(o)||(r[e]=GE(o,null,n,t,b,v)))break}}function R(e){let t=r.length-1;if(r.length>1){const e=r[r.length-1];/^(?:<!|$)/.test(e)&&-1===e.indexOf(A)&&t--}w(t,e)}(t.sortAttributes&&"function"!=typeof t.sortAttributes||t.sortClassName&&"function"!=typeof t.sortClassName)&&await async function(e,t,n,r){const i=t.sortAttributes&&Object.create(null),o=t.sortClassName&&new ME;function a(e){return e.map(function(e){return t.name(e.name)})}function s(e,t){return!t||-1===e.indexOf(t)}function u(e){return s(e,n)&&s(e,r)}const c=t.log;if(t.log=Dv,t.sortAttributes=!1,t.sortClassName=!1,await async function e(n){let r,s;const c=new xE(n,{start:function(e,n){i&&(i[e]||(i[e]=new ME),i[e].add(a(n).filter(u)));for(let i=0,a=n.length;i<a;i++){const a=n[i];o&&a.value&&"class"===t.name(a.name)?o.add(NE(a.value).split(/[ \t\n\f\r]+/).filter(u)):t.processScripts&&"type"===a.name.toLowerCase()&&(r=e,s=a.value)}},end:function(){r=""},chars:async function(n){t.processScripts&&Ov.has(r)&&t.processScripts.indexOf(s)>-1&&await e(n)}});await c.parse()}(await Iv(e,t)),t.log=c,i){const e=Object.create(null);for(const t in i)e[t]=i[t].createSorter();t.sortAttributes=function(t,n){const r=e[t];if(r){const e=Object.create(null),t=a(n);t.forEach(function(t,r){(e[t]||(e[t]=[])).push(n[r])}),r.sort(t).forEach(function(t,r){n[r]=e[t].shift()})}}}if(o){const e=o.createSorter();t.sortClassName=function(t){return e.sort(t.split(/[ \n\f\r]+/)).join(" ")}}}(e,t,A,m);const T=new xE(e,{partialMarkup:n,continueOnParseError:t.continueOnParseError,customAttrAssign:t.customAttrAssign,customAttrSurround:t.customAttrSurround,html5:t.html5,start:async function(e,n,d,h,A){"svg"===e.toLowerCase()&&((t=Object.create(t)).caseSensitive=!0,t.keepClosingSlash=!0,t.name=Dv),e=t.name(e),s=e,i=e,v.has(e)||(a=""),o=!1,u=n;let g=t.removeOptionalTags;if(g){const t=_v.has(e);t&&function(e,t){switch(e){case"html":case"head":return!0;case"body":return!iv.has(t);case"colgroup":return"col"===t;case"tbody":return"tr"===t}return!1}(f,e)&&C(),f="",t&&function(e,t){switch(e){case"html":case"head":case"body":case"colgroup":case"caption":return!0;case"li":case"optgroup":case"tr":return t===e;case"dt":case"dd":return ov.has(t);case"p":return av.has(t);case"rb":case"rt":case"rp":return uv.has(t);case"rtc":return cv.has(t);case"option":return lv.has(t);case"thead":case"tbody":return fv.has(t);case"tfoot":return"tbody"===t;case"td":case"th":return dv.has(t)}return!1}(p,e)&&(D(),g=!function(e,t){switch(t){case"colgroup":return"colgroup"===e;case"tbody":return pv.has(e)}return!1}(p,e)),p=""}t.collapseWhitespace&&(c.length||R(e),d||(S(e,n)&&!c.length||c.push(e),function(e,n){return t.canCollapseWhitespace(e,n,bv)}(e,n)&&!l.length||l.push(e)));const _="<"+e,E=h&&t.keepClosingSlash;r.push(_),t.sortAttributes&&t.sortAttributes(e,n);const b=[];for(let r=n.length,i=!0;--r>=0;){const o=await Sv(n[r],n,e,t);o&&(b.unshift(Cv(o,E,t,i,m)),i=!1)}b.length>0?(r.push(" "),r.push.apply(r,b)):g&&nv.has(e)&&(f=e),r.push(r.pop()+(E?"/":"")+">"),A&&!t.includeAutoGeneratedTags&&(C(),f="")},end:function(e,n,u){"svg"===e.toLowerCase()&&(t=Object.getPrototypeOf(t)),e=t.name(e),t.collapseWhitespace&&(c.length?e===c[c.length-1]&&c.pop():R("/"+e),l.length&&e===l[l.length-1]&&l.pop());let d=!1;e===s&&(s="",d=!o),t.removeOptionalTags&&(d&&hv.has(f)&&C(),f="",!_v.has(e)||!p||gv.has(p)||"p"===p&&sv.has(e)||D(),p=rv.has(e)?e:""),t.removeEmptyElements&&d&&function(e,t){switch(e){case"textarea":return!1;case"audio":case"script":case"video":if(vv("src",t))return!1;break;case"iframe":if(vv("src",t)||vv("srcdoc",t))return!1;break;case"object":if(vv("data",t))return!1;break;case"applet":if(vv("code",t))return!1}return!0}(e,n)?(C(),f="",p=""):(u&&!t.includeAutoGeneratedTags?p="":r.push("</"+e+">"),i="/"+e,b.has(e)?d&&(a+="|"):a="")},chars:async function(e,n,d){if(n=""===n?"comment":n,d=""===d?"comment":d,t.decodeEntities&&e&&!Ov.has(s)&&(e=function(e,t=Ql.Legacy){return Jl(e,t)}(e)),t.collapseWhitespace){if(!c.length){if("comment"===n){const o=r[r.length-1];if(-1===o.indexOf(A)&&(o||(n=i),r.length>1&&(!o||!t.conservativeCollapse&&/ $/.test(a)))){const t=r.length-2;r[t]=r[t].replace(/\s+$/,function(t){return e=t+e,""})}}if(n)if("/nobr"===n||"wbr"===n){if(/^\s/.test(e)){let e=r.length-1;for(;e>0&&0!==r[e].lastIndexOf("<"+n);)e--;w(e-1,"br")}}else v.has("/"===n.charAt(0)?n.slice(1):n)&&(e=PE(e,t,/(?:^|\s)$/.test(a)));!(e=n||d?GE(e,n,d,t,b,v):PE(e,t,!0,!0))&&/\s$/.test(a)&&n&&"/"===n.charAt(0)&&w(r.length-1,d)}l.length||"html"===d||n&&d||(e=PE(e,t,!1,!1,!0))}t.processScripts&&Ov.has(s)&&(e=await async function(e,t,n){for(let r=0,i=n.length;r<i;r++)if("type"===n[r].name.toLowerCase()&&t.processScripts.indexOf(n[r].value)>-1)return await Iv(e,t);return e}(e,t,u)),function(e,t){if("script"!==e)return!1;for(let e=0,n=t.length;e<n;e++)if("type"===t[e].name.toLowerCase())return YE(t[e].value);return!0}(s,u)&&(e=await t.minifyJS(e)),QE(s,u)&&(e=await t.minifyCSS(e)),t.removeOptionalTags&&e&&(("html"===f||"body"===f&&!/^\s/.test(e))&&C(),f="",(Av.has(p)||mv.has(p)&&!/^\s/.test(e))&&D(),p=""),i=/^\s*$/.test(e)?n:"comment",t.decodeEntities&&e&&!Ov.has(s)&&(e=e.replace(/&((?:Iacute|aacute|uacute|plusmn|Otilde|otilde|agrave|Agrave|Yacute|yacute|Oslash|oslash|atilde|Atilde|brvbar|ccedil|Ccedil|Ograve|curren|divide|eacute|Eacute|ograve|Oacute|egrave|Egrave|Ugrave|frac12|frac14|frac34|ugrave|oacute|iacute|Ntilde|ntilde|Uacute|middot|igrave|Igrave|iquest|Aacute|cedil|laquo|micro|iexcl|Icirc|icirc|acirc|Ucirc|Ecirc|ocirc|Ocirc|ecirc|ucirc|Aring|aring|AElig|aelig|acute|pound|raquo|Acirc|times|THORN|szlig|thorn|COPY|auml|ordf|ordm|Uuml|macr|uuml|Auml|ouml|Ouml|para|nbsp|euml|quot|QUOT|Euml|yuml|cent|sect|copy|sup1|sup2|sup3|iuml|Iuml|ETH|shy|reg|not|yen|amp|AMP|REG|uml|eth|deg|gt|GT|LT|lt)(?!;)|(?:#?[0-9a-zA-Z]+;))/g,"&$1").replace(/</g,"<")),g&&t.collapseWhitespace&&c.length&&(e=e.replace(g,function(e,t,n){return h[+n][0]})),a+=e,e&&(o=!0),r.push(e)},comment:async function(e,n){const i=n?"<!":"\x3c!--",o=n?">":"--\x3e";e=function(e){return/^\[if\s[^\]]+]|\[endif]$/.test(e)}(e)?i+await async function(e,t){return t.processConditionalComments?await hE(e,/^(\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif])$/,async function(e,n,r,i){return n+await Iv(r,t,!0)+i}):e}(e,t)+o:t.removeComments?function(e,t){for(let n=0,r=t.ignoreCustomComments.length;n<r;n++)if(t.ignoreCustomComments[n].test(e))return!0;return!1}(e,t)?"\x3c!--"+e+"--\x3e":"":i+e+o,t.removeOptionalTags&&e&&(f="",p=""),r.push(e)},doctype:function(e){r.push(t.useShortDoctype?"<!doctype"+(t.removeTagWhitespace?"":" ")+"html>":LE(e))}});return await T.parse(),t.removeOptionalTags&&(hv.has(f)&&C(),p&&!gv.has(p)&&D()),t.collapseWhitespace&&R("br"),function(e,t,n,r){let i;const o=t.maxLineLength,a=t.noNewlinesBeforeTagClose;if(o){let t="";const s=[];for(;e.length;){const i=t.length,u=e[0].indexOf("\n"),c=Boolean(e[0].match(yE)),l=a&&c;u<0?t+=r(n(e.shift())):(t+=r(n(e[0].slice(0,u))),e[0]=e[0].slice(u+1)),i>0&&t.length>o&&!l?(s.push(t.slice(0,i)),t=t.slice(i)):u>=0&&(s.push(t),t="")}t&&s.push(t),i=s.join("\n")}else i=r(n(e.join("")));return t.collapseWhitespace?PE(i,t,!0,!0):i}(r,t,g?function(e){return e.replace(g,function(e,n,r,i){let o=h[+r][0];return t.collapseWhitespace?("\t"!==n&&(o=n+o),"\t"!==i&&(o+=i),PE(o,{preserveLineBreaks:t.preserveLineBreaks,conservativeCollapse:!t.trimCustomFragments},/^[ \n\r\t\f]/.test(o),/[ \n\r\t\f]$/.test(o))):o})}:Dv,A?function(e){return e.replace(new RegExp("\x3c!--"+A+"([0-9]+)--\x3e","g"),function(e,t){return d[+t]})}:Dv)}const kv=async function(e,t){const n=Date.now();t=Rv(t||{});const r=await Iv(e,t);return t.log("minified in: "+(Date.now()-n)+"ms"),r};var Fv={minify:kv};e.default=Fv,e.minify=kv,Object.defineProperty(e,"__esModule",{value:!0})});
|
|
9
|
+
*/class AE extends Set{has(e){return super.has(e.toLowerCase())}}const mE=/([^\s"'<>/=]+)/,gE=[/=/],_E=[/"([^"]*)"+/.source,/'([^']*)'+/.source,/([^ \t\n\f\r"'`=<>]+)/.source],EE=function(){const e="A-Za-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u0131\\u0134-\\u013E\\u0141-\\u0148\\u014A-\\u017E\\u0180-\\u01C3\\u01CD-\\u01F0\\u01F4\\u01F5\\u01FA-\\u0217\\u0250-\\u02A8\\u02BB-\\u02C1\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03CE\\u03D0-\\u03D6\\u03DA\\u03DC\\u03DE\\u03E0\\u03E2-\\u03F3\\u0401-\\u040C\\u040E-\\u044F\\u0451-\\u045C\\u045E-\\u0481\\u0490-\\u04C4\\u04C7\\u04C8\\u04CB\\u04CC\\u04D0-\\u04EB\\u04EE-\\u04F5\\u04F8\\u04F9\\u0531-\\u0556\\u0559\\u0561-\\u0586\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u063A\\u0641-\\u064A\\u0671-\\u06B7\\u06BA-\\u06BE\\u06C0-\\u06CE\\u06D0-\\u06D3\\u06D5\\u06E5\\u06E6\\u0905-\\u0939\\u093D\\u0958-\\u0961\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8B\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AE0\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B36-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB5\\u0BB7-\\u0BB9\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D60\\u0D61\\u0E01-\\u0E2E\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E45\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD\\u0EAE\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0F40-\\u0F47\\u0F49-\\u0F69\\u10A0-\\u10C5\\u10D0-\\u10F6\\u1100\\u1102\\u1103\\u1105-\\u1107\\u1109\\u110B\\u110C\\u110E-\\u1112\\u113C\\u113E\\u1140\\u114C\\u114E\\u1150\\u1154\\u1155\\u1159\\u115F-\\u1161\\u1163\\u1165\\u1167\\u1169\\u116D\\u116E\\u1172\\u1173\\u1175\\u119E\\u11A8\\u11AB\\u11AE\\u11AF\\u11B7\\u11B8\\u11BA\\u11BC-\\u11C2\\u11EB\\u11F0\\u11F9\\u1E00-\\u1E9B\\u1EA0-\\u1EF9\\u1F00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2126\\u212A\\u212B\\u212E\\u2180-\\u2182\\u3007\\u3021-\\u3029\\u3041-\\u3094\\u30A1-\\u30FA\\u3105-\\u312C\\u4E00-\\u9FA5\\uAC00-\\uD7A3",t="["+e+"_]["+e+"0-9\\u0660-\\u0669\\u06F0-\\u06F9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE7-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\.\\-_\\u0300-\\u0345\\u0360\\u0361\\u0483-\\u0486\\u0591-\\u05A1\\u05A3-\\u05B9\\u05BB-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u064B-\\u0652\\u0670\\u06D6-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0901-\\u0903\\u093C\\u093E-\\u094D\\u0951-\\u0954\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A02\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A70\\u0A71\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B43\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B82\\u0B83\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C01-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C82\\u0C83\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D43\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86-\\u0F8B\\u0F90-\\u0F95\\u0F97\\u0F99-\\u0FAD\\u0FB1-\\u0FB7\\u0FB9\\u20D0-\\u20DC\\u20E1\\u302A-\\u302F\\u3099\\u309A\\xB7\\u02D0\\u02D1\\u0387\\u0640\\u0E46\\u0EC6\\u3005\\u3031-\\u3035\\u309D\\u309E\\u30FC-\\u30FE]*";return"((?:"+t+"\\:)?"+t+")"}(),vE=new RegExp("^<"+EE),bE=/^\s*(\/?)>/,yE=new RegExp("^<\\/"+EE+"[^>]*>"),SE=/^<!DOCTYPE\s?[^>]+>/i;let CE=!1;"x".replace(/x(.)?/g,function(e,t){CE=""===t});const DE=new AE(["area","base","basefont","br","col","embed","frame","hr","img","input","isindex","keygen","link","meta","param","source","track","wbr"]),wE=new AE(["a","abbr","acronym","applet","b","basefont","bdo","big","br","button","cite","code","del","dfn","em","font","i","iframe","img","input","ins","kbd","label","map","noscript","object","q","s","samp","script","select","small","span","strike","strong","sub","sup","svg","textarea","tt","u","var"]),RE=new AE(["colgroup","dd","dt","li","option","p","td","tfoot","th","thead","tr","source"]),TE=new AE(["checked","compact","declare","defer","disabled","ismap","multiple","nohref","noresize","noshade","nowrap","readonly","selected"]),OE=new AE(["script","style"]),IE=new AE(["address","article","aside","base","blockquote","body","caption","col","colgroup","dd","details","dialog","div","dl","dt","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","legend","li","menuitem","meta","ol","optgroup","option","param","rp","rt","source","style","summary","tbody","td","tfoot","th","thead","title","tr","track","ul"]),kE={};function FE(e){let t=mE.source+"(?:\\s*("+function(e){return gE.concat(e.customAttrAssign||[]).map(function(e){return"(?:"+e.source+")"}).join("|")}(e)+")[ \\t\\n\\f\\r]*(?:"+_E.join("|")+"))?";if(e.customAttrSurround){const n=[];for(let r=e.customAttrSurround.length-1;r>=0;r--)n[r]="(?:("+e.customAttrSurround[r][0].source+")\\s*"+t+"\\s*("+e.customAttrSurround[r][1].source+"))";n.push("(?:"+t+")"),t="(?:"+n.join("|")+")"}return new RegExp("^\\s*"+t)}class xE{constructor(e,t){this.html=e,this.handler=t}async parse(){let e=this.html;const t=this.handler,n=[];let r;const i=FE(t);let o,a,s;for(;e;){if(o=e,r&&OE.has(r)){const n=r.toLowerCase(),i=kE[n]||(kE[n]=new RegExp("([\\s\\S]*?)</"+n+"[^>]*>","i"));e=await hE(e,i,async(e,r)=>("script"!==n&&"style"!==n&&"noscript"!==n&&(r=r.replace(/<!--([\s\S]*?)-->/g,"$1").replace(/<!\[CDATA\[([\s\S]*?)]]>/g,"$1")),t.chars&&await t.chars(r),"")),await p("</"+n+">",n)}else{let n,r=e.indexOf("<");if(0===r){if(/^<!--/.test(e)){const n=e.indexOf("--\x3e");if(n>=0){t.comment&&await t.comment(e.substring(4,n)),e=e.substring(n+3),a="";continue}}if(/^<!\[/.test(e)){const n=e.indexOf("]>");if(n>=0){t.comment&&await t.comment(e.substring(2,n+1),!0),e=e.substring(n+2),a="";continue}}const n=e.match(SE);if(n){t.doctype&&t.doctype(n[0]),e=e.substring(n[0].length),a="";continue}const i=e.match(yE);if(i){e=e.substring(i[0].length),await hE(i[0],yE,p),a="/"+i[1].toLowerCase();continue}const o=u(e);if(o){e=o.rest,await l(o),a=o.tagName.toLowerCase();continue}t.continueOnParseError&&(r=e.indexOf("<",1))}r>=0?(n=e.substring(0,r),e=e.substring(r)):(n=e,e="");let i=u(e);i?s=i.tagName:(i=e.match(yE),s=i?"/"+i[1]:""),t.chars&&await t.chars(n,a,s),a=""}if(e===o)throw new Error("Parse Error: "+e)}function u(e){const t=e.match(vE);if(t){const n={tagName:t[1],attrs:[]};let r,o;for(e=e.slice(t[0].length);!(r=e.match(bE))&&(o=e.match(i));)e=e.slice(o[0].length),n.attrs.push(o);if(r)return n.unarySlash=r[1],n.rest=e.slice(r[0].length),n}}async function c(e){const i=function(e){let t;const r=e.toLowerCase();for(t=n.length-1;t>=0;t--){const e=n[t].tag.toLowerCase();if(e===r)return t;if("table"===e)break}return-1}(e);return i>=0&&(await async function(e){for(let r=n.length-1;r>=e;r--)t.end&&await t.end(n[r].tag,n[r].attrs,!0);n.length=e,r=e&&n[e-1].tag}(i),!0)}async function l(e){const i=e.tagName;let o=e.unarySlash;if(t.html5&&("p"===r&&IE.has(i)?await p("",r):"tbody"===i?await c("thead"):"tfoot"===i?await c("tbody")||await c("thead"):"thead"===i&&(await c("tbody")||await c("tfoot")),"col"===i&&f("colgroup")<0&&(r="colgroup",n.push({tag:r,attrs:[]}),t.start&&await t.start(r,[],!1,""))),!t.html5&&!wE.has(i))for(;r&&wE.has(r);)await p("",r);RE.has(i)&&r===i&&await p("",i);const a=DE.has(i)||"html"===i&&"head"===r||!!o,s=e.attrs.map(function(e){let n,r,i,o,a,s;function u(t){return a=e[t],r=e[t+1],void 0!==r?'"':(r=e[t+2],void 0!==r?"'":(r=e[t+3],void 0===r&&TE.has(n)&&(r=n),""))}CE&&-1===e[0].indexOf('""')&&(""===e[3]&&delete e[3],""===e[4]&&delete e[4],""===e[5]&&delete e[5]);let c=1;if(t.customAttrSurround)for(let r=0,a=t.customAttrSurround.length;r<a;r++,c+=7)if(n=e[c+1],n){s=u(c+2),i=e[c],o=e[c+6];break}return!n&&(n=e[c])&&(s=u(c+1)),{name:n,value:r,customAssign:a||"=",customOpen:i||"",customClose:o||"",quote:s||""}});a||(n.push({tag:i,attrs:s}),r=i,o=""),t.start&&await t.start(i,s,a,o)}function f(e){let t;const r=e.toLowerCase();for(t=n.length-1;t>=0&&n[t].tag.toLowerCase()!==r;t--);return t}async function p(e,i){let o;if(o=i?f(i):0,o>=0){for(let r=n.length-1;r>=o;r--)t.end&&t.end(n[r].tag,n[r].attrs,r>o||!e);n.length=o,r=o&&n[o-1].tag}else"br"===i.toLowerCase()?t.start&&await t.start(i,[],!0,""):"p"===i.toLowerCase()&&(t.start&&await t.start(i,[],!1,"",!0),t.end&&t.end(i,[]))}t.partialMarkup||await p()}}class BE{sort(e,t=0){for(let n=0,r=this.keys.length;n<r;n++){const r=this.keys[n],i=r.slice(1);let o=e.indexOf(i,t);if(-1!==o){do{o!==t&&(e.splice(o,1),e.splice(t,0,i)),t++}while(-1!==(o=e.indexOf(i,t)));return this[r].sort(e,t)}}return e}}class ME{add(e){e.forEach(t=>{const n="$"+t;this[n]||(this[n]=[],this[n].processed=0),this[n].push(e)})}createSorter(){const e=new BE;return e.keys=Object.keys(this).sort((e,t)=>{const n=this[e].length,r=this[t].length;return n<r?1:n>r||e<t?-1:e>t?1:0}).filter(t=>{if(this[t].processed<this[t].length){const n=t.slice(1),r=new ME;return this[t].forEach(e=>{let t;for(;-1!==(t=e.indexOf(n));)e.splice(t,1);e.forEach(e=>{this["$"+e].processed++}),r.add(e.slice(0))}),e[t]=r.createSorter(),!0}return!1}),e}}const NE=e=>e&&e.replace(/^[ \n\r\t\f]+/,"").replace(/[ \n\r\t\f]+$/,"");function LE(e){return e&&e.replace(/[ \n\r\t\f\xA0]+/g,function(e){return"\t"===e?"\t":e.replace(/(^|\xA0+)[^\xA0]+/g,"$1 ")})}function PE(e,t,n,r,i){let o="",a="";return t.preserveLineBreaks&&(e=e.replace(/^[ \n\r\t\f]*?[\n\r][ \n\r\t\f]*/,function(){return o="\n",""}).replace(/[ \n\r\t\f]*?[\n\r][ \n\r\t\f]*$/,function(){return a="\n",""})),n&&(e=e.replace(/^[ \n\r\t\f\xA0]+/,function(e){const n=!o&&t.conservativeCollapse;return n&&"\t"===e?"\t":e.replace(/^[^\xA0]+/,"").replace(/(\xA0+)[^\xA0]+/g,"$1 ")||(n?" ":"")})),r&&(e=e.replace(/[ \n\r\t\f\xA0]+$/,function(e){const n=!a&&t.conservativeCollapse;return n&&"\t"===e?"\t":e.replace(/[^\xA0]+(\xA0+)/g," $1").replace(/[^\xA0]+$/,"")||(n?" ":"")})),i&&(e=LE(e)),o+e+a}const UE=["a","abbr","acronym","b","bdi","bdo","big","button","cite","code","del","dfn","em","font","i","img","input","ins","kbd","label","mark","math","meter","nobr","object","output","progress","q","rb","rp","rt","rtc","ruby","s","samp","select","small","span","strike","strong","sub","sup","svg","textarea","time","tt","u","var","wbr"],VE=new Set(["a","abbr","acronym","b","big","del","em","font","i","ins","kbd","mark","nobr","s","samp","small","span","strike","strong","sub","sup","time","tt","u","var"]),KE=new Set(["comment","img","input","wbr"]);function GE(e,t,n,r,i,o){let a=t&&!KE.has(t);a&&!r.collapseInlineTagWhitespace&&(a="/"===t.charAt(0)?!i.has(t.slice(1)):!o.has(t));let s=n&&!KE.has(n);return s&&!r.collapseInlineTagWhitespace&&(s="/"===n.charAt(0)?!o.has(n.slice(1)):!i.has(n)),PE(e,r,a,s,t&&n)}function HE(e,t){for(let n=e.length;n--;)if(e[n].name.toLowerCase()===t)return!0;return!1}const WE=new Set(["text/javascript","text/ecmascript","text/jscript","application/javascript","application/x-javascript","application/ecmascript","module"]),zE=new Set(["module"]);function YE(e=""){return""===(e=NE(e.split(/;/,2)[0]).toLowerCase())||WE.has(e)}function XE(e=""){return""===(e=NE(e).toLowerCase())||"text/css"===e}function QE(e,t){if("style"!==e)return!1;for(let e=0,n=t.length;e<n;e++){if("type"===t[e].name.toLowerCase())return XE(t[e].value)}return!0}const jE=new Set(["allowfullscreen","async","autofocus","autoplay","checked","compact","controls","declare","default","defaultchecked","defaultmuted","defaultselected","defer","disabled","enabled","formnovalidate","hidden","indeterminate","inert","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","pauseonexit","readonly","required","reversed","scoped","seamless","selected","sortable","truespeed","typemustmatch","visible"]),qE=new Set(["true","false"]);function ZE(e,t,n){if("link"!==e)return!1;const r=String(n).toLowerCase();for(let e=0;e<t.length;e++)if("rel"===t[e].name.toLowerCase()){if(String(t[e].value).toLowerCase().split(/\s+/).includes(r))return!0}return!1}const JE=new Set(["img","source"]);async function $E(e,t,n,r,i,o){if(function(e,t){const n=t.customEventAttributes;if(n){for(let t=n.length;t--;)if(n[t].test(e))return!0;return!1}return/^on[a-z]{3,}$/.test(e)}(t,r))return n=NE(n).replace(/^javascript:\s*/i,""),r.minifyJS(n,!0);if("class"===t)return n=NE(n),n=r.sortClassName?r.sortClassName(n):LE(n);if(function(e,t){return/^(?:a|area|link|base)$/.test(t)&&"href"===e||"img"===t&&/^(?:src|longdesc|usemap)$/.test(e)||"object"===t&&/^(?:classid|codebase|data|usemap)$/.test(e)||"q"===t&&"cite"===e||"blockquote"===t&&"cite"===e||("ins"===t||"del"===t)&&"cite"===e||"form"===t&&"action"===e||"input"===t&&("src"===e||"usemap"===e)||"head"===t&&"profile"===e||"script"===t&&("src"===e||"for"===e)}(t,e)){if(n=NE(n),ZE(e,i,"canonical"))return n;try{const e=await r.minifyURLs(n);return"string"==typeof e?e:n}catch(e){return r.log&&r.log(e),n}}else{if(function(e,t){return/^(?:a|area|object|button)$/.test(t)&&"tabindex"===e||"input"===t&&("maxlength"===e||"tabindex"===e)||"select"===t&&("size"===e||"tabindex"===e)||"textarea"===t&&/^(?:rows|cols|tabindex)$/.test(e)||"colgroup"===t&&"span"===e||"col"===t&&"span"===e||("th"===t||"td"===t)&&("rowspan"===e||"colspan"===e)}(t,e))return NE(n);if("style"===t)return(n=NE(n))&&(/;$/.test(n)&&!/&#?[0-9a-zA-Z]+;$/.test(n)&&(n=n.replace(/\s*;$/,";")),n=await r.minifyCSS(n,"inline")),n;if(function(e,t){return"srcset"===e&&JE.has(t)}(t,e))n=(await Promise.all(NE(n).split(/\s+,\s*|\s*,\s+/).map(async function(e){let t=e,n="";const i=e.match(/\s+([1-9][0-9]*w|[0-9]+(?:\.[0-9]+)?x)$/);if(i){t=t.slice(0,-i[0].length);const e=+i[1].slice(0,-1),r=i[1].slice(-1);1===e&&"x"===r||(n=" "+e+r)}try{const e=await r.minifyURLs(t);return("string"==typeof e?e:t)+n}catch(e){return r.log&&r.log(e),t+n}}))).join(", ");else if(function(e,t){if("meta"!==e)return!1;for(let e=0,n=t.length;e<n;e++)if("name"===t[e].name&&"viewport"===t[e].value)return!0}(e,i)&&"content"===t)n=n.replace(/\s+/g,"").replace(/[0-9]+\.[0-9]+/g,function(e){return(+e).toString()});else{if(function(e,t){if("meta"!==e)return!1;for(let e=0,n=t.length;e<n;e++)if("http-equiv"===t[e].name.toLowerCase()&&"content-security-policy"===t[e].value.toLowerCase())return!0}(e,i)&&"content"===t.toLowerCase())return LE(n);if(r.customAttrCollapse&&r.customAttrCollapse.test(t))n=NE(n.replace(/ ?[\n\r]+ ?/g,"").replace(/\s{2,}/g,r.conservativeCollapse?" ":""));else if("script"===e&&"type"===t)n=NE(n.replace(/\s*;\s*/g,";"));else{if(function(e,t,n){return"media"===n&&(ZE(e,t,"stylesheet")||QE(e,t))}(e,i,t))return n=NE(n),r.minifyCSS(n,"media");if("iframe"===e&&"srcdoc"===t)return function(e){return Boolean(e.collapseWhitespace||e.removeComments||e.removeOptionalTags||e.minifyJS!==Dv||e.minifyCSS!==wv||e.minifyURLs!==Dv)}(r)?o(n,r,!0):n}}}return n}function ev(e){return"/* clean-css ignore:start */"+e+"/* clean-css ignore:end */"}function tv(e,t){switch(t){case"inline":return"*{"+e+"}";case"media":return"@media "+e+"{a{top:0}}";default:return e}}const nv=new Set(["html","head","body","colgroup","tbody"]),rv=new Set(["html","head","body","li","dt","dd","p","rb","rt","rtc","rp","optgroup","option","colgroup","caption","thead","tbody","tfoot","tr","td","th"]),iv=new Set(["meta","link","script","style","template","noscript"]),ov=new Set(["dt","dd"]),av=new Set(["address","article","aside","blockquote","details","dialog","div","dl","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","main","menu","nav","ol","p","pre","search","section","table","ul"]),sv=new Set(["a","audio","del","ins","map","noscript","video"]),uv=new Set(["rb","rt","rtc","rp"]),cv=new Set(["rb","rtc"]),lv=new Set(["option","optgroup"]),fv=new Set(["tbody","tfoot"]),pv=new Set(["thead","tbody","tfoot"]),dv=new Set(["td","th"]),hv=new Set(["html","head","body"]),Av=new Set(["html","body"]),mv=new Set(["head","colgroup","caption"]),gv=new Set(["dt","thead"]),_v=new Set(["a","abbr","acronym","address","applet","area","article","aside","audio","b","base","basefont","bdi","bdo","bgsound","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","command","content","data","datalist","dd","del","details","dfn","dialog","dir","div","dl","dt","element","em","embed","fieldset","figcaption","figure","font","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","image","img","input","ins","isindex","kbd","keygen","label","legend","li","link","listing","main","map","mark","marquee","menu","menuitem","meta","meter","multicol","nav","nobr","noembed","noframes","noscript","object","ol","optgroup","option","output","p","param","picture","plaintext","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr","xmp"]);const Ev=new RegExp("^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(?:down|up|over|move|out)|key(?:press|down|up)))$");function vv(e,t){for(let n=t.length-1;n>=0;n--)if(t[n].name===e)return!0;return!1}function bv(e){return!/^(?:script|style|pre|textarea)$/.test(e)}function yv(e){return!/^(?:pre|textarea)$/.test(e)}async function Sv(e,t,n,r){const i=r.name(e.name);let o=e.value;if(r.decodeEntities&&o&&(o=Jl(o,Ql.Strict)),!(r.removeRedundantAttributes&&function(e,t,n,r){return n=n?NE(n.toLowerCase()):"","script"===e&&"language"===t&&"javascript"===n||"form"===e&&"method"===t&&"get"===n||"input"===e&&"type"===t&&"text"===n||"script"===e&&"charset"===t&&!HE(r,"src")||"a"===e&&"name"===t&&HE(r,"id")||"area"===e&&"shape"===t&&"rect"===n}(n,i,o,t)||r.removeScriptTypeAttributes&&"script"===n&&"type"===i&&YE(o)&&!function(e=""){return e=NE(e.split(/;/,2)[0]).toLowerCase(),zE.has(e)}(o)||r.removeStyleLinkTypeAttributes&&("style"===n||"link"===n)&&"type"===i&&XE(o)||(o&&(o=await $E(n,i,o,r,t,Iv)),r.removeEmptyAttributes&&function(e,t,n,r){return!(n&&!/^\s*$/.test(n))&&("function"==typeof r.removeEmptyAttributes?r.removeEmptyAttributes(t,e):"input"===e&&"value"===t||Ev.test(t))}(n,i,o,r))))return r.decodeEntities&&o&&(o=o.replace(/&(#?[0-9a-zA-Z]+;)/g,"&$1")),{attr:e,name:i,value:o}}function Cv(e,t,n,r,i){const o=e.name;let a=e.value;const s=e.attr;let u,c,l=s.quote;if(void 0===a||n.removeAttributeQuotes&&!~a.indexOf(i)&&/^[^ \t\n\f\r"'`=<>]+$/.test(a))c=!r||t||/\/$/.test(a)?a+" ":a;else{if(!n.preventAttributesEscaping){if(void 0===n.quoteCharacter){l=(a.match(/'/g)||[]).length<(a.match(/"/g)||[]).length?"'":'"'}else l="'"===n.quoteCharacter?"'":'"';a='"'===l?a.replace(/"/g,"""):a.replace(/'/g,"'")}c=l+a+l,r||n.removeTagWhitespace||(c+=" ")}return void 0===a||n.collapseBooleanAttributes&&function(e,t){return jE.has(e)||"draggable"===e&&!qE.has(t)}(o.toLowerCase(),a.toLowerCase())?(u=o,r||(u+=" ")):u=o+s.customAssign+c,s.customOpen+u+s.customClose}function Dv(e){return e}function wv(e){return Promise.resolve(e)}const Rv=e=>{const t={name:function(e){return e.toLowerCase()},canCollapseWhitespace:bv,canTrimWhitespace:yv,html5:!0,ignoreCustomComments:[/^!/,/^\s*#/],ignoreCustomFragments:[/<%[\s\S]*?%>/,/<\?[\s\S]*?\?>/],includeAutoGeneratedTags:!0,log:Dv,minifyCSS:wv,minifyJS:Dv,minifyURLs:Dv};return Object.keys(e).forEach(function(n){const r=e[n];if("caseSensitive"===n)r&&(t.name=Dv);else if("log"===n)"function"==typeof r&&(t.log=r);else if("minifyCSS"===n&&"function"!=typeof r){if(!r)return;const e="object"==typeof r?r:{};t.minifyCSS=async function(n,r){const i=tv(n=await hE(n,/(url\s*\(\s*)(?:"([^"]*)"|'([^']*)'|([^\s)]+))(\s*\))/gi,async function(e,n,r,i,o,a){const s=null!=r?'"':null!=i?"'":"",u=r??i??o??"";try{const e=await t.minifyURLs(u);return n+s+("string"==typeof e?e:u)+s+a}catch(n){return t.log&&t.log(n),e}}),r);return new Promise(o=>{new Ll(e).minify(i,(e,i)=>{i.errors.length>0&&(i.errors.forEach(t.log),o(n));const a=function(e,t){let n;switch(t){case"inline":n=e.match(/^\*\{([\s\S]*)\}$/);break;case"media":n=e.match(/^@media ([\s\S]*?)\s*{[\s\S]*}$/)}return n?n[1]:e}(i.styles,r);o(a)})})}}else if("minifyJS"===n&&"function"!=typeof r){if(!r)return;const e="object"==typeof r?r:{};e.parse={...e.parse,bare_returns:!1},t.minifyJS=async function(n,r){const i=n.match(/^\s*<!--.*/),o=i?n.slice(i[0].length).replace(/\n\s*-->\s*$/,""):n;e.parse.bare_returns=r;try{const t=await async function(e,t){const n=dE(e,t);let r,i;do{i=n.next(await r),r=i.value}while(!i.done);return i.value}(o,e);return t.code.replace(/;$/,"")}catch(e){return t.log(e),n}}}else if("minifyURLs"===n&&"function"!=typeof r){if(!r)return;let e=r;"string"==typeof r?e={site:r}:"object"!=typeof r&&(e={}),t.minifyURLs=function(n){try{return Hf.relate(n,e)}catch(e){return t.log(e),n}}}else t[n]=r}),t};function Tv(e){let t;do{t=Math.random().toString(36).replace(/^0\.[0-9]*/,"")}while(~e.indexOf(t));return t}const Ov=new Set(["script","style"]);async function Iv(e,t,n){if(t.maxInputLength&&e.length>t.maxInputLength)throw new Error(`Input length (${e.length}) exceeds maximum allowed length (${t.maxInputLength})`);t.collapseWhitespace&&(e=PE(e,t,!0,!0));const r=[];let i,o,a="",s="",u=[];const c=[],l=[];let f="",p="";const d=[],h=[];let A,m,g;const _=t.inlineCustomElements??[],E=(Array.isArray(_)?_:Array.from(_)).map(e=>t.name(e)),v=new Set([...VE,...E]),b=new Set([...UE,...E]);e=e.replace(/<!-- htmlmin:ignore -->([\s\S]*?)<!-- htmlmin:ignore -->/g,function(n,r){if(!A){A=Tv(e);const n=new RegExp("^"+A+"([0-9]+)$");t.ignoreCustomComments?t.ignoreCustomComments=t.ignoreCustomComments.slice():t.ignoreCustomComments=[],t.ignoreCustomComments.push(n)}const i="\x3c!--"+A+d.length+"--\x3e";return d.push(r),i});const y=t.ignoreCustomFragments.map(function(e){return e.source});if(y.length){for(let e=0;e<y.length;e++)if(/[*+]/.test(y[e])){t.log("Warning: Custom fragment contains unlimited quantifiers (* or +) which may cause ReDoS vulnerability");break}const n=t.customFragmentQuantifierLimit||200,r=`\\s{0,${n}}`,i=new RegExp(r+"(?:"+y.join("|")+"){1,"+n+"}"+r,"g");e=e.replace(i,function(n){var r;m||(m=Tv(e),g=new RegExp("(\\s*)"+m+"([0-9]+)"+m+"(\\s*)","g"),t.minifyCSS&&(t.minifyCSS=(r=t.minifyCSS,function(e,t){e=e.replace(g,function(e,t,n){const r=h[+n];return r[1]+m+n+m+r[2]});const n=[];return(new Ll).minify(tv(e,t)).warnings.forEach(function(t){const r=g.exec(t);if(r){const t=m+r[2]+m;e=e.replace(t,ev(t)),n.push(t)}}),r(e,t).then(e=>(n.forEach(function(t){e=e.replace(ev(t),t)}),e))})),t.minifyJS&&(t.minifyJS=function(e){return function(t,n){return e(t.replace(g,function(e,t,n){const r=h[+n];return r[1]+m+n+m+r[2]}),n)}}(t.minifyJS)));const i=m+h.length+m;return h.push(/^(\s*)[\s\S]*?(\s*)$/.exec(n)),"\t"+i+"\t"})}function S(e,n){return t.canTrimWhitespace(e,n,yv)}function C(){let e=r.length-1;for(;e>0&&!/^<[^/!]/.test(r[e]);)e--;r.length=Math.max(0,e)}function D(){let e=r.length-1;for(;e>0&&!/^<\//.test(r[e]);)e--;r.length=Math.max(0,e)}function w(e,n){for(let i=null;e>=0&&S(i);e--){const o=r[e],a=o.match(/^<\/([\w:-]+)>$/);if(a)i=a[1];else if(/>$/.test(o)||(r[e]=GE(o,null,n,t,b,v)))break}}function R(e){let t=r.length-1;if(r.length>1){const e=r[r.length-1];/^(?:<!|$)/.test(e)&&-1===e.indexOf(A)&&t--}w(t,e)}(t.sortAttributes&&"function"!=typeof t.sortAttributes||t.sortClassName&&"function"!=typeof t.sortClassName)&&await async function(e,t,n,r){const i=t.sortAttributes&&Object.create(null),o=t.sortClassName&&new ME;function a(e){return e.map(function(e){return t.name(e.name)})}function s(e,t){return!t||-1===e.indexOf(t)}function u(e){return s(e,n)&&s(e,r)}const c=t.log;if(t.log=Dv,t.sortAttributes=!1,t.sortClassName=!1,await async function e(n){let r,s;const c=new xE(n,{start:function(e,n){i&&(i[e]||(i[e]=new ME),i[e].add(a(n).filter(u)));for(let i=0,a=n.length;i<a;i++){const a=n[i];o&&a.value&&"class"===t.name(a.name)?o.add(NE(a.value).split(/[ \t\n\f\r]+/).filter(u)):t.processScripts&&"type"===a.name.toLowerCase()&&(r=e,s=a.value)}},end:function(){r=""},chars:async function(n){t.processScripts&&Ov.has(r)&&t.processScripts.indexOf(s)>-1&&await e(n)}});await c.parse()}(await Iv(e,t)),t.log=c,i){const e=Object.create(null);for(const t in i)e[t]=i[t].createSorter();t.sortAttributes=function(t,n){const r=e[t];if(r){const e=Object.create(null),t=a(n);t.forEach(function(t,r){(e[t]||(e[t]=[])).push(n[r])}),r.sort(t).forEach(function(t,r){n[r]=e[t].shift()})}}}if(o){const e=o.createSorter();t.sortClassName=function(t){return e.sort(t.split(/[ \n\f\r]+/)).join(" ")}}}(e,t,A,m);const T=new xE(e,{partialMarkup:n,continueOnParseError:t.continueOnParseError,customAttrAssign:t.customAttrAssign,customAttrSurround:t.customAttrSurround,html5:t.html5,start:async function(e,n,d,h,A){"svg"===e.toLowerCase()&&((t=Object.create(t)).caseSensitive=!0,t.keepClosingSlash=!0,t.name=Dv),e=t.name(e),s=e,i=e,v.has(e)||(a=""),o=!1,u=n;let g=t.removeOptionalTags;if(g){const t=_v.has(e);t&&function(e,t){switch(e){case"html":case"head":return!0;case"body":return!iv.has(t);case"colgroup":return"col"===t;case"tbody":return"tr"===t}return!1}(f,e)&&C(),f="",t&&function(e,t){switch(e){case"html":case"head":case"body":case"colgroup":case"caption":return!0;case"li":case"optgroup":case"tr":return t===e;case"dt":case"dd":return ov.has(t);case"p":return av.has(t);case"rb":case"rt":case"rp":return uv.has(t);case"rtc":return cv.has(t);case"option":return lv.has(t);case"thead":case"tbody":return fv.has(t);case"tfoot":return"tbody"===t;case"td":case"th":return dv.has(t)}return!1}(p,e)&&(D(),g=!function(e,t){switch(t){case"colgroup":return"colgroup"===e;case"tbody":return pv.has(e)}return!1}(p,e)),p=""}t.collapseWhitespace&&(c.length||R(e),d||(S(e,n)&&!c.length||c.push(e),function(e,n){return t.canCollapseWhitespace(e,n,bv)}(e,n)&&!l.length||l.push(e)));const _="<"+e,E=h&&t.keepClosingSlash;r.push(_),t.sortAttributes&&t.sortAttributes(e,n);const b=[];for(let r=n.length,i=!0;--r>=0;){const o=await Sv(n[r],n,e,t);o&&(b.unshift(Cv(o,E,t,i,m)),i=!1)}b.length>0?(r.push(" "),r.push.apply(r,b)):g&&nv.has(e)&&(f=e),r.push(r.pop()+(E?"/":"")+">"),A&&!t.includeAutoGeneratedTags&&(C(),f="")},end:function(e,n,u){"svg"===e.toLowerCase()&&(t=Object.getPrototypeOf(t)),e=t.name(e),t.collapseWhitespace&&(c.length?e===c[c.length-1]&&c.pop():R("/"+e),l.length&&e===l[l.length-1]&&l.pop());let d=!1;e===s&&(s="",d=!o),t.removeOptionalTags&&(d&&hv.has(f)&&C(),f="",!_v.has(e)||!p||gv.has(p)||"p"===p&&sv.has(e)||D(),p=rv.has(e)?e:""),t.removeEmptyElements&&d&&function(e,t){switch(e){case"textarea":return!1;case"audio":case"script":case"video":if(vv("src",t))return!1;break;case"iframe":if(vv("src",t)||vv("srcdoc",t))return!1;break;case"object":if(vv("data",t))return!1;break;case"applet":if(vv("code",t))return!1}return!0}(e,n)?(C(),f="",p=""):(u&&!t.includeAutoGeneratedTags?p="":r.push("</"+e+">"),i="/"+e,b.has(e)?d&&(a+="|"):a="")},chars:async function(e,n,d){if(n=""===n?"comment":n,d=""===d?"comment":d,t.decodeEntities&&e&&!Ov.has(s)&&(e=function(e,t=Ql.Legacy){return Jl(e,t)}(e)),t.collapseWhitespace){if(!c.length){if("comment"===n){const o=r[r.length-1];if(-1===o.indexOf(A)&&(o||(n=i),r.length>1&&(!o||!t.conservativeCollapse&&/ $/.test(a)))){const t=r.length-2;r[t]=r[t].replace(/\s+$/,function(t){return e=t+e,""})}}if(n)if("/nobr"===n||"wbr"===n){if(/^\s/.test(e)){let e=r.length-1;for(;e>0&&0!==r[e].lastIndexOf("<"+n);)e--;w(e-1,"br")}}else v.has("/"===n.charAt(0)?n.slice(1):n)&&(e=PE(e,t,/(?:^|\s)$/.test(a)));!(e=n||d?GE(e,n,d,t,b,v):PE(e,t,!0,!0))&&/\s$/.test(a)&&n&&"/"===n.charAt(0)&&w(r.length-1,d)}l.length||"html"===d||n&&d||(e=PE(e,t,!1,!1,!0))}t.processScripts&&Ov.has(s)&&(e=await async function(e,t,n){for(let r=0,i=n.length;r<i;r++)if("type"===n[r].name.toLowerCase()&&t.processScripts.indexOf(n[r].value)>-1)return await Iv(e,t);return e}(e,t,u)),function(e,t){if("script"!==e)return!1;for(let e=0,n=t.length;e<n;e++)if("type"===t[e].name.toLowerCase())return YE(t[e].value);return!0}(s,u)&&(e=await t.minifyJS(e)),QE(s,u)&&(e=await t.minifyCSS(e)),t.removeOptionalTags&&e&&(("html"===f||"body"===f&&!/^\s/.test(e))&&C(),f="",(Av.has(p)||mv.has(p)&&!/^\s/.test(e))&&D(),/^\s+$/.test(e)&&t.collapseWhitespace&&!t.conservativeCollapse||(p="")),i=/^\s*$/.test(e)?n:"comment",t.decodeEntities&&e&&!Ov.has(s)&&(e=e.replace(/&((?:Iacute|aacute|uacute|plusmn|Otilde|otilde|agrave|Agrave|Yacute|yacute|Oslash|oslash|atilde|Atilde|brvbar|ccedil|Ccedil|Ograve|curren|divide|eacute|Eacute|ograve|Oacute|egrave|Egrave|Ugrave|frac12|frac14|frac34|ugrave|oacute|iacute|Ntilde|ntilde|Uacute|middot|igrave|Igrave|iquest|Aacute|cedil|laquo|micro|iexcl|Icirc|icirc|acirc|Ucirc|Ecirc|ocirc|Ocirc|ecirc|ucirc|Aring|aring|AElig|aelig|acute|pound|raquo|Acirc|times|THORN|szlig|thorn|COPY|auml|ordf|ordm|Uuml|macr|uuml|Auml|ouml|Ouml|para|nbsp|euml|quot|QUOT|Euml|yuml|cent|sect|copy|sup1|sup2|sup3|iuml|Iuml|ETH|shy|reg|not|yen|amp|AMP|REG|uml|eth|deg|gt|GT|LT|lt)(?!;)|(?:#?[0-9a-zA-Z]+;))/g,"&$1").replace(/</g,"<")),g&&t.collapseWhitespace&&c.length&&(e=e.replace(g,function(e,t,n){return h[+n][0]})),a+=e,e&&(o=!0),r.push(e)},comment:async function(e,n){const i=n?"<!":"\x3c!--",o=n?">":"--\x3e";e=function(e){return/^\[if\s[^\]]+]|\[endif]$/.test(e)}(e)?i+await async function(e,t){return t.processConditionalComments?await hE(e,/^(\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif])$/,async function(e,n,r,i){return n+await Iv(r,t,!0)+i}):e}(e,t)+o:t.removeComments?function(e,t){for(let n=0,r=t.ignoreCustomComments.length;n<r;n++)if(t.ignoreCustomComments[n].test(e))return!0;return!1}(e,t)?"\x3c!--"+e+"--\x3e":"":i+e+o,t.removeOptionalTags&&e&&(f="",p=""),r.push(e)},doctype:function(e){r.push(t.useShortDoctype?"<!doctype"+(t.removeTagWhitespace?"":" ")+"html>":LE(e))}});return await T.parse(),t.removeOptionalTags&&(hv.has(f)&&C(),p&&!gv.has(p)&&D()),t.collapseWhitespace&&R("br"),function(e,t,n,r){let i;const o=t.maxLineLength,a=t.noNewlinesBeforeTagClose;if(o){let t="";const s=[];for(;e.length;){const i=t.length,u=e[0].indexOf("\n"),c=Boolean(e[0].match(yE)),l=a&&c;u<0?t+=r(n(e.shift())):(t+=r(n(e[0].slice(0,u))),e[0]=e[0].slice(u+1)),i>0&&t.length>o&&!l?(s.push(t.slice(0,i)),t=t.slice(i)):u>=0&&(s.push(t),t="")}t&&s.push(t),i=s.join("\n")}else i=r(n(e.join("")));return t.collapseWhitespace?PE(i,t,!0,!0):i}(r,t,g?function(e){return e.replace(g,function(e,n,r,i){let o=h[+r][0];return t.collapseWhitespace?("\t"!==n&&(o=n+o),"\t"!==i&&(o+=i),PE(o,{preserveLineBreaks:t.preserveLineBreaks,conservativeCollapse:!t.trimCustomFragments},/^[ \n\r\t\f]/.test(o),/[ \n\r\t\f]$/.test(o))):o})}:Dv,A?function(e){return e.replace(new RegExp("\x3c!--"+A+"([0-9]+)--\x3e","g"),function(e,t){return d[+t]})}:Dv)}const kv=async function(e,t){const n=Date.now();t=Rv(t||{});const r=await Iv(e,t);return t.log("minified in: "+(Date.now()-n)+"ms"),r};var Fv={minify:kv};e.default=Fv,e.minify=kv,Object.defineProperty(e,"__esModule",{value:!0})});
|
package/package.json
CHANGED
|
@@ -7,22 +7,22 @@
|
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"change-case": "^4.1.2",
|
|
9
9
|
"clean-css": "~5.3.3",
|
|
10
|
-
"commander": "^14.0.
|
|
10
|
+
"commander": "^14.0.1",
|
|
11
11
|
"entities": "^7.0.0",
|
|
12
12
|
"relateurl": "^0.2.7",
|
|
13
13
|
"terser": "^5.44.0"
|
|
14
14
|
},
|
|
15
|
-
"description": "Highly configurable, well-tested, JavaScript-based HTML minifier
|
|
15
|
+
"description": "Highly configurable, well-tested, JavaScript-based HTML minifier",
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@commitlint/cli": "^
|
|
18
|
-
"@eslint/js": "^9.
|
|
19
|
-
"@jest/globals": "^30.
|
|
17
|
+
"@commitlint/cli": "^20.1.0",
|
|
18
|
+
"@eslint/js": "^9.36.0",
|
|
19
|
+
"@jest/globals": "^30.2.0",
|
|
20
20
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
21
21
|
"@rollup/plugin-json": "^6.1.0",
|
|
22
22
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
23
23
|
"@rollup/plugin-terser": "^0.4.4",
|
|
24
|
-
"eslint": "^9.
|
|
25
|
-
"jest": "^30.
|
|
24
|
+
"eslint": "^9.36.0",
|
|
25
|
+
"jest": "^30.2.0",
|
|
26
26
|
"rollup": "^4.50.0",
|
|
27
27
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
28
28
|
"vite": "^7.1.5"
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"test:watch": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --watch"
|
|
86
86
|
},
|
|
87
87
|
"type": "module",
|
|
88
|
-
"version": "2.1.
|
|
88
|
+
"version": "2.1.6"
|
|
89
89
|
}
|
package/src/htmlminifier.js
CHANGED
|
@@ -59,9 +59,9 @@ function collapseWhitespace(str, options, trimLeft, trimRight, collapseAll) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Non-empty elements that will maintain whitespace around them
|
|
62
|
-
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
62
|
+
const inlineElementsToKeepWhitespaceAround = ['a', 'abbr', 'acronym', 'b', 'bdi', 'bdo', 'big', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'mark', 'math', 'meter', 'nobr', 'object', 'output', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'time', 'tt', 'u', 'var', 'wbr'];
|
|
63
63
|
// Non-empty elements that will maintain whitespace within them
|
|
64
|
-
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', '
|
|
64
|
+
const inlineElementsToKeepWhitespaceWithin = new Set(['a', 'abbr', 'acronym', 'b', 'big', 'del', 'em', 'font', 'i', 'ins', 'kbd', 'mark', 'nobr', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'time', 'tt', 'u', 'var']);
|
|
65
65
|
// Elements that will always maintain whitespace around them
|
|
66
66
|
const inlineElementsToKeepWhitespace = new Set(['comment', 'img', 'input', 'wbr']);
|
|
67
67
|
|
|
@@ -414,19 +414,18 @@ async function processScript(text, options, currentAttrs) {
|
|
|
414
414
|
return text;
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
|
418
|
-
// with the following deviations:
|
|
417
|
+
// Tag omission rules from https://html.spec.whatwg.org/multipage/syntax.html#optional-tags with the following extensions:
|
|
419
418
|
// - retain <body> if followed by <noscript>
|
|
420
|
-
// -
|
|
419
|
+
// - <rb>, <rt>, <rtc>, <rp> follow HTML Ruby Markup Extensions draft (https://www.w3.org/TR/html-ruby-extensions/)
|
|
421
420
|
// - retain all tags which are adjacent to non-standard HTML tags
|
|
422
421
|
const optionalStartTags = new Set(['html', 'head', 'body', 'colgroup', 'tbody']);
|
|
423
422
|
const optionalEndTags = new Set(['html', 'head', 'body', 'li', 'dt', 'dd', 'p', 'rb', 'rt', 'rtc', 'rp', 'optgroup', 'option', 'colgroup', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th']);
|
|
424
423
|
const headerTags = new Set(['meta', 'link', 'script', 'style', 'template', 'noscript']);
|
|
425
424
|
const descriptionTags = new Set(['dt', 'dd']);
|
|
426
|
-
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']);
|
|
425
|
+
const pBlockTags = new Set(['address', 'article', 'aside', 'blockquote', 'details', 'dialog', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'search', 'section', 'table', 'ul']);
|
|
427
426
|
const pInlineTags = new Set(['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']);
|
|
428
|
-
const
|
|
429
|
-
const
|
|
427
|
+
const rubyEndTagOmission = new Set(['rb', 'rt', 'rtc', 'rp']); // </rb>, </rt>, </rp> can be omitted if followed by <rb>, <rt>, <rtc>, or <rp>
|
|
428
|
+
const rubyRtcEndTagOmission = new Set(['rb', 'rtc']); // </rtc> can be omitted if followed by <rb> or <rtc> (not <rt> or <rp>)
|
|
430
429
|
const optionTag = new Set(['option', 'optgroup']);
|
|
431
430
|
const tableContentTags = new Set(['tbody', 'tfoot']);
|
|
432
431
|
const tableSectionTags = new Set(['thead', 'tbody', 'tfoot']);
|
|
@@ -482,9 +481,9 @@ function canRemovePrecedingTag(optionalEndTag, tag) {
|
|
|
482
481
|
case 'rb':
|
|
483
482
|
case 'rt':
|
|
484
483
|
case 'rp':
|
|
485
|
-
return
|
|
484
|
+
return rubyEndTagOmission.has(tag);
|
|
486
485
|
case 'rtc':
|
|
487
|
-
return
|
|
486
|
+
return rubyRtcEndTagOmission.has(tag);
|
|
488
487
|
case 'option':
|
|
489
488
|
return optionTag.has(tag);
|
|
490
489
|
case 'thead':
|
|
@@ -1094,7 +1093,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1094
1093
|
let optional = options.removeOptionalTags;
|
|
1095
1094
|
if (optional) {
|
|
1096
1095
|
const htmlTag = htmlTags.has(tag);
|
|
1097
|
-
// <html> may be omitted if first thing inside is not comment
|
|
1096
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
1098
1097
|
// <head> may be omitted if first thing inside is an element
|
|
1099
1098
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
1100
1099
|
// <colgroup> may be omitted if first thing inside is <col>
|
|
@@ -1113,7 +1112,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1113
1112
|
optionalEndTag = '';
|
|
1114
1113
|
}
|
|
1115
1114
|
|
|
1116
|
-
// Set whitespace flags for nested tags (
|
|
1115
|
+
// Set whitespace flags for nested tags (e.g., <code> within a <pre>)
|
|
1117
1116
|
if (options.collapseWhitespace) {
|
|
1118
1117
|
if (!stackNoTrimWhitespace.length) {
|
|
1119
1118
|
squashTrailingWhitespace(tag);
|
|
@@ -1281,7 +1280,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1281
1280
|
text = await options.minifyCSS(text);
|
|
1282
1281
|
}
|
|
1283
1282
|
if (options.removeOptionalTags && text) {
|
|
1284
|
-
// <html> may be omitted if first thing inside is not comment
|
|
1283
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
1285
1284
|
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
|
|
1286
1285
|
if (optionalStartTag === 'html' || (optionalStartTag === 'body' && !/^\s/.test(text))) {
|
|
1287
1286
|
removeStartTag();
|
|
@@ -1292,7 +1291,10 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1292
1291
|
if (compactTags.has(optionalEndTag) || (looseTags.has(optionalEndTag) && !/^\s/.test(text))) {
|
|
1293
1292
|
removeEndTag();
|
|
1294
1293
|
}
|
|
1295
|
-
optionalEndTag
|
|
1294
|
+
// Don’t reset optionalEndTag if text is only whitespace and will be collapsed (not conservatively)
|
|
1295
|
+
if (!/^\s+$/.test(text) || !options.collapseWhitespace || options.conservativeCollapse) {
|
|
1296
|
+
optionalEndTag = '';
|
|
1297
|
+
}
|
|
1296
1298
|
}
|
|
1297
1299
|
charsPrevTag = /^\s*$/.test(text) ? prevTag : 'comment';
|
|
1298
1300
|
if (options.decodeEntities && text && !specialContentTags.has(currentTag)) {
|
|
@@ -1346,7 +1348,7 @@ async function minifyHTML(value, options, partialMarkup) {
|
|
|
1346
1348
|
await parser.parse();
|
|
1347
1349
|
|
|
1348
1350
|
if (options.removeOptionalTags) {
|
|
1349
|
-
// <html> may be omitted if first thing inside is not comment
|
|
1351
|
+
// <html> may be omitted if first thing inside is not a comment
|
|
1350
1352
|
// <head> or <body> may be omitted if empty
|
|
1351
1353
|
if (topLevelTags.has(optionalStartTag)) {
|
|
1352
1354
|
removeStartTag();
|
package/src/htmlparser.js
CHANGED
|
@@ -122,7 +122,7 @@ export class HTMLParser {
|
|
|
122
122
|
if (!lastTag || !special.has(lastTag)) {
|
|
123
123
|
let textEnd = html.indexOf('<');
|
|
124
124
|
if (textEnd === 0) {
|
|
125
|
-
// Comment
|
|
125
|
+
// Comment
|
|
126
126
|
if (/^<!--/.test(html)) {
|
|
127
127
|
const commentEnd = html.indexOf('-->');
|
|
128
128
|
|
|
@@ -150,7 +150,7 @@ export class HTMLParser {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
// Doctype
|
|
153
|
+
// Doctype
|
|
154
154
|
const doctypeMatch = html.match(doctype);
|
|
155
155
|
if (doctypeMatch) {
|
|
156
156
|
if (handler.doctype) {
|
|
@@ -161,7 +161,7 @@ export class HTMLParser {
|
|
|
161
161
|
continue;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
// End tag
|
|
164
|
+
// End tag
|
|
165
165
|
const endTagMatch = html.match(endTag);
|
|
166
166
|
if (endTagMatch) {
|
|
167
167
|
html = html.substring(endTagMatch[0].length);
|
|
@@ -170,7 +170,7 @@ export class HTMLParser {
|
|
|
170
170
|
continue;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
// Start tag
|
|
173
|
+
// Start tag
|
|
174
174
|
const startTagMatch = parseStartTag(html);
|
|
175
175
|
if (startTagMatch) {
|
|
176
176
|
html = startTagMatch.rest;
|
|
@@ -263,11 +263,41 @@ export class HTMLParser {
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
function findTagInCurrentTable(tagName) {
|
|
267
|
+
let pos;
|
|
268
|
+
const needle = tagName.toLowerCase();
|
|
269
|
+
for (pos = stack.length - 1; pos >= 0; pos--) {
|
|
270
|
+
const currentTag = stack[pos].tag.toLowerCase();
|
|
271
|
+
if (currentTag === needle) {
|
|
272
|
+
return pos;
|
|
273
|
+
}
|
|
274
|
+
// Stop searching if we hit a table boundary
|
|
275
|
+
if (currentTag === 'table') {
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return -1;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async function parseEndTagAt(pos) {
|
|
283
|
+
// Close all open elements up to pos (mirrors parseEndTag’s core branch)
|
|
284
|
+
for (let i = stack.length - 1; i >= pos; i--) {
|
|
285
|
+
if (handler.end) {
|
|
286
|
+
await handler.end(stack[i].tag, stack[i].attrs, true);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
stack.length = pos;
|
|
290
|
+
lastTag = pos && stack[pos - 1].tag;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async function closeIfFoundInCurrentTable(tagName) {
|
|
294
|
+
const pos = findTagInCurrentTable(tagName);
|
|
295
|
+
if (pos >= 0) {
|
|
296
|
+
// Close at the specific index to avoid re-searching
|
|
297
|
+
await parseEndTagAt(pos);
|
|
269
298
|
return true;
|
|
270
299
|
}
|
|
300
|
+
return false;
|
|
271
301
|
}
|
|
272
302
|
|
|
273
303
|
async function handleStartTag(match) {
|
|
@@ -278,10 +308,15 @@ export class HTMLParser {
|
|
|
278
308
|
if (lastTag === 'p' && nonPhrasing.has(tagName)) {
|
|
279
309
|
await parseEndTag('', lastTag);
|
|
280
310
|
} else if (tagName === 'tbody') {
|
|
281
|
-
await
|
|
311
|
+
await closeIfFoundInCurrentTable('thead');
|
|
282
312
|
} else if (tagName === 'tfoot') {
|
|
283
|
-
if (!await
|
|
284
|
-
await
|
|
313
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
314
|
+
await closeIfFoundInCurrentTable('thead');
|
|
315
|
+
}
|
|
316
|
+
} else if (tagName === 'thead') {
|
|
317
|
+
// If a `tbody` or `tfoot` is open in the current table, close it
|
|
318
|
+
if (!await closeIfFoundInCurrentTable('tbody')) {
|
|
319
|
+
await closeIfFoundInCurrentTable('tfoot');
|
|
285
320
|
}
|
|
286
321
|
}
|
|
287
322
|
if (tagName === 'col' && findTag('colgroup') < 0) {
|