UNPKG

891 kBJavaScriptView Raw
1/**
2 * @license Paged.js v0.4.3 | MIT | https://gitlab.coko.foundation/pagedjs/pagedjs
3 */
4
5function getBoundingClientRect(element) {
6 if (!element) {
7 return;
8 }
9 let rect;
10 if (typeof element.getBoundingClientRect !== "undefined") {
11 rect = element.getBoundingClientRect();
12 } else {
13 let range = document.createRange();
14 range.selectNode(element);
15 rect = range.getBoundingClientRect();
16 }
17 return rect;
18}
19
20function getClientRects(element) {
21 if (!element) {
22 return;
23 }
24 let rect;
25 if (typeof element.getClientRects !== "undefined") {
26 rect = element.getClientRects();
27 } else {
28 let range = document.createRange();
29 range.selectNode(element);
30 rect = range.getClientRects();
31 }
32 return rect;
33}
34
35/**
36 * Generates a UUID
37 * based on: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
38 * @returns {string} uuid
39 */
40function UUID() {
41 var d = new Date().getTime();
42 if (typeof performance !== "undefined" && typeof performance.now === "function") {
43 d += performance.now(); //use high-precision timer if available
44 }
45 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
46 var r = (d + Math.random() * 16) % 16 | 0;
47 d = Math.floor(d / 16);
48 return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16);
49 });
50}
51
52function attr(element, attributes) {
53 for (var i = 0; i < attributes.length; i++) {
54 if (element.hasAttribute(attributes[i])) {
55 return element.getAttribute(attributes[i]);
56 }
57 }
58}
59
60/* Based on by https://mths.be/cssescape v1.5.1 by @mathias | MIT license
61 * Allows # and .
62 */
63function querySelectorEscape(value) {
64 if (arguments.length == 0) {
65 throw new TypeError("`CSS.escape` requires an argument.");
66 }
67 var string = String(value);
68
69 var length = string.length;
70 var index = -1;
71 var codeUnit;
72 var result = "";
73 var firstCodeUnit = string.charCodeAt(0);
74 while (++index < length) {
75 codeUnit = string.charCodeAt(index);
76
77
78
79 // Note: there’s no need to special-case astral symbols, surrogate
80 // pairs, or lone surrogates.
81
82 // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
83 // (U+FFFD).
84 if (codeUnit == 0x0000) {
85 result += "\uFFFD";
86 continue;
87 }
88
89 if (
90 // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
91 // U+007F, […]
92 (codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
93 // If the character is the first character and is in the range [0-9]
94 // (U+0030 to U+0039), […]
95 (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
96 // If the character is the second character and is in the range [0-9]
97 // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
98 (
99 index == 1 &&
100 codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
101 firstCodeUnit == 0x002D
102 )
103 ) {
104 // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
105 result += "\\" + codeUnit.toString(16) + " ";
106 continue;
107 }
108
109 if (
110 // If the character is the first character and is a `-` (U+002D), and
111 // there is no second character, […]
112 index == 0 &&
113 length == 1 &&
114 codeUnit == 0x002D
115 ) {
116 result += "\\" + string.charAt(index);
117 continue;
118 }
119
120 // support for period character in id
121 if (codeUnit == 0x002E) {
122 if (string.charAt(0) == "#") {
123 result += "\\.";
124 continue;
125 }
126 }
127
128
129 // If the character is not handled by one of the above rules and is
130 // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
131 // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
132 // U+005A), or [a-z] (U+0061 to U+007A), […]
133 if (
134 codeUnit >= 0x0080 ||
135 codeUnit == 0x002D ||
136 codeUnit == 0x005F ||
137 codeUnit == 35 || // Allow #
138 codeUnit == 46 || // Allow .
139 codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
140 codeUnit >= 0x0041 && codeUnit <= 0x005A ||
141 codeUnit >= 0x0061 && codeUnit <= 0x007A
142 ) {
143 // the character itself
144 result += string.charAt(index);
145 continue;
146 }
147
148 // Otherwise, the escaped character.
149 // https://drafts.csswg.org/cssom/#escape-a-character
150 result += "\\" + string.charAt(index);
151
152 }
153 return result;
154}
155
156/**
157 * Creates a new pending promise and provides methods to resolve or reject it.
158 * From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible
159 * @returns {object} defered
160 */
161function defer() {
162 this.resolve = null;
163
164 this.reject = null;
165
166 this.id = UUID();
167
168 this.promise = new Promise((resolve, reject) => {
169 this.resolve = resolve;
170 this.reject = reject;
171 });
172 Object.freeze(this);
173}
174
175const requestIdleCallback = typeof window !== "undefined" && ("requestIdleCallback" in window ? window.requestIdleCallback : window.requestAnimationFrame);
176
177function CSSValueToString(obj) {
178 return obj.value + (obj.unit || "");
179}
180
181function isElement(node) {
182 return node && node.nodeType === 1;
183}
184
185function isText(node) {
186 return node && node.nodeType === 3;
187}
188
189function* walk$2(start, limiter) {
190 let node = start;
191
192 while (node) {
193
194 yield node;
195
196 if (node.childNodes.length) {
197 node = node.firstChild;
198 } else if (node.nextSibling) {
199 if (limiter && node === limiter) {
200 node = undefined;
201 break;
202 }
203 node = node.nextSibling;
204 } else {
205 while (node) {
206 node = node.parentNode;
207 if (limiter && node === limiter) {
208 node = undefined;
209 break;
210 }
211 if (node && node.nextSibling) {
212 node = node.nextSibling;
213 break;
214 }
215
216 }
217 }
218 }
219}
220
221function nodeAfter(node, limiter) {
222 if (limiter && node === limiter) {
223 return;
224 }
225 let significantNode = nextSignificantNode(node);
226 if (significantNode) {
227 return significantNode;
228 }
229 if (node.parentNode) {
230 while ((node = node.parentNode)) {
231 if (limiter && node === limiter) {
232 return;
233 }
234 significantNode = nextSignificantNode(node);
235 if (significantNode) {
236 return significantNode;
237 }
238 }
239 }
240}
241
242function nodeBefore(node, limiter) {
243 if (limiter && node === limiter) {
244 return;
245 }
246 let significantNode = previousSignificantNode(node);
247 if (significantNode) {
248 return significantNode;
249 }
250 if (node.parentNode) {
251 while ((node = node.parentNode)) {
252 if (limiter && node === limiter) {
253 return;
254 }
255 significantNode = previousSignificantNode(node);
256 if (significantNode) {
257 return significantNode;
258 }
259 }
260 }
261}
262
263function elementAfter(node, limiter) {
264 let after = nodeAfter(node, limiter);
265
266 while (after && after.nodeType !== 1) {
267 after = nodeAfter(after, limiter);
268 }
269
270 return after;
271}
272
273function elementBefore(node, limiter) {
274 let before = nodeBefore(node, limiter);
275
276 while (before && before.nodeType !== 1) {
277 before = nodeBefore(before, limiter);
278 }
279
280 return before;
281}
282
283function displayedElementAfter(node, limiter) {
284 let after = elementAfter(node, limiter);
285
286 while (after && after.dataset.undisplayed) {
287 after = elementAfter(after, limiter);
288 }
289
290 return after;
291}
292
293function displayedElementBefore(node, limiter) {
294 let before = elementBefore(node, limiter);
295
296 while (before && before.dataset.undisplayed) {
297 before = elementBefore(before, limiter);
298 }
299
300 return before;
301}
302
303function rebuildAncestors(node) {
304 let parent, ancestor;
305 let ancestors = [];
306 let added = [];
307
308 let fragment = document.createDocumentFragment();
309
310 // Handle rowspan on table
311 if (node.nodeName === "TR") {
312 let previousRow = node.previousElementSibling;
313 let previousRowDistance = 1;
314 while (previousRow) {
315 // previous row has more columns, might indicate a rowspan.
316 if (previousRow.childElementCount > node.childElementCount) {
317 const initialColumns = Array.from(node.children);
318 while (node.firstChild) {
319 node.firstChild.remove();
320 }
321 let k = 0;
322 for (let j = 0; j < previousRow.children.length; j++) {
323 let column = previousRow.children[j];
324 if (column.rowSpan && column.rowSpan > previousRowDistance) {
325 const duplicatedColumn = column.cloneNode(true);
326 // Adjust rowspan value
327 duplicatedColumn.rowSpan = column.rowSpan - previousRowDistance;
328 // Add the column to the row
329 node.appendChild(duplicatedColumn);
330 } else {
331 // Fill the gap with the initial columns (if exists)
332 const initialColumn = initialColumns[k++];
333 // The initial column can be undefined if the newly created table has less columns than the original table
334 if (initialColumn) {
335 node.appendChild(initialColumn);
336 }
337 }
338 }
339 }
340 previousRow = previousRow.previousElementSibling;
341 previousRowDistance++;
342 }
343 }
344
345 // Gather all ancestors
346 let element = node;
347 while(element.parentNode && element.parentNode.nodeType === 1) {
348 ancestors.unshift(element.parentNode);
349 element = element.parentNode;
350 }
351
352 for (var i = 0; i < ancestors.length; i++) {
353 ancestor = ancestors[i];
354 parent = ancestor.cloneNode(false);
355
356 parent.setAttribute("data-split-from", parent.getAttribute("data-ref"));
357 // ancestor.setAttribute("data-split-to", parent.getAttribute("data-ref"));
358
359 if (parent.hasAttribute("id")) {
360 let dataID = parent.getAttribute("id");
361 parent.setAttribute("data-id", dataID);
362 parent.removeAttribute("id");
363 }
364
365 // This is handled by css :not, but also tidied up here
366 if (parent.hasAttribute("data-break-before")) {
367 parent.removeAttribute("data-break-before");
368 }
369
370 if (parent.hasAttribute("data-previous-break-after")) {
371 parent.removeAttribute("data-previous-break-after");
372 }
373
374 if (added.length) {
375 let container = added[added.length-1];
376 container.appendChild(parent);
377 } else {
378 fragment.appendChild(parent);
379 }
380 added.push(parent);
381
382 // rebuild table rows
383 if (parent.nodeName === "TD" && ancestor.parentElement.contains(ancestor)) {
384 let td = ancestor;
385 let prev = parent;
386 while ((td = td.previousElementSibling)) {
387 let sib = td.cloneNode(false);
388 parent.parentElement.insertBefore(sib, prev);
389 prev = sib;
390 }
391
392 }
393 }
394
395 added = undefined;
396 return fragment;
397}
398/*
399export function split(bound, cutElement, breakAfter) {
400 let needsRemoval = [];
401 let index = indexOf(cutElement);
402
403 if (!breakAfter && index === 0) {
404 return;
405 }
406
407 if (breakAfter && index === (cutElement.parentNode.children.length - 1)) {
408 return;
409 }
410
411 // Create a fragment with rebuilt ancestors
412 let fragment = rebuildAncestors(cutElement);
413
414 // Clone cut
415 if (!breakAfter) {
416 let clone = cutElement.cloneNode(true);
417 let ref = cutElement.parentNode.getAttribute('data-ref');
418 let parent = fragment.querySelector("[data-ref='" + ref + "']");
419 parent.appendChild(clone);
420 needsRemoval.push(cutElement);
421 }
422
423 // Remove all after cut
424 let next = nodeAfter(cutElement, bound);
425 while (next) {
426 let clone = next.cloneNode(true);
427 let ref = next.parentNode.getAttribute('data-ref');
428 let parent = fragment.querySelector("[data-ref='" + ref + "']");
429 parent.appendChild(clone);
430 needsRemoval.push(next);
431 next = nodeAfter(next, bound);
432 }
433
434 // Remove originals
435 needsRemoval.forEach((node) => {
436 if (node) {
437 node.remove();
438 }
439 });
440
441 // Insert after bounds
442 bound.parentNode.insertBefore(fragment, bound.nextSibling);
443 return [bound, bound.nextSibling];
444}
445*/
446
447function needsBreakBefore(node) {
448 if( typeof node !== "undefined" &&
449 typeof node.dataset !== "undefined" &&
450 typeof node.dataset.breakBefore !== "undefined" &&
451 (node.dataset.breakBefore === "always" ||
452 node.dataset.breakBefore === "page" ||
453 node.dataset.breakBefore === "left" ||
454 node.dataset.breakBefore === "right" ||
455 node.dataset.breakBefore === "recto" ||
456 node.dataset.breakBefore === "verso")
457 ) {
458 return true;
459 }
460
461 return false;
462}
463
464function needsPreviousBreakAfter(node) {
465 if( typeof node !== "undefined" &&
466 typeof node.dataset !== "undefined" &&
467 typeof node.dataset.previousBreakAfter !== "undefined" &&
468 (node.dataset.previousBreakAfter === "always" ||
469 node.dataset.previousBreakAfter === "page" ||
470 node.dataset.previousBreakAfter === "left" ||
471 node.dataset.previousBreakAfter === "right" ||
472 node.dataset.previousBreakAfter === "recto" ||
473 node.dataset.previousBreakAfter === "verso")
474 ) {
475 return true;
476 }
477
478 return false;
479}
480
481function needsPageBreak(node, previousSignificantNode) {
482 if (typeof node === "undefined" || !previousSignificantNode || isIgnorable(node)) {
483 return false;
484 }
485 if (node.dataset && node.dataset.undisplayed) {
486 return false;
487 }
488 let previousSignificantNodePage = previousSignificantNode.dataset ? previousSignificantNode.dataset.page : undefined;
489 if (typeof previousSignificantNodePage === "undefined") {
490 const nodeWithNamedPage = getNodeWithNamedPage(previousSignificantNode);
491 if (nodeWithNamedPage) {
492 previousSignificantNodePage = nodeWithNamedPage.dataset.page;
493 }
494 }
495 let currentNodePage = node.dataset ? node.dataset.page : undefined;
496 if (typeof currentNodePage === "undefined") {
497 const nodeWithNamedPage = getNodeWithNamedPage(node, previousSignificantNode);
498 if (nodeWithNamedPage) {
499 currentNodePage = nodeWithNamedPage.dataset.page;
500 }
501 }
502 return currentNodePage !== previousSignificantNodePage;
503}
504
505function *words(node) {
506 let currentText = node.nodeValue;
507 let max = currentText.length;
508 let currentOffset = 0;
509 let currentLetter;
510
511 let range;
512 const significantWhitespaces = node.parentElement && node.parentElement.nodeName === "PRE";
513
514 while (currentOffset < max) {
515 currentLetter = currentText[currentOffset];
516 if (/^[\S\u202F\u00A0]$/.test(currentLetter) || significantWhitespaces) {
517 if (!range) {
518 range = document.createRange();
519 range.setStart(node, currentOffset);
520 }
521 } else {
522 if (range) {
523 range.setEnd(node, currentOffset);
524 yield range;
525 range = undefined;
526 }
527 }
528
529 currentOffset += 1;
530 }
531
532 if (range) {
533 range.setEnd(node, currentOffset);
534 yield range;
535 }
536}
537
538function *letters(wordRange) {
539 let currentText = wordRange.startContainer;
540 let max = currentText.length;
541 let currentOffset = wordRange.startOffset;
542 // let currentLetter;
543
544 let range;
545
546 while(currentOffset < max) {
547 // currentLetter = currentText[currentOffset];
548 range = document.createRange();
549 range.setStart(currentText, currentOffset);
550 range.setEnd(currentText, currentOffset+1);
551
552 yield range;
553
554 currentOffset += 1;
555 }
556}
557
558function isContainer(node) {
559 let container;
560
561 if (typeof node.tagName === "undefined") {
562 return true;
563 }
564
565 if (node.style && node.style.display === "none") {
566 return false;
567 }
568
569 switch (node.tagName) {
570 // Inline
571 case "A":
572 case "ABBR":
573 case "ACRONYM":
574 case "B":
575 case "BDO":
576 case "BIG":
577 case "BR":
578 case "BUTTON":
579 case "CITE":
580 case "CODE":
581 case "DFN":
582 case "EM":
583 case "I":
584 case "IMG":
585 case "INPUT":
586 case "KBD":
587 case "LABEL":
588 case "MAP":
589 case "OBJECT":
590 case "Q":
591 case "SAMP":
592 case "SCRIPT":
593 case "SELECT":
594 case "SMALL":
595 case "SPAN":
596 case "STRONG":
597 case "SUB":
598 case "SUP":
599 case "TEXTAREA":
600 case "TIME":
601 case "TT":
602 case "VAR":
603 case "P":
604 case "H1":
605 case "H2":
606 case "H3":
607 case "H4":
608 case "H5":
609 case "H6":
610 case "FIGCAPTION":
611 case "BLOCKQUOTE":
612 case "PRE":
613 case "LI":
614 case "TD":
615 case "DT":
616 case "DD":
617 case "VIDEO":
618 case "CANVAS":
619 container = false;
620 break;
621 default:
622 container = true;
623 }
624
625 return container;
626}
627
628function cloneNode(n, deep=false) {
629 return n.cloneNode(deep);
630}
631
632function findElement(node, doc, forceQuery) {
633 const ref = node.getAttribute("data-ref");
634 return findRef(ref, doc, forceQuery);
635}
636
637function findRef(ref, doc, forceQuery) {
638 if (!forceQuery && doc.indexOfRefs && doc.indexOfRefs[ref]) {
639 return doc.indexOfRefs[ref];
640 } else {
641 return doc.querySelector(`[data-ref='${ref}']`);
642 }
643}
644
645function validNode(node) {
646 if (isText(node)) {
647 return true;
648 }
649
650 if (isElement(node) && node.dataset.ref) {
651 return true;
652 }
653
654 return false;
655}
656
657function prevValidNode(node) {
658 while (!validNode(node)) {
659 if (node.previousSibling) {
660 node = node.previousSibling;
661 } else {
662 node = node.parentNode;
663 }
664
665 if (!node) {
666 break;
667 }
668 }
669
670 return node;
671}
672
673
674function indexOf$2(node) {
675 let parent = node.parentNode;
676 if (!parent) {
677 return 0;
678 }
679 return Array.prototype.indexOf.call(parent.childNodes, node);
680}
681
682function child(node, index) {
683 return node.childNodes[index];
684}
685
686function hasContent(node) {
687 if (isElement(node)) {
688 return true;
689 } else if (isText(node) &&
690 node.textContent.trim().length) {
691 return true;
692 }
693 return false;
694}
695
696function indexOfTextNode(node, parent) {
697 if (!isText(node)) {
698 return -1;
699 }
700 let nodeTextContent = node.textContent;
701 let child;
702 let index = -1;
703 for (var i = 0; i < parent.childNodes.length; i++) {
704 child = parent.childNodes[i];
705 if (child.nodeType === 3) {
706 let text = parent.childNodes[i].textContent;
707 if (text.includes(nodeTextContent)) {
708 index = i;
709 break;
710 }
711 }
712 }
713
714 return index;
715}
716
717
718/**
719 * Throughout, whitespace is defined as one of the characters
720 * "\t" TAB \u0009
721 * "\n" LF \u000A
722 * "\r" CR \u000D
723 * " " SPC \u0020
724 *
725 * This does not use Javascript's "\s" because that includes non-breaking
726 * spaces (and also some other characters).
727 */
728
729/**
730 * Determine if a node should be ignored by the iterator functions.
731 * taken from https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#Whitespace_helper_functions
732 *
733 * @param {Node} node An object implementing the DOM1 |Node| interface.
734 * @return {boolean} true if the node is:
735 * 1) A |Text| node that is all whitespace
736 * 2) A |Comment| node
737 * and otherwise false.
738 */
739function isIgnorable(node) {
740 return (node.nodeType === 8) || // A comment node
741 ((node.nodeType === 3) && isAllWhitespace(node)); // a text node, all whitespace
742}
743
744/**
745 * Determine whether a node's text content is entirely whitespace.
746 *
747 * @param {Node} node A node implementing the |CharacterData| interface (i.e., a |Text|, |Comment|, or |CDATASection| node
748 * @return {boolean} true if all of the text content of |nod| is whitespace, otherwise false.
749 */
750function isAllWhitespace(node) {
751 return !(/[^\t\n\r ]/.test(node.textContent));
752}
753
754/**
755 * Version of |previousSibling| that skips nodes that are entirely
756 * whitespace or comments. (Normally |previousSibling| is a property
757 * of all DOM nodes that gives the sibling node, the node that is
758 * a child of the same parent, that occurs immediately before the
759 * reference node.)
760 *
761 * @param {ChildNode} sib The reference node.
762 * @return {Node|null} Either:
763 * 1) The closest previous sibling to |sib| that is not ignorable according to |is_ignorable|, or
764 * 2) null if no such node exists.
765 */
766function previousSignificantNode(sib) {
767 while ((sib = sib.previousSibling)) {
768 if (!isIgnorable(sib)) return sib;
769 }
770 return null;
771}
772
773function getNodeWithNamedPage(node, limiter) {
774 if (node && node.dataset && node.dataset.page) {
775 return node;
776 }
777 if (node.parentNode) {
778 while ((node = node.parentNode)) {
779 if (limiter && node === limiter) {
780 return;
781 }
782 if (node.dataset && node.dataset.page) {
783 return node;
784 }
785 }
786 }
787 return null;
788}
789
790function breakInsideAvoidParentNode(node) {
791 while ((node = node.parentNode)) {
792 if (node && node.dataset && node.dataset.breakInside === "avoid") {
793 return node;
794 }
795 }
796 return null;
797}
798
799/**
800 * Find a parent with a given node name.
801 * @param {Node} node - initial Node
802 * @param {string} nodeName - node name (eg. "TD", "TABLE", "STRONG"...)
803 * @param {Node} limiter - go up to the parent until there's no more parent or the current node is equals to the limiter
804 * @returns {Node|undefined} - Either:
805 * 1) The closest parent for a the given node name, or
806 * 2) undefined if no such node exists.
807 */
808function parentOf(node, nodeName, limiter) {
809 if (limiter && node === limiter) {
810 return;
811 }
812 if (node.parentNode) {
813 while ((node = node.parentNode)) {
814 if (limiter && node === limiter) {
815 return;
816 }
817 if (node.nodeName === nodeName) {
818 return node;
819 }
820 }
821 }
822}
823
824/**
825 * Version of |nextSibling| that skips nodes that are entirely
826 * whitespace or comments.
827 *
828 * @param {ChildNode} sib The reference node.
829 * @return {Node|null} Either:
830 * 1) The closest next sibling to |sib| that is not ignorable according to |is_ignorable|, or
831 * 2) null if no such node exists.
832 */
833function nextSignificantNode(sib) {
834 while ((sib = sib.nextSibling)) {
835 if (!isIgnorable(sib)) return sib;
836 }
837 return null;
838}
839
840function filterTree(content, func, what) {
841 const treeWalker = document.createTreeWalker(
842 content || this.dom,
843 what || NodeFilter.SHOW_ALL,
844 func ? { acceptNode: func } : null,
845 false
846 );
847
848 let node;
849 let current;
850 node = treeWalker.nextNode();
851 while(node) {
852 current = node;
853 node = treeWalker.nextNode();
854 current.parentNode.removeChild(current);
855 }
856}
857
858/**
859 * BreakToken
860 * @class
861 */
862class BreakToken {
863
864 constructor(node, offset) {
865 this.node = node;
866 this.offset = offset;
867 }
868
869 equals(otherBreakToken) {
870 if (!otherBreakToken) {
871 return false;
872 }
873 if (this["node"] && otherBreakToken["node"] &&
874 this["node"] !== otherBreakToken["node"]) {
875 return false;
876 }
877 if (this["offset"] && otherBreakToken["offset"] &&
878 this["offset"] !== otherBreakToken["offset"]) {
879 return false;
880 }
881 return true;
882 }
883
884 toJSON(hash) {
885 let node;
886 let index = 0;
887 if (!this.node) {
888 return {};
889 }
890 if (isElement(this.node) && this.node.dataset.ref) {
891 node = this.node.dataset.ref;
892 } else if (hash) {
893 node = this.node.parentElement.dataset.ref;
894 }
895
896 if (this.node.parentElement) {
897 const children = Array.from(this.node.parentElement.childNodes);
898 index = children.indexOf(this.node);
899 }
900
901 return JSON.stringify({
902 "node": node,
903 "index" : index,
904 "offset": this.offset
905 });
906 }
907
908}
909
910/**
911 * Render result.
912 * @class
913 */
914class RenderResult {
915
916 constructor(breakToken, error) {
917 this.breakToken = breakToken;
918 this.error = error;
919 }
920}
921
922class OverflowContentError extends Error {
923 constructor(message, items) {
924 super(message);
925 this.items = items;
926 }
927}
928
929function getDefaultExportFromCjs (x) {
930 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
931}
932
933var eventEmitter = {exports: {}};
934
935var d$2 = {exports: {}};
936
937var isImplemented$6 = function () {
938 var assign = Object.assign, obj;
939 if (typeof assign !== "function") return false;
940 obj = { foo: "raz" };
941 assign(obj, { bar: "dwa" }, { trzy: "trzy" });
942 return (obj.foo + obj.bar + obj.trzy) === "razdwatrzy";
943};
944
945var isImplemented$5;
946var hasRequiredIsImplemented$1;
947
948function requireIsImplemented$1 () {
949 if (hasRequiredIsImplemented$1) return isImplemented$5;
950 hasRequiredIsImplemented$1 = 1;
951
952 isImplemented$5 = function () {
953 try {
954 Object.keys("primitive");
955 return true;
956 } catch (e) {
957 return false;
958 }
959 };
960 return isImplemented$5;
961}
962
963// eslint-disable-next-line no-empty-function
964var noop$4 = function () {};
965
966var _undefined = noop$4(); // Support ES3 engines
967
968var isValue$3 = function (val) {
969 return (val !== _undefined) && (val !== null);
970};
971
972var shim$5;
973var hasRequiredShim$5;
974
975function requireShim$5 () {
976 if (hasRequiredShim$5) return shim$5;
977 hasRequiredShim$5 = 1;
978
979 var isValue = isValue$3;
980
981 var keys = Object.keys;
982
983 shim$5 = function (object) {
984 return keys(isValue(object) ? Object(object) : object);
985 };
986 return shim$5;
987}
988
989var keys;
990var hasRequiredKeys;
991
992function requireKeys () {
993 if (hasRequiredKeys) return keys;
994 hasRequiredKeys = 1;
995
996 keys = requireIsImplemented$1()()
997 ? Object.keys
998 : requireShim$5();
999 return keys;
1000}
1001
1002var isValue$2 = isValue$3;
1003
1004var validValue = function (value) {
1005 if (!isValue$2(value)) throw new TypeError("Cannot use null or undefined");
1006 return value;
1007};
1008
1009var shim$4;
1010var hasRequiredShim$4;
1011
1012function requireShim$4 () {
1013 if (hasRequiredShim$4) return shim$4;
1014 hasRequiredShim$4 = 1;
1015
1016 var keys = requireKeys()
1017 , value = validValue
1018 , max = Math.max;
1019
1020 shim$4 = function (dest, src /*, …srcn*/) {
1021 var error, i, length = max(arguments.length, 2), assign;
1022 dest = Object(value(dest));
1023 assign = function (key) {
1024 try {
1025 dest[key] = src[key];
1026 } catch (e) {
1027 if (!error) error = e;
1028 }
1029 };
1030 for (i = 1; i < length; ++i) {
1031 src = arguments[i];
1032 keys(src).forEach(assign);
1033 }
1034 if (error !== undefined) throw error;
1035 return dest;
1036 };
1037 return shim$4;
1038}
1039
1040var assign$2 = isImplemented$6()
1041 ? Object.assign
1042 : requireShim$4();
1043
1044var isValue$1 = isValue$3;
1045
1046var forEach$1 = Array.prototype.forEach, create$5 = Object.create;
1047
1048var process = function (src, obj) {
1049 var key;
1050 for (key in src) obj[key] = src[key];
1051};
1052
1053// eslint-disable-next-line no-unused-vars
1054var normalizeOptions = function (opts1 /*, …options*/) {
1055 var result = create$5(null);
1056 forEach$1.call(arguments, function (options) {
1057 if (!isValue$1(options)) return;
1058 process(Object(options), result);
1059 });
1060 return result;
1061};
1062
1063var isCallable$1 = function (obj) {
1064 return typeof obj === "function";
1065};
1066
1067var str = "razdwatrzy";
1068
1069var isImplemented$4 = function () {
1070 if (typeof str.contains !== "function") return false;
1071 return (str.contains("dwa") === true) && (str.contains("foo") === false);
1072};
1073
1074var shim$3;
1075var hasRequiredShim$3;
1076
1077function requireShim$3 () {
1078 if (hasRequiredShim$3) return shim$3;
1079 hasRequiredShim$3 = 1;
1080
1081 var indexOf = String.prototype.indexOf;
1082
1083 shim$3 = function (searchString/*, position*/) {
1084 return indexOf.call(this, searchString, arguments[1]) > -1;
1085 };
1086 return shim$3;
1087}
1088
1089var contains$1 = isImplemented$4()
1090 ? String.prototype.contains
1091 : requireShim$3();
1092
1093var assign$1 = assign$2
1094 , normalizeOpts = normalizeOptions
1095 , isCallable = isCallable$1
1096 , contains = contains$1
1097
1098 , d$1;
1099
1100d$1 = d$2.exports = function (dscr, value/*, options*/) {
1101 var c, e, w, options, desc;
1102 if ((arguments.length < 2) || (typeof dscr !== 'string')) {
1103 options = value;
1104 value = dscr;
1105 dscr = null;
1106 } else {
1107 options = arguments[2];
1108 }
1109 if (dscr == null) {
1110 c = w = true;
1111 e = false;
1112 } else {
1113 c = contains.call(dscr, 'c');
1114 e = contains.call(dscr, 'e');
1115 w = contains.call(dscr, 'w');
1116 }
1117
1118 desc = { value: value, configurable: c, enumerable: e, writable: w };
1119 return !options ? desc : assign$1(normalizeOpts(options), desc);
1120};
1121
1122d$1.gs = function (dscr, get, set/*, options*/) {
1123 var c, e, options, desc;
1124 if (typeof dscr !== 'string') {
1125 options = set;
1126 set = get;
1127 get = dscr;
1128 dscr = null;
1129 } else {
1130 options = arguments[3];
1131 }
1132 if (get == null) {
1133 get = undefined;
1134 } else if (!isCallable(get)) {
1135 options = get;
1136 get = set = undefined;
1137 } else if (set == null) {
1138 set = undefined;
1139 } else if (!isCallable(set)) {
1140 options = set;
1141 set = undefined;
1142 }
1143 if (dscr == null) {
1144 c = true;
1145 e = false;
1146 } else {
1147 c = contains.call(dscr, 'c');
1148 e = contains.call(dscr, 'e');
1149 }
1150
1151 desc = { get: get, set: set, configurable: c, enumerable: e };
1152 return !options ? desc : assign$1(normalizeOpts(options), desc);
1153};
1154
1155var dExports = d$2.exports;
1156
1157var validCallable = function (fn) {
1158 if (typeof fn !== "function") throw new TypeError(fn + " is not a function");
1159 return fn;
1160};
1161
1162(function (module, exports) {
1163
1164 var d = dExports
1165 , callable = validCallable
1166
1167 , apply = Function.prototype.apply, call = Function.prototype.call
1168 , create = Object.create, defineProperty = Object.defineProperty
1169 , defineProperties = Object.defineProperties
1170 , hasOwnProperty = Object.prototype.hasOwnProperty
1171 , descriptor = { configurable: true, enumerable: false, writable: true }
1172
1173 , on, once, off, emit, methods, descriptors, base;
1174
1175 on = function (type, listener) {
1176 var data;
1177
1178 callable(listener);
1179
1180 if (!hasOwnProperty.call(this, '__ee__')) {
1181 data = descriptor.value = create(null);
1182 defineProperty(this, '__ee__', descriptor);
1183 descriptor.value = null;
1184 } else {
1185 data = this.__ee__;
1186 }
1187 if (!data[type]) data[type] = listener;
1188 else if (typeof data[type] === 'object') data[type].push(listener);
1189 else data[type] = [data[type], listener];
1190
1191 return this;
1192 };
1193
1194 once = function (type, listener) {
1195 var once, self;
1196
1197 callable(listener);
1198 self = this;
1199 on.call(this, type, once = function () {
1200 off.call(self, type, once);
1201 apply.call(listener, this, arguments);
1202 });
1203
1204 once.__eeOnceListener__ = listener;
1205 return this;
1206 };
1207
1208 off = function (type, listener) {
1209 var data, listeners, candidate, i;
1210
1211 callable(listener);
1212
1213 if (!hasOwnProperty.call(this, '__ee__')) return this;
1214 data = this.__ee__;
1215 if (!data[type]) return this;
1216 listeners = data[type];
1217
1218 if (typeof listeners === 'object') {
1219 for (i = 0; (candidate = listeners[i]); ++i) {
1220 if ((candidate === listener) ||
1221 (candidate.__eeOnceListener__ === listener)) {
1222 if (listeners.length === 2) data[type] = listeners[i ? 0 : 1];
1223 else listeners.splice(i, 1);
1224 }
1225 }
1226 } else {
1227 if ((listeners === listener) ||
1228 (listeners.__eeOnceListener__ === listener)) {
1229 delete data[type];
1230 }
1231 }
1232
1233 return this;
1234 };
1235
1236 emit = function (type) {
1237 var i, l, listener, listeners, args;
1238
1239 if (!hasOwnProperty.call(this, '__ee__')) return;
1240 listeners = this.__ee__[type];
1241 if (!listeners) return;
1242
1243 if (typeof listeners === 'object') {
1244 l = arguments.length;
1245 args = new Array(l - 1);
1246 for (i = 1; i < l; ++i) args[i - 1] = arguments[i];
1247
1248 listeners = listeners.slice();
1249 for (i = 0; (listener = listeners[i]); ++i) {
1250 apply.call(listener, this, args);
1251 }
1252 } else {
1253 switch (arguments.length) {
1254 case 1:
1255 call.call(listeners, this);
1256 break;
1257 case 2:
1258 call.call(listeners, this, arguments[1]);
1259 break;
1260 case 3:
1261 call.call(listeners, this, arguments[1], arguments[2]);
1262 break;
1263 default:
1264 l = arguments.length;
1265 args = new Array(l - 1);
1266 for (i = 1; i < l; ++i) {
1267 args[i - 1] = arguments[i];
1268 }
1269 apply.call(listeners, this, args);
1270 }
1271 }
1272 };
1273
1274 methods = {
1275 on: on,
1276 once: once,
1277 off: off,
1278 emit: emit
1279 };
1280
1281 descriptors = {
1282 on: d(on),
1283 once: d(once),
1284 off: d(off),
1285 emit: d(emit)
1286 };
1287
1288 base = defineProperties({}, descriptors);
1289
1290 module.exports = exports = function (o) {
1291 return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
1292 };
1293 exports.methods = methods;
1294} (eventEmitter, eventEmitter.exports));
1295
1296var eventEmitterExports = eventEmitter.exports;
1297var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventEmitterExports);
1298
1299/**
1300 * Hooks allow for injecting functions that must all complete in order before finishing
1301 * They will execute in parallel but all must finish before continuing
1302 * Functions may return a promise if they are asycn.
1303 * From epubjs/src/utils/hooks
1304 * @param {any} context scope of this
1305 * @example this.content = new Hook(this);
1306 */
1307class Hook {
1308 constructor(context){
1309 this.context = context || this;
1310 this.hooks = [];
1311 }
1312
1313 /**
1314 * Adds a function to be run before a hook completes
1315 * @example this.content.register(function(){...});
1316 * @return {undefined} void
1317 */
1318 register(){
1319 for(var i = 0; i < arguments.length; ++i) {
1320 if (typeof arguments[i] === "function") {
1321 this.hooks.push(arguments[i]);
1322 } else {
1323 // unpack array
1324 for(var j = 0; j < arguments[i].length; ++j) {
1325 this.hooks.push(arguments[i][j]);
1326 }
1327 }
1328 }
1329 }
1330
1331 /**
1332 * Triggers a hook to run all functions
1333 * @example this.content.trigger(args).then(function(){...});
1334 * @return {Promise} results
1335 */
1336 trigger(){
1337 var args = arguments;
1338 var context = this.context;
1339 var promises = [];
1340
1341 this.hooks.forEach(function(task) {
1342 var executing = task.apply(context, args);
1343
1344 if(executing && typeof executing["then"] === "function") {
1345 // Task is a function that returns a promise
1346 promises.push(executing);
1347 } else {
1348 // Otherwise Task resolves immediately, add resolved promise with result
1349 promises.push(new Promise((resolve, reject) => {
1350 resolve(executing);
1351 }));
1352 }
1353 });
1354
1355
1356 return Promise.all(promises);
1357 }
1358
1359 /**
1360 * Triggers a hook to run all functions synchronously
1361 * @example this.content.trigger(args).then(function(){...});
1362 * @return {Array} results
1363 */
1364 triggerSync(){
1365 var args = arguments;
1366 var context = this.context;
1367 var results = [];
1368
1369 this.hooks.forEach(function(task) {
1370 var executing = task.apply(context, args);
1371
1372 results.push(executing);
1373 });
1374
1375
1376 return results;
1377 }
1378
1379 // Adds a function to be run before a hook completes
1380 list(){
1381 return this.hooks;
1382 }
1383
1384 clear(){
1385 return this.hooks = [];
1386 }
1387}
1388
1389const MAX_CHARS_PER_BREAK = 1500;
1390
1391/**
1392 * Layout
1393 * @class
1394 */
1395class Layout {
1396
1397 constructor(element, hooks, options) {
1398 this.element = element;
1399
1400 this.bounds = this.element.getBoundingClientRect();
1401 this.parentBounds = this.element.offsetParent.getBoundingClientRect();
1402 let gap = parseFloat(window.getComputedStyle(this.element).columnGap);
1403
1404 if (gap) {
1405 let leftMargin = this.bounds.left - this.parentBounds.left;
1406 this.gap = gap - leftMargin;
1407 } else {
1408 this.gap = 0;
1409 }
1410
1411 if (hooks) {
1412 this.hooks = hooks;
1413 } else {
1414 this.hooks = {};
1415 this.hooks.onPageLayout = new Hook();
1416 this.hooks.layout = new Hook();
1417 this.hooks.renderNode = new Hook();
1418 this.hooks.layoutNode = new Hook();
1419 this.hooks.beforeOverflow = new Hook();
1420 this.hooks.onOverflow = new Hook();
1421 this.hooks.afterOverflowRemoved = new Hook();
1422 this.hooks.onBreakToken = new Hook();
1423 this.hooks.beforeRenderResult = new Hook();
1424 }
1425
1426 this.settings = options || {};
1427
1428 this.maxChars = this.settings.maxChars || MAX_CHARS_PER_BREAK;
1429 this.forceRenderBreak = false;
1430 }
1431
1432 async renderTo(wrapper, source, breakToken, bounds = this.bounds) {
1433 let start = this.getStart(source, breakToken);
1434 let walker = walk$2(start, source);
1435
1436 let node;
1437 let prevNode;
1438 let done;
1439 let next;
1440
1441 let hasRenderedContent = false;
1442 let newBreakToken;
1443
1444 let length = 0;
1445
1446 let prevBreakToken = breakToken || new BreakToken(start);
1447
1448 this.hooks && this.hooks.onPageLayout.trigger(wrapper, prevBreakToken, this);
1449
1450 while (!done && !newBreakToken) {
1451 next = walker.next();
1452 prevNode = node;
1453 node = next.value;
1454 done = next.done;
1455
1456 if (!node) {
1457 this.hooks && this.hooks.layout.trigger(wrapper, this);
1458
1459 let imgs = wrapper.querySelectorAll("img");
1460 if (imgs.length) {
1461 await this.waitForImages(imgs);
1462 }
1463
1464 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1465
1466 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1467 console.warn("Unable to layout item: ", prevNode);
1468 this.hooks && this.hooks.beforeRenderResult.trigger(undefined, wrapper, this);
1469 return new RenderResult(undefined, new OverflowContentError("Unable to layout item", [prevNode]));
1470 }
1471
1472 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1473
1474 this.hooks && this.hooks.beforeRenderResult.trigger(newBreakToken, wrapper, this);
1475 return new RenderResult(newBreakToken);
1476 }
1477
1478 this.hooks && this.hooks.layoutNode.trigger(node);
1479
1480 // Check if the rendered element has a break set
1481 if (hasRenderedContent && this.shouldBreak(node, start)) {
1482 this.hooks && this.hooks.layout.trigger(wrapper, this);
1483
1484 let imgs = wrapper.querySelectorAll("img");
1485 if (imgs.length) {
1486 await this.waitForImages(imgs);
1487 }
1488
1489 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1490
1491 if (!newBreakToken) {
1492 newBreakToken = this.breakAt(node);
1493 } else {
1494 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1495 }
1496
1497 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1498 console.warn("Unable to layout item: ", node);
1499 let after = newBreakToken.node && nodeAfter(newBreakToken.node);
1500 if (after) {
1501 newBreakToken = new BreakToken(after);
1502 } else {
1503 return new RenderResult(undefined, new OverflowContentError("Unable to layout item", [node]));
1504 }
1505 }
1506
1507 length = 0;
1508
1509 break;
1510 }
1511
1512 if (node.dataset && node.dataset.page) {
1513 let named = node.dataset.page;
1514 let page = this.element.closest(".pagedjs_page");
1515 page.classList.add("pagedjs_named_page");
1516 page.classList.add("pagedjs_" + named + "_page");
1517
1518 if (!node.dataset.splitFrom) {
1519 page.classList.add("pagedjs_" + named + "_first_page");
1520 }
1521 }
1522
1523 // Should the Node be a shallow or deep clone
1524 let shallow = isContainer(node);
1525
1526 let rendered = this.append(node, wrapper, breakToken, shallow);
1527
1528 length += rendered.textContent.length;
1529
1530 // Check if layout has content yet
1531 if (!hasRenderedContent) {
1532 hasRenderedContent = hasContent(node);
1533 }
1534
1535 // Skip to the next node if a deep clone was rendered
1536 if (!shallow) {
1537 walker = walk$2(nodeAfter(node, source), source);
1538 }
1539
1540 if (this.forceRenderBreak) {
1541 this.hooks && this.hooks.layout.trigger(wrapper, this);
1542
1543 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1544
1545 if (!newBreakToken) {
1546 newBreakToken = this.breakAt(node);
1547 } else {
1548 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1549 }
1550
1551 length = 0;
1552 this.forceRenderBreak = false;
1553
1554 break;
1555 }
1556
1557 // Only check x characters
1558 if (length >= this.maxChars) {
1559
1560 this.hooks && this.hooks.layout.trigger(wrapper, this);
1561
1562 let imgs = wrapper.querySelectorAll("img");
1563 if (imgs.length) {
1564 await this.waitForImages(imgs);
1565 }
1566
1567 newBreakToken = this.findBreakToken(wrapper, source, bounds, prevBreakToken);
1568
1569 if (newBreakToken) {
1570 length = 0;
1571 this.rebuildTableFromBreakToken(newBreakToken, wrapper);
1572 }
1573
1574 if (newBreakToken && newBreakToken.equals(prevBreakToken)) {
1575 console.warn("Unable to layout item: ", node);
1576 let after = newBreakToken.node && nodeAfter(newBreakToken.node);
1577 if (after) {
1578 newBreakToken = new BreakToken(after);
1579 } else {
1580 this.hooks && this.hooks.beforeRenderResult.trigger(undefined, wrapper, this);
1581 return new RenderResult(undefined, new OverflowContentError("Unable to layout item", [node]));
1582 }
1583 }
1584 }
1585
1586 }
1587
1588 this.hooks && this.hooks.beforeRenderResult.trigger(newBreakToken, wrapper, this);
1589 return new RenderResult(newBreakToken);
1590 }
1591
1592 breakAt(node, offset = 0) {
1593 let newBreakToken = new BreakToken(
1594 node,
1595 offset
1596 );
1597 let breakHooks = this.hooks.onBreakToken.triggerSync(newBreakToken, undefined, node, this);
1598 breakHooks.forEach((newToken) => {
1599 if (typeof newToken != "undefined") {
1600 newBreakToken = newToken;
1601 }
1602 });
1603
1604 return newBreakToken;
1605 }
1606
1607 shouldBreak(node, limiter) {
1608 let previousNode = nodeBefore(node, limiter);
1609 let parentNode = node.parentNode;
1610 let parentBreakBefore = needsBreakBefore(node) && parentNode && !previousNode && needsBreakBefore(parentNode);
1611 let doubleBreakBefore;
1612
1613 if (parentBreakBefore) {
1614 doubleBreakBefore = node.dataset.breakBefore === parentNode.dataset.breakBefore;
1615 }
1616
1617 return !doubleBreakBefore && needsBreakBefore(node) || needsPreviousBreakAfter(node) || needsPageBreak(node, previousNode);
1618 }
1619
1620 forceBreak() {
1621 this.forceRenderBreak = true;
1622 }
1623
1624 getStart(source, breakToken) {
1625 let start;
1626 let node = breakToken && breakToken.node;
1627
1628 if (node) {
1629 start = node;
1630 } else {
1631 start = source.firstChild;
1632 }
1633
1634 return start;
1635 }
1636
1637 append(node, dest, breakToken, shallow = true, rebuild = true) {
1638
1639 let clone = cloneNode(node, !shallow);
1640
1641 if (node.parentNode && isElement(node.parentNode)) {
1642 let parent = findElement(node.parentNode, dest);
1643 // Rebuild chain
1644 if (parent) {
1645 parent.appendChild(clone);
1646 } else if (rebuild) {
1647 let fragment = rebuildAncestors(node);
1648 parent = findElement(node.parentNode, fragment);
1649 if (!parent) {
1650 dest.appendChild(clone);
1651 } else if (breakToken && isText(breakToken.node) && breakToken.offset > 0) {
1652 clone.textContent = clone.textContent.substring(breakToken.offset);
1653 parent.appendChild(clone);
1654 } else {
1655 parent.appendChild(clone);
1656 }
1657
1658 dest.appendChild(fragment);
1659 } else {
1660 dest.appendChild(clone);
1661 }
1662
1663
1664 } else {
1665 dest.appendChild(clone);
1666 }
1667
1668 if (clone.dataset && clone.dataset.ref) {
1669 if (!dest.indexOfRefs) {
1670 dest.indexOfRefs = {};
1671 }
1672 dest.indexOfRefs[clone.dataset.ref] = clone;
1673 }
1674
1675 let nodeHooks = this.hooks.renderNode.triggerSync(clone, node, this);
1676 nodeHooks.forEach((newNode) => {
1677 if (typeof newNode != "undefined") {
1678 clone = newNode;
1679 }
1680 });
1681
1682 return clone;
1683 }
1684
1685 rebuildTableFromBreakToken(breakToken, dest) {
1686 if (!breakToken || !breakToken.node) {
1687 return;
1688 }
1689 let node = breakToken.node;
1690 let td = isElement(node) ? node.closest("td") : node.parentElement.closest("td");
1691 if (td) {
1692 let rendered = findElement(td, dest, true);
1693 if (!rendered) {
1694 return;
1695 }
1696 while ((td = td.nextElementSibling)) {
1697 this.append(td, dest, null, true);
1698 }
1699 }
1700 }
1701
1702 async waitForImages(imgs) {
1703 let results = Array.from(imgs).map(async (img) => {
1704 return this.awaitImageLoaded(img);
1705 });
1706 await Promise.all(results);
1707 }
1708
1709 async awaitImageLoaded(image) {
1710 return new Promise(resolve => {
1711 if (image.complete !== true) {
1712 image.onload = function () {
1713 let {width, height} = window.getComputedStyle(image);
1714 resolve(width, height);
1715 };
1716 image.onerror = function (e) {
1717 let {width, height} = window.getComputedStyle(image);
1718 resolve(width, height, e);
1719 };
1720 } else {
1721 let {width, height} = window.getComputedStyle(image);
1722 resolve(width, height);
1723 }
1724 });
1725 }
1726
1727 avoidBreakInside(node, limiter) {
1728 let breakNode;
1729
1730 if (node === limiter) {
1731 return;
1732 }
1733
1734 while (node.parentNode) {
1735 node = node.parentNode;
1736
1737 if (node === limiter) {
1738 break;
1739 }
1740
1741 if (window.getComputedStyle(node)["break-inside"] === "avoid") {
1742 breakNode = node;
1743 break;
1744 }
1745
1746 }
1747 return breakNode;
1748 }
1749
1750 createBreakToken(overflow, rendered, source) {
1751 let container = overflow.startContainer;
1752 let offset = overflow.startOffset;
1753 let node, renderedNode, parent, index, temp;
1754
1755 if (isElement(container)) {
1756 temp = child(container, offset);
1757
1758 if (isElement(temp)) {
1759 renderedNode = findElement(temp, rendered);
1760
1761 if (!renderedNode) {
1762 // Find closest element with data-ref
1763 let prevNode = prevValidNode(temp);
1764 if (!isElement(prevNode)) {
1765 prevNode = prevNode.parentElement;
1766 }
1767 renderedNode = findElement(prevNode, rendered);
1768 // Check if temp is the last rendered node at its level.
1769 if (!temp.nextSibling) {
1770 // We need to ensure that the previous sibling of temp is fully rendered.
1771 const renderedNodeFromSource = findElement(renderedNode, source);
1772 const walker = document.createTreeWalker(renderedNodeFromSource, NodeFilter.SHOW_ELEMENT);
1773 const lastChildOfRenderedNodeFromSource = walker.lastChild();
1774 const lastChildOfRenderedNodeMatchingFromRendered = findElement(lastChildOfRenderedNodeFromSource, rendered);
1775 // Check if we found that the last child in source
1776 if (!lastChildOfRenderedNodeMatchingFromRendered) {
1777 // Pending content to be rendered before virtual break token
1778 return;
1779 }
1780 // Otherwise we will return a break token as per below
1781 }
1782 // renderedNode is actually the last unbroken box that does not overflow.
1783 // Break Token is therefore the next sibling of renderedNode within source node.
1784 node = findElement(renderedNode, source).nextSibling;
1785 offset = 0;
1786 } else {
1787 node = findElement(renderedNode, source);
1788 offset = 0;
1789 }
1790 } else {
1791 renderedNode = findElement(container, rendered);
1792
1793 if (!renderedNode) {
1794 renderedNode = findElement(prevValidNode(container), rendered);
1795 }
1796
1797 parent = findElement(renderedNode, source);
1798 index = indexOfTextNode(temp, parent);
1799 // No seperatation for the first textNode of an element
1800 if(index === 0) {
1801 node = parent;
1802 offset = 0;
1803 } else {
1804 node = child(parent, index);
1805 offset = 0;
1806 }
1807 }
1808 } else {
1809 renderedNode = findElement(container.parentNode, rendered);
1810
1811 if (!renderedNode) {
1812 renderedNode = findElement(prevValidNode(container.parentNode), rendered);
1813 }
1814
1815 parent = findElement(renderedNode, source);
1816 index = indexOfTextNode(container, parent);
1817
1818 if (index === -1) {
1819 return;
1820 }
1821
1822 node = child(parent, index);
1823
1824 offset += node.textContent.indexOf(container.textContent);
1825 }
1826
1827 if (!node) {
1828 return;
1829 }
1830
1831 return new BreakToken(
1832 node,
1833 offset
1834 );
1835
1836 }
1837
1838 findBreakToken(rendered, source, bounds = this.bounds, prevBreakToken, extract = true) {
1839 let overflow = this.findOverflow(rendered, bounds);
1840 let breakToken, breakLetter;
1841
1842 let overflowHooks = this.hooks.onOverflow.triggerSync(overflow, rendered, bounds, this);
1843 overflowHooks.forEach((newOverflow) => {
1844 if (typeof newOverflow != "undefined") {
1845 overflow = newOverflow;
1846 }
1847 });
1848
1849 if (overflow) {
1850 breakToken = this.createBreakToken(overflow, rendered, source);
1851 // breakToken is nullable
1852 let breakHooks = this.hooks.onBreakToken.triggerSync(breakToken, overflow, rendered, this);
1853 breakHooks.forEach((newToken) => {
1854 if (typeof newToken != "undefined") {
1855 breakToken = newToken;
1856 }
1857 });
1858
1859 // Stop removal if we are in a loop
1860 if (breakToken && breakToken.equals(prevBreakToken)) {
1861 return breakToken;
1862 }
1863
1864 if (breakToken && breakToken["node"] && breakToken["offset"] && breakToken["node"].textContent) {
1865 breakLetter = breakToken["node"].textContent.charAt(breakToken["offset"]);
1866 } else {
1867 breakLetter = undefined;
1868 }
1869
1870 if (breakToken && breakToken.node && extract) {
1871 let removed = this.removeOverflow(overflow, breakLetter);
1872 this.hooks && this.hooks.afterOverflowRemoved.trigger(removed, rendered, this);
1873 }
1874
1875 }
1876 return breakToken;
1877 }
1878
1879 hasOverflow(element, bounds = this.bounds) {
1880 let constrainingElement = element && element.parentNode; // this gets the element, instead of the wrapper for the width workaround
1881 let {width, height} = element.getBoundingClientRect();
1882 let scrollWidth = constrainingElement ? constrainingElement.scrollWidth : 0;
1883 let scrollHeight = constrainingElement ? constrainingElement.scrollHeight : 0;
1884 return Math.max(Math.floor(width), scrollWidth) > Math.round(bounds.width) ||
1885 Math.max(Math.floor(height), scrollHeight) > Math.round(bounds.height);
1886 }
1887
1888 findOverflow(rendered, bounds = this.bounds, gap = this.gap) {
1889 if (!this.hasOverflow(rendered, bounds)) return;
1890
1891 let start = Math.floor(bounds.left);
1892 let end = Math.round(bounds.right + gap);
1893 let vStart = Math.round(bounds.top);
1894 let vEnd = Math.round(bounds.bottom);
1895 let range;
1896
1897 let walker = walk$2(rendered.firstChild, rendered);
1898
1899 // Find Start
1900 let next, done, node, offset, skip, breakAvoid, prev, br;
1901 while (!done) {
1902 next = walker.next();
1903 done = next.done;
1904 node = next.value;
1905 skip = false;
1906 breakAvoid = false;
1907 prev = undefined;
1908 br = undefined;
1909
1910 if (node) {
1911 let pos = getBoundingClientRect(node);
1912 let left = Math.round(pos.left);
1913 let right = Math.floor(pos.right);
1914 let top = Math.round(pos.top);
1915 let bottom = Math.floor(pos.bottom);
1916
1917 if (!range && (left >= end || top >= vEnd)) {
1918 // Check if it is a float
1919 let isFloat = false;
1920
1921 // Check if the node is inside a break-inside: avoid table cell
1922 const insideTableCell = parentOf(node, "TD", rendered);
1923 if (insideTableCell && window.getComputedStyle(insideTableCell)["break-inside"] === "avoid") {
1924 // breaking inside a table cell produces unexpected result, as a workaround, we forcibly avoid break inside in a cell.
1925 // But we take the whole row, not just the cell that is causing the break.
1926 prev = insideTableCell.parentElement;
1927 } else if (isElement(node)) {
1928 let styles = window.getComputedStyle(node);
1929 isFloat = styles.getPropertyValue("float") !== "none";
1930 skip = styles.getPropertyValue("break-inside") === "avoid";
1931 breakAvoid = node.dataset.breakBefore === "avoid" || node.dataset.previousBreakAfter === "avoid";
1932 prev = breakAvoid && nodeBefore(node, rendered);
1933 br = node.tagName === "BR" || node.tagName === "WBR";
1934 }
1935
1936 let tableRow;
1937 if (node.nodeName === "TR") {
1938 tableRow = node;
1939 } else {
1940 tableRow = parentOf(node, "TR", rendered);
1941 }
1942 if (tableRow) {
1943 // honor break-inside="avoid" in parent tbody/thead
1944 let container = tableRow.parentElement;
1945 if (["TBODY", "THEAD"].includes(container.nodeName)) {
1946 let styles = window.getComputedStyle(container);
1947 if (styles.getPropertyValue("break-inside") === "avoid") prev = container;
1948 }
1949
1950 // Check if the node is inside a row with a rowspan
1951 const table = parentOf(tableRow, "TABLE", rendered);
1952 const rowspan = table.querySelector("[colspan]");
1953 if (table && rowspan) {
1954 let columnCount = 0;
1955 for (const cell of Array.from(table.rows[0].cells)) {
1956 columnCount += parseInt(cell.getAttribute("colspan") || "1");
1957 }
1958 if (tableRow.cells.length !== columnCount) {
1959 let previousRow = tableRow.previousElementSibling;
1960 let previousRowColumnCount;
1961 while (previousRow !== null) {
1962 previousRowColumnCount = 0;
1963 for (const cell of Array.from(previousRow.cells)) {
1964 previousRowColumnCount += parseInt(cell.getAttribute("colspan") || "1");
1965 }
1966 if (previousRowColumnCount === columnCount) {
1967 break;
1968 }
1969 previousRow = previousRow.previousElementSibling;
1970 }
1971 if (previousRowColumnCount === columnCount) {
1972 prev = previousRow;
1973 }
1974 }
1975 }
1976 }
1977
1978 if (prev) {
1979 range = document.createRange();
1980 range.selectNode(prev);
1981 break;
1982 }
1983
1984 if (!br && !isFloat && isElement(node)) {
1985 range = document.createRange();
1986 range.selectNode(node);
1987 break;
1988 }
1989
1990 if (isText(node) && node.textContent.trim().length) {
1991 range = document.createRange();
1992 range.selectNode(node);
1993 break;
1994 }
1995
1996 }
1997
1998 if (!range && isText(node) &&
1999 node.textContent.trim().length &&
2000 !breakInsideAvoidParentNode(node.parentNode)) {
2001
2002 let rects = getClientRects(node);
2003 let rect;
2004 left = 0;
2005 top = 0;
2006 for (var i = 0; i != rects.length; i++) {
2007 rect = rects[i];
2008 if (rect.width > 0 && (!left || rect.left > left)) {
2009 left = rect.left;
2010 }
2011 if (rect.height > 0 && (!top || rect.top > top)) {
2012 top = rect.top;
2013 }
2014 }
2015
2016 if (left >= end || top >= vEnd) {
2017 range = document.createRange();
2018 offset = this.textBreak(node, start, end, vStart, vEnd);
2019 if (!offset) {
2020 range = undefined;
2021 } else {
2022 range.setStart(node, offset);
2023 }
2024 break;
2025 }
2026 }
2027
2028 // Skip children
2029 if (skip || (right <= end && bottom <= vEnd)) {
2030 next = nodeAfter(node, rendered);
2031 if (next) {
2032 walker = walk$2(next, rendered);
2033 }
2034
2035 }
2036
2037 }
2038 }
2039
2040 // Find End
2041 if (range) {
2042 range.setEndAfter(rendered.lastChild);
2043 return range;
2044 }
2045
2046 }
2047
2048 findEndToken(rendered, source) {
2049 if (rendered.childNodes.length === 0) {
2050 return;
2051 }
2052
2053 let lastChild = rendered.lastChild;
2054
2055 let lastNodeIndex;
2056 while (lastChild && lastChild.lastChild) {
2057 if (!validNode(lastChild)) {
2058 // Only get elements with refs
2059 lastChild = lastChild.previousSibling;
2060 } else if (!validNode(lastChild.lastChild)) {
2061 // Deal with invalid dom items
2062 lastChild = prevValidNode(lastChild.lastChild);
2063 break;
2064 } else {
2065 lastChild = lastChild.lastChild;
2066 }
2067 }
2068
2069 if (isText(lastChild)) {
2070
2071 if (lastChild.parentNode.dataset.ref) {
2072 lastNodeIndex = indexOf$2(lastChild);
2073 lastChild = lastChild.parentNode;
2074 } else {
2075 lastChild = lastChild.previousSibling;
2076 }
2077 }
2078
2079 let original = findElement(lastChild, source);
2080
2081 if (lastNodeIndex) {
2082 original = original.childNodes[lastNodeIndex];
2083 }
2084
2085 let after = nodeAfter(original);
2086
2087 return this.breakAt(after);
2088 }
2089
2090 textBreak(node, start, end, vStart, vEnd) {
2091 let wordwalker = words(node);
2092 let left = 0;
2093 let right = 0;
2094 let top = 0;
2095 let bottom = 0;
2096 let word, next, done, pos;
2097 let offset;
2098 while (!done) {
2099 next = wordwalker.next();
2100 word = next.value;
2101 done = next.done;
2102
2103 if (!word) {
2104 break;
2105 }
2106
2107 pos = getBoundingClientRect(word);
2108
2109 left = Math.floor(pos.left);
2110 right = Math.floor(pos.right);
2111 top = Math.floor(pos.top);
2112 bottom = Math.floor(pos.bottom);
2113
2114 if (left >= end || top >= vEnd) {
2115 offset = word.startOffset;
2116 break;
2117 }
2118
2119 if (right > end || bottom > vEnd) {
2120 let letterwalker = letters(word);
2121 let letter, nextLetter, doneLetter;
2122
2123 while (!doneLetter) {
2124 nextLetter = letterwalker.next();
2125 letter = nextLetter.value;
2126 doneLetter = nextLetter.done;
2127
2128 if (!letter) {
2129 break;
2130 }
2131
2132 pos = getBoundingClientRect(letter);
2133 left = Math.floor(pos.left);
2134 top = Math.floor(pos.top);
2135
2136 if (left >= end || top >= vEnd) {
2137 offset = letter.startOffset;
2138 done = true;
2139
2140 break;
2141 }
2142 }
2143 }
2144
2145 }
2146
2147 return offset;
2148 }
2149
2150 removeOverflow(overflow, breakLetter) {
2151 let {startContainer} = overflow;
2152 let extracted = overflow.extractContents();
2153
2154 this.hyphenateAtBreak(startContainer, breakLetter);
2155
2156 return extracted;
2157 }
2158
2159 hyphenateAtBreak(startContainer, breakLetter) {
2160 if (isText(startContainer)) {
2161 let startText = startContainer.textContent;
2162 let prevLetter = startText[startText.length - 1];
2163
2164 // Add a hyphen if previous character is a letter or soft hyphen
2165 if (
2166 (breakLetter && /^\w|\u00AD$/.test(prevLetter) && /^\w|\u00AD$/.test(breakLetter)) ||
2167 (!breakLetter && /^\w|\u00AD$/.test(prevLetter))
2168 ) {
2169 startContainer.parentNode.classList.add("pagedjs_hyphen");
2170 startContainer.textContent += this.settings.hyphenGlyph || "\u2011";
2171 }
2172 }
2173 }
2174
2175 equalTokens(a, b) {
2176 if (!a || !b) {
2177 return false;
2178 }
2179 if (a["node"] && b["node"] && a["node"] !== b["node"]) {
2180 return false;
2181 }
2182 if (a["offset"] && b["offset"] && a["offset"] !== b["offset"]) {
2183 return false;
2184 }
2185 return true;
2186 }
2187}
2188
2189EventEmitter(Layout.prototype);
2190
2191/**
2192 * Render a page
2193 * @class
2194 */
2195class Page {
2196 constructor(pagesArea, pageTemplate, blank, hooks, options) {
2197 this.pagesArea = pagesArea;
2198 this.pageTemplate = pageTemplate;
2199 this.blank = blank;
2200
2201 this.width = undefined;
2202 this.height = undefined;
2203
2204 this.hooks = hooks;
2205
2206 this.settings = options || {};
2207
2208 // this.element = this.create(this.pageTemplate);
2209 }
2210
2211 create(template, after) {
2212 //let documentFragment = document.createRange().createContextualFragment( TEMPLATE );
2213 //let page = documentFragment.children[0];
2214 let clone = document.importNode(this.pageTemplate.content, true);
2215
2216 let page, index;
2217 if (after) {
2218 this.pagesArea.insertBefore(clone, after.nextElementSibling);
2219 index = Array.prototype.indexOf.call(this.pagesArea.children, after.nextElementSibling);
2220 page = this.pagesArea.children[index];
2221 } else {
2222 this.pagesArea.appendChild(clone);
2223 page = this.pagesArea.lastChild;
2224 }
2225
2226 let pagebox = page.querySelector(".pagedjs_pagebox");
2227 let area = page.querySelector(".pagedjs_page_content");
2228 let footnotesArea = page.querySelector(".pagedjs_footnote_area");
2229
2230
2231 let size = area.getBoundingClientRect();
2232
2233
2234 area.style.columnWidth = Math.round(size.width) + "px";
2235 area.style.columnGap = "calc(var(--pagedjs-margin-right) + var(--pagedjs-margin-left) + var(--pagedjs-bleed-right) + var(--pagedjs-bleed-left) + var(--pagedjs-column-gap-offset))";
2236 // area.style.overflow = "scroll";
2237
2238 this.width = Math.round(size.width);
2239 this.height = Math.round(size.height);
2240
2241 this.element = page;
2242 this.pagebox = pagebox;
2243 this.area = area;
2244 this.footnotesArea = footnotesArea;
2245
2246 return page;
2247 }
2248
2249 createWrapper() {
2250 let wrapper = document.createElement("div");
2251
2252 this.area.appendChild(wrapper);
2253
2254 this.wrapper = wrapper;
2255
2256 return wrapper;
2257 }
2258
2259 index(pgnum) {
2260 this.position = pgnum;
2261
2262 let page = this.element;
2263 // let pagebox = this.pagebox;
2264
2265 let index = pgnum + 1;
2266
2267 let id = `page-${index}`;
2268
2269 this.id = id;
2270
2271 // page.dataset.pageNumber = index;
2272
2273 page.dataset.pageNumber = index;
2274 page.setAttribute("id", id);
2275
2276 if (this.name) {
2277 page.classList.add("pagedjs_" + this.name + "_page");
2278 }
2279
2280 if (this.blank) {
2281 page.classList.add("pagedjs_blank_page");
2282 }
2283
2284 if (pgnum === 0) {
2285 page.classList.add("pagedjs_first_page");
2286 }
2287
2288 if (pgnum % 2 !== 1) {
2289 page.classList.remove("pagedjs_left_page");
2290 page.classList.add("pagedjs_right_page");
2291 } else {
2292 page.classList.remove("pagedjs_right_page");
2293 page.classList.add("pagedjs_left_page");
2294 }
2295 }
2296
2297 /*
2298 size(width, height) {
2299 if (width === this.width && height === this.height) {
2300 return;
2301 }
2302 this.width = width;
2303 this.height = height;
2304
2305 this.element.style.width = Math.round(width) + "px";
2306 this.element.style.height = Math.round(height) + "px";
2307 this.element.style.columnWidth = Math.round(width) + "px";
2308 }
2309 */
2310
2311 async layout(contents, breakToken, maxChars) {
2312
2313 this.clear();
2314
2315 this.startToken = breakToken;
2316
2317 let settings = this.settings;
2318 if (!settings.maxChars && maxChars) {
2319 settings.maxChars = maxChars;
2320 }
2321
2322 this.layoutMethod = new Layout(this.area, this.hooks, settings);
2323
2324 let renderResult = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
2325 let newBreakToken = renderResult.breakToken;
2326
2327 this.addListeners(contents);
2328
2329 this.endToken = newBreakToken;
2330
2331 return newBreakToken;
2332 }
2333
2334 async append(contents, breakToken) {
2335
2336 if (!this.layoutMethod) {
2337 return this.layout(contents, breakToken);
2338 }
2339
2340 let renderResult = await this.layoutMethod.renderTo(this.wrapper, contents, breakToken);
2341 let newBreakToken = renderResult.breakToken;
2342
2343 this.endToken = newBreakToken;
2344
2345 return newBreakToken;
2346 }
2347
2348 getByParent(ref, entries) {
2349 let e;
2350 for (var i = 0; i < entries.length; i++) {
2351 e = entries[i];
2352 if (e.dataset.ref === ref) {
2353 return e;
2354 }
2355 }
2356 }
2357
2358 onOverflow(func) {
2359 this._onOverflow = func;
2360 }
2361
2362 onUnderflow(func) {
2363 this._onUnderflow = func;
2364 }
2365
2366 clear() {
2367 this.removeListeners();
2368 this.wrapper && this.wrapper.remove();
2369 this.createWrapper();
2370 }
2371
2372 addListeners(contents) {
2373 if (typeof ResizeObserver !== "undefined") {
2374 this.addResizeObserver(contents);
2375 } else {
2376 this._checkOverflowAfterResize = this.checkOverflowAfterResize.bind(this, contents);
2377 this.element.addEventListener("overflow", this._checkOverflowAfterResize, false);
2378 this.element.addEventListener("underflow", this._checkOverflowAfterResize, false);
2379 }
2380 // TODO: fall back to mutation observer?
2381
2382 this._onScroll = function () {
2383 if (this.listening) {
2384 this.element.scrollLeft = 0;
2385 }
2386 }.bind(this);
2387
2388 // Keep scroll left from changing
2389 this.element.addEventListener("scroll", this._onScroll);
2390
2391 this.listening = true;
2392
2393 return true;
2394 }
2395
2396 removeListeners() {
2397 this.listening = false;
2398
2399 if (typeof ResizeObserver !== "undefined" && this.ro) {
2400 this.ro.disconnect();
2401 } else if (this.element) {
2402 this.element.removeEventListener("overflow", this._checkOverflowAfterResize, false);
2403 this.element.removeEventListener("underflow", this._checkOverflowAfterResize, false);
2404 }
2405
2406 this.element && this.element.removeEventListener("scroll", this._onScroll);
2407
2408 }
2409
2410 addResizeObserver(contents) {
2411 let wrapper = this.wrapper;
2412 let prevHeight = wrapper.getBoundingClientRect().height;
2413 this.ro = new ResizeObserver(entries => {
2414
2415 if (!this.listening) {
2416 return;
2417 }
2418 requestAnimationFrame(() => {
2419 for (let entry of entries) {
2420 const cr = entry.contentRect;
2421
2422 if (cr.height > prevHeight) {
2423 this.checkOverflowAfterResize(contents);
2424 prevHeight = wrapper.getBoundingClientRect().height;
2425 } else if (cr.height < prevHeight) { // TODO: calc line height && (prevHeight - cr.height) >= 22
2426 this.checkUnderflowAfterResize(contents);
2427 prevHeight = cr.height;
2428 }
2429 }
2430 });
2431 });
2432
2433 this.ro.observe(wrapper);
2434 }
2435
2436 checkOverflowAfterResize(contents) {
2437 if (!this.listening || !this.layoutMethod) {
2438 return;
2439 }
2440
2441 let newBreakToken = this.layoutMethod.findBreakToken(this.wrapper, contents, this.startToken);
2442
2443 if (newBreakToken) {
2444 this.endToken = newBreakToken;
2445 this._onOverflow && this._onOverflow(newBreakToken);
2446 }
2447 }
2448
2449 checkUnderflowAfterResize(contents) {
2450 if (!this.listening || !this.layoutMethod) {
2451 return;
2452 }
2453
2454 let endToken = this.layoutMethod.findEndToken(this.wrapper, contents);
2455
2456 if (endToken) {
2457 this._onUnderflow && this._onUnderflow(endToken);
2458 }
2459 }
2460
2461
2462 destroy() {
2463 this.removeListeners();
2464
2465 this.element.remove();
2466
2467 this.element = undefined;
2468 this.wrapper = undefined;
2469 }
2470}
2471
2472EventEmitter(Page.prototype);
2473
2474/**
2475 * Render a flow of text offscreen
2476 * @class
2477 */
2478class ContentParser {
2479
2480 constructor(content, cb) {
2481 if (content && content.nodeType) {
2482 // handle dom
2483 this.dom = this.add(content);
2484 } else if (typeof content === "string") {
2485 this.dom = this.parse(content);
2486 }
2487
2488 return this.dom;
2489 }
2490
2491 parse(markup, mime) {
2492 let range = document.createRange();
2493 let fragment = range.createContextualFragment(markup);
2494
2495 this.addRefs(fragment);
2496
2497 return fragment;
2498 }
2499
2500 add(contents) {
2501 // let fragment = document.createDocumentFragment();
2502 //
2503 // let children = [...contents.childNodes];
2504 // for (let child of children) {
2505 // let clone = child.cloneNode(true);
2506 // fragment.appendChild(clone);
2507 // }
2508
2509 this.addRefs(contents);
2510
2511 return contents;
2512 }
2513
2514 addRefs(content) {
2515 var treeWalker = document.createTreeWalker(
2516 content,
2517 NodeFilter.SHOW_ELEMENT,
2518 null,
2519 false
2520 );
2521
2522 let node = treeWalker.nextNode();
2523 while(node) {
2524
2525 if (!node.hasAttribute("data-ref")) {
2526 let uuid = UUID();
2527 node.setAttribute("data-ref", uuid);
2528 }
2529
2530 if (node.id) {
2531 node.setAttribute("data-id", node.id);
2532 }
2533
2534 // node.setAttribute("data-children", node.childNodes.length);
2535
2536 // node.setAttribute("data-text", node.textContent.trim().length);
2537 node = treeWalker.nextNode();
2538 }
2539 }
2540
2541 find(ref) {
2542 return this.refs[ref];
2543 }
2544
2545 destroy() {
2546 this.refs = undefined;
2547 this.dom = undefined;
2548 }
2549}
2550
2551/**
2552 * Queue for handling tasks one at a time
2553 * @class
2554 * @param {scope} context what this will resolve to in the tasks
2555 */
2556class Queue {
2557 constructor(context){
2558 this._q = [];
2559 this.context = context;
2560 this.tick = requestAnimationFrame;
2561 this.running = false;
2562 this.paused = false;
2563 }
2564
2565 /**
2566 * Add an item to the queue
2567 * @return {Promise} enqueued
2568 */
2569 enqueue() {
2570 var deferred, promise;
2571 var queued;
2572 var task = [].shift.call(arguments);
2573 var args = arguments;
2574
2575 // Handle single args without context
2576 // if(args && !Array.isArray(args)) {
2577 // args = [args];
2578 // }
2579 if(!task) {
2580 throw new Error("No Task Provided");
2581 }
2582
2583 if(typeof task === "function"){
2584
2585 deferred = new defer();
2586 promise = deferred.promise;
2587
2588 queued = {
2589 "task" : task,
2590 "args" : args,
2591 //"context" : context,
2592 "deferred" : deferred,
2593 "promise" : promise
2594 };
2595
2596 } else {
2597 // Task is a promise
2598 queued = {
2599 "promise" : task
2600 };
2601
2602 }
2603
2604 this._q.push(queued);
2605
2606 // Wait to start queue flush
2607 if (this.paused == false && !this.running) {
2608 this.run();
2609 }
2610
2611 return queued.promise;
2612 }
2613
2614 /**
2615 * Run one item
2616 * @return {Promise} dequeued
2617 */
2618 dequeue(){
2619 var inwait, task, result;
2620
2621 if(this._q.length && !this.paused) {
2622 inwait = this._q.shift();
2623 task = inwait.task;
2624 if(task){
2625 // console.log(task)
2626
2627 result = task.apply(this.context, inwait.args);
2628
2629 if(result && typeof result["then"] === "function") {
2630 // Task is a function that returns a promise
2631 return result.then(function(){
2632 inwait.deferred.resolve.apply(this.context, arguments);
2633 }.bind(this), function() {
2634 inwait.deferred.reject.apply(this.context, arguments);
2635 }.bind(this));
2636 } else {
2637 // Task resolves immediately
2638 inwait.deferred.resolve.apply(this.context, result);
2639 return inwait.promise;
2640 }
2641
2642
2643
2644 } else if(inwait.promise) {
2645 // Task is a promise
2646 return inwait.promise;
2647 }
2648
2649 } else {
2650 inwait = new defer();
2651 inwait.deferred.resolve();
2652 return inwait.promise;
2653 }
2654
2655 }
2656
2657 // Run All Immediately
2658 dump(){
2659 while(this._q.length) {
2660 this.dequeue();
2661 }
2662 }
2663
2664 /**
2665 * Run all tasks sequentially, at convince
2666 * @return {Promise} all run
2667 */
2668 run(){
2669
2670 if(!this.running){
2671 this.running = true;
2672 this.defered = new defer();
2673 }
2674
2675 this.tick.call(window, () => {
2676
2677 if(this._q.length) {
2678
2679 this.dequeue()
2680 .then(function(){
2681 this.run();
2682 }.bind(this));
2683
2684 } else {
2685 this.defered.resolve();
2686 this.running = undefined;
2687 }
2688
2689 });
2690
2691 // Unpause
2692 if(this.paused == true) {
2693 this.paused = false;
2694 }
2695
2696 return this.defered.promise;
2697 }
2698
2699 /**
2700 * Flush all, as quickly as possible
2701 * @return {Promise} ran
2702 */
2703 flush(){
2704
2705 if(this.running){
2706 return this.running;
2707 }
2708
2709 if(this._q.length) {
2710 this.running = this.dequeue()
2711 .then(function(){
2712 this.running = undefined;
2713 return this.flush();
2714 }.bind(this));
2715
2716 return this.running;
2717 }
2718
2719 }
2720
2721 /**
2722 * Clear all items in wait
2723 * @return {void}
2724 */
2725 clear(){
2726 this._q = [];
2727 }
2728
2729 /**
2730 * Get the number of tasks in the queue
2731 * @return {number} tasks
2732 */
2733 length(){
2734 return this._q.length;
2735 }
2736
2737 /**
2738 * Pause a running queue
2739 * @return {void}
2740 */
2741 pause(){
2742 this.paused = true;
2743 }
2744
2745 /**
2746 * End the queue
2747 * @return {void}
2748 */
2749 stop(){
2750 this._q = [];
2751 this.running = false;
2752 this.paused = true;
2753 }
2754}
2755
2756const TEMPLATE = `
2757<div class="pagedjs_page">
2758 <div class="pagedjs_sheet">
2759 <div class="pagedjs_bleed pagedjs_bleed-top">
2760 <div class="pagedjs_marks-crop"></div>
2761 <div class="pagedjs_marks-middle">
2762 <div class="pagedjs_marks-cross"></div>
2763 </div>
2764 <div class="pagedjs_marks-crop"></div>
2765 </div>
2766 <div class="pagedjs_bleed pagedjs_bleed-bottom">
2767 <div class="pagedjs_marks-crop"></div>
2768 <div class="pagedjs_marks-middle">
2769 <div class="pagedjs_marks-cross"></div>
2770 </div> <div class="pagedjs_marks-crop"></div>
2771 </div>
2772 <div class="pagedjs_bleed pagedjs_bleed-left">
2773 <div class="pagedjs_marks-crop"></div>
2774 <div class="pagedjs_marks-middle">
2775 <div class="pagedjs_marks-cross"></div>
2776 </div> <div class="pagedjs_marks-crop"></div>
2777 </div>
2778 <div class="pagedjs_bleed pagedjs_bleed-right">
2779 <div class="pagedjs_marks-crop"></div>
2780 <div class="pagedjs_marks-middle">
2781 <div class="pagedjs_marks-cross"></div>
2782 </div>
2783 <div class="pagedjs_marks-crop"></div>
2784 </div>
2785 <div class="pagedjs_pagebox">
2786 <div class="pagedjs_margin-top-left-corner-holder">
2787 <div class="pagedjs_margin pagedjs_margin-top-left-corner"><div class="pagedjs_margin-content"></div></div>
2788 </div>
2789 <div class="pagedjs_margin-top">
2790 <div class="pagedjs_margin pagedjs_margin-top-left"><div class="pagedjs_margin-content"></div></div>
2791 <div class="pagedjs_margin pagedjs_margin-top-center"><div class="pagedjs_margin-content"></div></div>
2792 <div class="pagedjs_margin pagedjs_margin-top-right"><div class="pagedjs_margin-content"></div></div>
2793 </div>
2794 <div class="pagedjs_margin-top-right-corner-holder">
2795 <div class="pagedjs_margin pagedjs_margin-top-right-corner"><div class="pagedjs_margin-content"></div></div>
2796 </div>
2797 <div class="pagedjs_margin-right">
2798 <div class="pagedjs_margin pagedjs_margin-right-top"><div class="pagedjs_margin-content"></div></div>
2799 <div class="pagedjs_margin pagedjs_margin-right-middle"><div class="pagedjs_margin-content"></div></div>
2800 <div class="pagedjs_margin pagedjs_margin-right-bottom"><div class="pagedjs_margin-content"></div></div>
2801 </div>
2802 <div class="pagedjs_margin-left">
2803 <div class="pagedjs_margin pagedjs_margin-left-top"><div class="pagedjs_margin-content"></div></div>
2804 <div class="pagedjs_margin pagedjs_margin-left-middle"><div class="pagedjs_margin-content"></div></div>
2805 <div class="pagedjs_margin pagedjs_margin-left-bottom"><div class="pagedjs_margin-content"></div></div>
2806 </div>
2807 <div class="pagedjs_margin-bottom-left-corner-holder">
2808 <div class="pagedjs_margin pagedjs_margin-bottom-left-corner"><div class="pagedjs_margin-content"></div></div>
2809 </div>
2810 <div class="pagedjs_margin-bottom">
2811 <div class="pagedjs_margin pagedjs_margin-bottom-left"><div class="pagedjs_margin-content"></div></div>
2812 <div class="pagedjs_margin pagedjs_margin-bottom-center"><div class="pagedjs_margin-content"></div></div>
2813 <div class="pagedjs_margin pagedjs_margin-bottom-right"><div class="pagedjs_margin-content"></div></div>
2814 </div>
2815 <div class="pagedjs_margin-bottom-right-corner-holder">
2816 <div class="pagedjs_margin pagedjs_margin-bottom-right-corner"><div class="pagedjs_margin-content"></div></div>
2817 </div>
2818 <div class="pagedjs_area">
2819 <div class="pagedjs_page_content"></div>
2820 <div class="pagedjs_footnote_area">
2821 <div class="pagedjs_footnote_content pagedjs_footnote_empty">
2822 <div class="pagedjs_footnote_inner_content"></div>
2823 </div>
2824 </div>
2825 </div>
2826 </div>
2827 </div>
2828</div>`;
2829
2830/**
2831 * Chop up text into flows
2832 * @class
2833 */
2834class Chunker {
2835 constructor(content, renderTo, options) {
2836 // this.preview = preview;
2837
2838 this.settings = options || {};
2839
2840 this.hooks = {};
2841 this.hooks.beforeParsed = new Hook(this);
2842 this.hooks.filter = new Hook(this);
2843 this.hooks.afterParsed = new Hook(this);
2844 this.hooks.beforePageLayout = new Hook(this);
2845 this.hooks.onPageLayout = new Hook(this);
2846 this.hooks.layout = new Hook(this);
2847 this.hooks.renderNode = new Hook(this);
2848 this.hooks.layoutNode = new Hook(this);
2849 this.hooks.onOverflow = new Hook(this);
2850 this.hooks.afterOverflowRemoved = new Hook(this);
2851 this.hooks.onBreakToken = new Hook();
2852 this.hooks.beforeRenderResult = new Hook(this);
2853 this.hooks.afterPageLayout = new Hook(this);
2854 this.hooks.finalizePage = new Hook(this);
2855 this.hooks.afterRendered = new Hook(this);
2856
2857 this.pages = [];
2858 this.total = 0;
2859
2860 this.q = new Queue(this);
2861 this.stopped = false;
2862 this.rendered = false;
2863
2864 this.content = content;
2865
2866 this.charsPerBreak = [];
2867 this.maxChars;
2868
2869 if (content) {
2870 this.flow(content, renderTo);
2871 }
2872 }
2873
2874 setup(renderTo) {
2875 this.pagesArea = document.createElement("div");
2876 this.pagesArea.classList.add("pagedjs_pages");
2877
2878 if (renderTo) {
2879 renderTo.appendChild(this.pagesArea);
2880 } else {
2881 document.querySelector("body").appendChild(this.pagesArea);
2882 }
2883
2884 this.pageTemplate = document.createElement("template");
2885 this.pageTemplate.innerHTML = TEMPLATE;
2886
2887 }
2888
2889 async flow(content, renderTo) {
2890 let parsed;
2891
2892 await this.hooks.beforeParsed.trigger(content, this);
2893
2894 parsed = new ContentParser(content);
2895
2896 this.hooks.filter.triggerSync(parsed);
2897
2898 this.source = parsed;
2899 this.breakToken = undefined;
2900
2901 if (this.pagesArea && this.pageTemplate) {
2902 this.q.clear();
2903 this.removePages();
2904 } else {
2905 this.setup(renderTo);
2906 }
2907
2908 this.emit("rendering", parsed);
2909
2910 await this.hooks.afterParsed.trigger(parsed, this);
2911
2912 await this.loadFonts();
2913
2914 let rendered = await this.render(parsed, this.breakToken);
2915 while (rendered.canceled) {
2916 this.start();
2917 rendered = await this.render(parsed, this.breakToken);
2918 }
2919
2920 this.rendered = true;
2921 this.pagesArea.style.setProperty("--pagedjs-page-count", this.total);
2922
2923 await this.hooks.afterRendered.trigger(this.pages, this);
2924
2925 this.emit("rendered", this.pages);
2926
2927
2928
2929 return this;
2930 }
2931
2932 // oversetPages() {
2933 // let overset = [];
2934 // for (let i = 0; i < this.pages.length; i++) {
2935 // let page = this.pages[i];
2936 // if (page.overset) {
2937 // overset.push(page);
2938 // // page.overset = false;
2939 // }
2940 // }
2941 // return overset;
2942 // }
2943 //
2944 // async handleOverset(parsed) {
2945 // let overset = this.oversetPages();
2946 // if (overset.length) {
2947 // console.log("overset", overset);
2948 // let index = this.pages.indexOf(overset[0]) + 1;
2949 // console.log("INDEX", index);
2950 //
2951 // // Remove pages
2952 // // this.removePages(index);
2953 //
2954 // // await this.render(parsed, overset[0].overset);
2955 //
2956 // // return this.handleOverset(parsed);
2957 // }
2958 // }
2959
2960 async render(parsed, startAt) {
2961 let renderer = this.layout(parsed, startAt);
2962
2963 let done = false;
2964 let result;
2965 while (!done) {
2966 result = await this.q.enqueue(() => { return this.renderAsync(renderer); });
2967 done = result.done;
2968 }
2969
2970 return result;
2971 }
2972
2973 start() {
2974 this.rendered = false;
2975 this.stopped = false;
2976 }
2977
2978 stop() {
2979 this.stopped = true;
2980 // this.q.clear();
2981 }
2982
2983 renderOnIdle(renderer) {
2984 return new Promise(resolve => {
2985 requestIdleCallback(async () => {
2986 if (this.stopped) {
2987 return resolve({ done: true, canceled: true });
2988 }
2989 let result = await renderer.next();
2990 if (this.stopped) {
2991 resolve({ done: true, canceled: true });
2992 } else {
2993 resolve(result);
2994 }
2995 });
2996 });
2997 }
2998
2999 async renderAsync(renderer) {
3000 if (this.stopped) {
3001 return { done: true, canceled: true };
3002 }
3003 let result = await renderer.next();
3004 if (this.stopped) {
3005 return { done: true, canceled: true };
3006 } else {
3007 return result;
3008 }
3009 }
3010
3011 async handleBreaks(node, force) {
3012 let currentPage = this.total + 1;
3013 let currentPosition = currentPage % 2 === 0 ? "left" : "right";
3014 // TODO: Recto and Verso should reverse for rtl languages
3015 let currentSide = currentPage % 2 === 0 ? "verso" : "recto";
3016 let previousBreakAfter;
3017 let breakBefore;
3018 let page;
3019
3020 if (currentPage === 1) {
3021 return;
3022 }
3023
3024 if (node &&
3025 typeof node.dataset !== "undefined" &&
3026 typeof node.dataset.previousBreakAfter !== "undefined") {
3027 previousBreakAfter = node.dataset.previousBreakAfter;
3028 }
3029
3030 if (node &&
3031 typeof node.dataset !== "undefined" &&
3032 typeof node.dataset.breakBefore !== "undefined") {
3033 breakBefore = node.dataset.breakBefore;
3034 }
3035
3036 if (force) {
3037 page = this.addPage(true);
3038 } else if( previousBreakAfter &&
3039 (previousBreakAfter === "left" || previousBreakAfter === "right") &&
3040 previousBreakAfter !== currentPosition) {
3041 page = this.addPage(true);
3042 } else if( previousBreakAfter &&
3043 (previousBreakAfter === "verso" || previousBreakAfter === "recto") &&
3044 previousBreakAfter !== currentSide) {
3045 page = this.addPage(true);
3046 } else if( breakBefore &&
3047 (breakBefore === "left" || breakBefore === "right") &&
3048 breakBefore !== currentPosition) {
3049 page = this.addPage(true);
3050 } else if( breakBefore &&
3051 (breakBefore === "verso" || breakBefore === "recto") &&
3052 breakBefore !== currentSide) {
3053 page = this.addPage(true);
3054 }
3055
3056 if (page) {
3057 await this.hooks.beforePageLayout.trigger(page, undefined, undefined, this);
3058 this.emit("page", page);
3059 // await this.hooks.layout.trigger(page.element, page, undefined, this);
3060 await this.hooks.afterPageLayout.trigger(page.element, page, undefined, this);
3061 await this.hooks.finalizePage.trigger(page.element, page, undefined, this);
3062 this.emit("renderedPage", page);
3063 }
3064 }
3065
3066 async *layout(content, startAt) {
3067 let breakToken = startAt || false;
3068 let tokens = [];
3069
3070 while (breakToken !== undefined && (true)) {
3071
3072 if (breakToken && breakToken.node) {
3073 await this.handleBreaks(breakToken.node);
3074 } else {
3075 await this.handleBreaks(content.firstChild);
3076 }
3077
3078 let page = this.addPage();
3079
3080 await this.hooks.beforePageLayout.trigger(page, content, breakToken, this);
3081 this.emit("page", page);
3082
3083 // Layout content in the page, starting from the breakToken
3084 breakToken = await page.layout(content, breakToken, this.maxChars);
3085
3086 if (breakToken) {
3087 let newToken = breakToken.toJSON(true);
3088 if (tokens.lastIndexOf(newToken) > -1) {
3089 // loop
3090 let err = new OverflowContentError("Layout repeated", [breakToken.node]);
3091 console.error("Layout repeated at: ", breakToken.node);
3092 return err;
3093 } else {
3094 tokens.push(newToken);
3095 }
3096 }
3097
3098 await this.hooks.afterPageLayout.trigger(page.element, page, breakToken, this);
3099 await this.hooks.finalizePage.trigger(page.element, page, undefined, this);
3100 this.emit("renderedPage", page);
3101
3102 this.recoredCharLength(page.wrapper.textContent.length);
3103
3104 yield breakToken;
3105
3106 // Stop if we get undefined, showing we have reached the end of the content
3107 }
3108
3109
3110 }
3111
3112 recoredCharLength(length) {
3113 if (length === 0) {
3114 return;
3115 }
3116
3117 this.charsPerBreak.push(length);
3118
3119 // Keep the length of the last few breaks
3120 if (this.charsPerBreak.length > 4) {
3121 this.charsPerBreak.shift();
3122 }
3123
3124 this.maxChars = this.charsPerBreak.reduce((a, b) => a + b, 0) / (this.charsPerBreak.length);
3125 }
3126
3127 removePages(fromIndex=0) {
3128
3129 if (fromIndex >= this.pages.length) {
3130 return;
3131 }
3132
3133 // Remove pages
3134 for (let i = fromIndex; i < this.pages.length; i++) {
3135 this.pages[i].destroy();
3136 }
3137
3138 if (fromIndex > 0) {
3139 this.pages.splice(fromIndex);
3140 } else {
3141 this.pages = [];
3142 }
3143
3144 this.total = this.pages.length;
3145 }
3146
3147 addPage(blank) {
3148 let lastPage = this.pages[this.pages.length - 1];
3149 // Create a new page from the template
3150 let page = new Page(this.pagesArea, this.pageTemplate, blank, this.hooks, this.settings);
3151
3152 this.pages.push(page);
3153
3154 // Create the pages
3155 page.create(undefined, lastPage && lastPage.element);
3156
3157 page.index(this.total);
3158
3159 if (!blank) {
3160 // Listen for page overflow
3161 page.onOverflow((overflowToken) => {
3162 console.warn("overflow on", page.id, overflowToken);
3163
3164 // Only reflow while rendering
3165 if (this.rendered) {
3166 return;
3167 }
3168
3169 let index = this.pages.indexOf(page) + 1;
3170
3171 // Stop the rendering
3172 this.stop();
3173
3174 // Set the breakToken to resume at
3175 this.breakToken = overflowToken;
3176
3177 // Remove pages
3178 this.removePages(index);
3179
3180 if (this.rendered === true) {
3181 this.rendered = false;
3182
3183 this.q.enqueue(async () => {
3184
3185 this.start();
3186
3187 await this.render(this.source, this.breakToken);
3188
3189 this.rendered = true;
3190
3191 });
3192 }
3193
3194
3195 });
3196
3197 page.onUnderflow((overflowToken) => {
3198 // console.log("underflow on", page.id, overflowToken);
3199
3200 // page.append(this.source, overflowToken);
3201
3202 });
3203 }
3204
3205 this.total = this.pages.length;
3206
3207 return page;
3208 }
3209 /*
3210 insertPage(index, blank) {
3211 let lastPage = this.pages[index];
3212 // Create a new page from the template
3213 let page = new Page(this.pagesArea, this.pageTemplate, blank, this.hooks);
3214
3215 let total = this.pages.splice(index, 0, page);
3216
3217 // Create the pages
3218 page.create(undefined, lastPage && lastPage.element);
3219
3220 page.index(index + 1);
3221
3222 for (let i = index + 2; i < this.pages.length; i++) {
3223 this.pages[i].index(i);
3224 }
3225
3226 if (!blank) {
3227 // Listen for page overflow
3228 page.onOverflow((overflowToken) => {
3229 if (total < this.pages.length) {
3230 this.pages[total].layout(this.source, overflowToken);
3231 } else {
3232 let newPage = this.addPage();
3233 newPage.layout(this.source, overflowToken);
3234 }
3235 });
3236
3237 page.onUnderflow(() => {
3238 // console.log("underflow on", page.id);
3239 });
3240 }
3241
3242 this.total += 1;
3243
3244 return page;
3245 }
3246 */
3247
3248 async clonePage(originalPage) {
3249 let lastPage = this.pages[this.pages.length - 1];
3250
3251 let page = new Page(this.pagesArea, this.pageTemplate, false, this.hooks);
3252
3253 this.pages.push(page);
3254
3255 // Create the pages
3256 page.create(undefined, lastPage && lastPage.element);
3257
3258 page.index(this.total);
3259
3260 await this.hooks.beforePageLayout.trigger(page, undefined, undefined, this);
3261 this.emit("page", page);
3262
3263 for (const className of originalPage.element.classList) {
3264 if (className !== "pagedjs_left_page" && className !== "pagedjs_right_page") {
3265 page.element.classList.add(className);
3266 }
3267 }
3268
3269 await this.hooks.afterPageLayout.trigger(page.element, page, undefined, this);
3270 await this.hooks.finalizePage.trigger(page.element, page, undefined, this);
3271 this.emit("renderedPage", page);
3272 }
3273
3274 loadFonts() {
3275 let fontPromises = [];
3276 (document.fonts || []).forEach((fontFace) => {
3277 if (fontFace.status !== "loaded") {
3278 let fontLoaded = fontFace.load().then((r) => {
3279 return fontFace.family;
3280 }, (r) => {
3281 console.warn("Failed to preload font-family:", fontFace.family);
3282 return fontFace.family;
3283 });
3284 fontPromises.push(fontLoaded);
3285 }
3286 });
3287 return Promise.all(fontPromises).catch((err) => {
3288 console.warn(err);
3289 });
3290 }
3291
3292 destroy() {
3293 this.pagesArea.remove();
3294 this.pageTemplate.remove();
3295 }
3296
3297}
3298
3299EventEmitter(Chunker.prototype);
3300
3301var syntax = {exports: {}};
3302
3303var create$4 = {};
3304
3305//
3306// list
3307// ┌──────┐
3308// ┌──────────────┼─head │
3309// │ │ tail─┼──────────────┐
3310// │ └──────┘ │
3311// ▼ ▼
3312// item item item item
3313// ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
3314// null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
3315// │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
3316// ├──────┤ ├──────┤ ├──────┤ ├──────┤
3317// │ data │ │ data │ │ data │ │ data │
3318// └──────┘ └──────┘ └──────┘ └──────┘
3319//
3320
3321function createItem(data) {
3322 return {
3323 prev: null,
3324 next: null,
3325 data: data
3326 };
3327}
3328
3329function allocateCursor(node, prev, next) {
3330 var cursor;
3331
3332 if (cursors !== null) {
3333 cursor = cursors;
3334 cursors = cursors.cursor;
3335 cursor.prev = prev;
3336 cursor.next = next;
3337 cursor.cursor = node.cursor;
3338 } else {
3339 cursor = {
3340 prev: prev,
3341 next: next,
3342 cursor: node.cursor
3343 };
3344 }
3345
3346 node.cursor = cursor;
3347
3348 return cursor;
3349}
3350
3351function releaseCursor(node) {
3352 var cursor = node.cursor;
3353
3354 node.cursor = cursor.cursor;
3355 cursor.prev = null;
3356 cursor.next = null;
3357 cursor.cursor = cursors;
3358 cursors = cursor;
3359}
3360
3361var cursors = null;
3362var List$6 = function() {
3363 this.cursor = null;
3364 this.head = null;
3365 this.tail = null;
3366};
3367
3368List$6.createItem = createItem;
3369List$6.prototype.createItem = createItem;
3370
3371List$6.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
3372 var cursor = this.cursor;
3373
3374 while (cursor !== null) {
3375 if (cursor.prev === prevOld) {
3376 cursor.prev = prevNew;
3377 }
3378
3379 if (cursor.next === nextOld) {
3380 cursor.next = nextNew;
3381 }
3382
3383 cursor = cursor.cursor;
3384 }
3385};
3386
3387List$6.prototype.getSize = function() {
3388 var size = 0;
3389 var cursor = this.head;
3390
3391 while (cursor) {
3392 size++;
3393 cursor = cursor.next;
3394 }
3395
3396 return size;
3397};
3398
3399List$6.prototype.fromArray = function(array) {
3400 var cursor = null;
3401
3402 this.head = null;
3403
3404 for (var i = 0; i < array.length; i++) {
3405 var item = createItem(array[i]);
3406
3407 if (cursor !== null) {
3408 cursor.next = item;
3409 } else {
3410 this.head = item;
3411 }
3412
3413 item.prev = cursor;
3414 cursor = item;
3415 }
3416
3417 this.tail = cursor;
3418
3419 return this;
3420};
3421
3422List$6.prototype.toArray = function() {
3423 var cursor = this.head;
3424 var result = [];
3425
3426 while (cursor) {
3427 result.push(cursor.data);
3428 cursor = cursor.next;
3429 }
3430
3431 return result;
3432};
3433
3434List$6.prototype.toJSON = List$6.prototype.toArray;
3435
3436List$6.prototype.isEmpty = function() {
3437 return this.head === null;
3438};
3439
3440List$6.prototype.first = function() {
3441 return this.head && this.head.data;
3442};
3443
3444List$6.prototype.last = function() {
3445 return this.tail && this.tail.data;
3446};
3447
3448List$6.prototype.each = function(fn, context) {
3449 var item;
3450
3451 if (context === undefined) {
3452 context = this;
3453 }
3454
3455 // push cursor
3456 var cursor = allocateCursor(this, null, this.head);
3457
3458 while (cursor.next !== null) {
3459 item = cursor.next;
3460 cursor.next = item.next;
3461
3462 fn.call(context, item.data, item, this);
3463 }
3464
3465 // pop cursor
3466 releaseCursor(this);
3467};
3468
3469List$6.prototype.forEach = List$6.prototype.each;
3470
3471List$6.prototype.eachRight = function(fn, context) {
3472 var item;
3473
3474 if (context === undefined) {
3475 context = this;
3476 }
3477
3478 // push cursor
3479 var cursor = allocateCursor(this, this.tail, null);
3480
3481 while (cursor.prev !== null) {
3482 item = cursor.prev;
3483 cursor.prev = item.prev;
3484
3485 fn.call(context, item.data, item, this);
3486 }
3487
3488 // pop cursor
3489 releaseCursor(this);
3490};
3491
3492List$6.prototype.forEachRight = List$6.prototype.eachRight;
3493
3494List$6.prototype.reduce = function(fn, initialValue, context) {
3495 var item;
3496
3497 if (context === undefined) {
3498 context = this;
3499 }
3500
3501 // push cursor
3502 var cursor = allocateCursor(this, null, this.head);
3503 var acc = initialValue;
3504
3505 while (cursor.next !== null) {
3506 item = cursor.next;
3507 cursor.next = item.next;
3508
3509 acc = fn.call(context, acc, item.data, item, this);
3510 }
3511
3512 // pop cursor
3513 releaseCursor(this);
3514
3515 return acc;
3516};
3517
3518List$6.prototype.reduceRight = function(fn, initialValue, context) {
3519 var item;
3520
3521 if (context === undefined) {
3522 context = this;
3523 }
3524
3525 // push cursor
3526 var cursor = allocateCursor(this, this.tail, null);
3527 var acc = initialValue;
3528
3529 while (cursor.prev !== null) {
3530 item = cursor.prev;
3531 cursor.prev = item.prev;
3532
3533 acc = fn.call(context, acc, item.data, item, this);
3534 }
3535
3536 // pop cursor
3537 releaseCursor(this);
3538
3539 return acc;
3540};
3541
3542List$6.prototype.nextUntil = function(start, fn, context) {
3543 if (start === null) {
3544 return;
3545 }
3546
3547 var item;
3548
3549 if (context === undefined) {
3550 context = this;
3551 }
3552
3553 // push cursor
3554 var cursor = allocateCursor(this, null, start);
3555
3556 while (cursor.next !== null) {
3557 item = cursor.next;
3558 cursor.next = item.next;
3559
3560 if (fn.call(context, item.data, item, this)) {
3561 break;
3562 }
3563 }
3564
3565 // pop cursor
3566 releaseCursor(this);
3567};
3568
3569List$6.prototype.prevUntil = function(start, fn, context) {
3570 if (start === null) {
3571 return;
3572 }
3573
3574 var item;
3575
3576 if (context === undefined) {
3577 context = this;
3578 }
3579
3580 // push cursor
3581 var cursor = allocateCursor(this, start, null);
3582
3583 while (cursor.prev !== null) {
3584 item = cursor.prev;
3585 cursor.prev = item.prev;
3586
3587 if (fn.call(context, item.data, item, this)) {
3588 break;
3589 }
3590 }
3591
3592 // pop cursor
3593 releaseCursor(this);
3594};
3595
3596List$6.prototype.some = function(fn, context) {
3597 var cursor = this.head;
3598
3599 if (context === undefined) {
3600 context = this;
3601 }
3602
3603 while (cursor !== null) {
3604 if (fn.call(context, cursor.data, cursor, this)) {
3605 return true;
3606 }
3607
3608 cursor = cursor.next;
3609 }
3610
3611 return false;
3612};
3613
3614List$6.prototype.map = function(fn, context) {
3615 var result = new List$6();
3616 var cursor = this.head;
3617
3618 if (context === undefined) {
3619 context = this;
3620 }
3621
3622 while (cursor !== null) {
3623 result.appendData(fn.call(context, cursor.data, cursor, this));
3624 cursor = cursor.next;
3625 }
3626
3627 return result;
3628};
3629
3630List$6.prototype.filter = function(fn, context) {
3631 var result = new List$6();
3632 var cursor = this.head;
3633
3634 if (context === undefined) {
3635 context = this;
3636 }
3637
3638 while (cursor !== null) {
3639 if (fn.call(context, cursor.data, cursor, this)) {
3640 result.appendData(cursor.data);
3641 }
3642 cursor = cursor.next;
3643 }
3644
3645 return result;
3646};
3647
3648List$6.prototype.clear = function() {
3649 this.head = null;
3650 this.tail = null;
3651};
3652
3653List$6.prototype.copy = function() {
3654 var result = new List$6();
3655 var cursor = this.head;
3656
3657 while (cursor !== null) {
3658 result.insert(createItem(cursor.data));
3659 cursor = cursor.next;
3660 }
3661
3662 return result;
3663};
3664
3665List$6.prototype.prepend = function(item) {
3666 // head
3667 // ^
3668 // item
3669 this.updateCursors(null, item, this.head, item);
3670
3671 // insert to the beginning of the list
3672 if (this.head !== null) {
3673 // new item <- first item
3674 this.head.prev = item;
3675
3676 // new item -> first item
3677 item.next = this.head;
3678 } else {
3679 // if list has no head, then it also has no tail
3680 // in this case tail points to the new item
3681 this.tail = item;
3682 }
3683
3684 // head always points to new item
3685 this.head = item;
3686
3687 return this;
3688};
3689
3690List$6.prototype.prependData = function(data) {
3691 return this.prepend(createItem(data));
3692};
3693
3694List$6.prototype.append = function(item) {
3695 return this.insert(item);
3696};
3697
3698List$6.prototype.appendData = function(data) {
3699 return this.insert(createItem(data));
3700};
3701
3702List$6.prototype.insert = function(item, before) {
3703 if (before !== undefined && before !== null) {
3704 // prev before
3705 // ^
3706 // item
3707 this.updateCursors(before.prev, item, before, item);
3708
3709 if (before.prev === null) {
3710 // insert to the beginning of list
3711 if (this.head !== before) {
3712 throw new Error('before doesn\'t belong to list');
3713 }
3714
3715 // since head points to before therefore list doesn't empty
3716 // no need to check tail
3717 this.head = item;
3718 before.prev = item;
3719 item.next = before;
3720
3721 this.updateCursors(null, item);
3722 } else {
3723
3724 // insert between two items
3725 before.prev.next = item;
3726 item.prev = before.prev;
3727
3728 before.prev = item;
3729 item.next = before;
3730 }
3731 } else {
3732 // tail
3733 // ^
3734 // item
3735 this.updateCursors(this.tail, item, null, item);
3736
3737 // insert to the ending of the list
3738 if (this.tail !== null) {
3739 // last item -> new item
3740 this.tail.next = item;
3741
3742 // last item <- new item
3743 item.prev = this.tail;
3744 } else {
3745 // if list has no tail, then it also has no head
3746 // in this case head points to new item
3747 this.head = item;
3748 }
3749
3750 // tail always points to new item
3751 this.tail = item;
3752 }
3753
3754 return this;
3755};
3756
3757List$6.prototype.insertData = function(data, before) {
3758 return this.insert(createItem(data), before);
3759};
3760
3761List$6.prototype.remove = function(item) {
3762 // item
3763 // ^
3764 // prev next
3765 this.updateCursors(item, item.prev, item, item.next);
3766
3767 if (item.prev !== null) {
3768 item.prev.next = item.next;
3769 } else {
3770 if (this.head !== item) {
3771 throw new Error('item doesn\'t belong to list');
3772 }
3773
3774 this.head = item.next;
3775 }
3776
3777 if (item.next !== null) {
3778 item.next.prev = item.prev;
3779 } else {
3780 if (this.tail !== item) {
3781 throw new Error('item doesn\'t belong to list');
3782 }
3783
3784 this.tail = item.prev;
3785 }
3786
3787 item.prev = null;
3788 item.next = null;
3789
3790 return item;
3791};
3792
3793List$6.prototype.push = function(data) {
3794 this.insert(createItem(data));
3795};
3796
3797List$6.prototype.pop = function() {
3798 if (this.tail !== null) {
3799 return this.remove(this.tail);
3800 }
3801};
3802
3803List$6.prototype.unshift = function(data) {
3804 this.prepend(createItem(data));
3805};
3806
3807List$6.prototype.shift = function() {
3808 if (this.head !== null) {
3809 return this.remove(this.head);
3810 }
3811};
3812
3813List$6.prototype.prependList = function(list) {
3814 return this.insertList(list, this.head);
3815};
3816
3817List$6.prototype.appendList = function(list) {
3818 return this.insertList(list);
3819};
3820
3821List$6.prototype.insertList = function(list, before) {
3822 // ignore empty lists
3823 if (list.head === null) {
3824 return this;
3825 }
3826
3827 if (before !== undefined && before !== null) {
3828 this.updateCursors(before.prev, list.tail, before, list.head);
3829
3830 // insert in the middle of dist list
3831 if (before.prev !== null) {
3832 // before.prev <-> list.head
3833 before.prev.next = list.head;
3834 list.head.prev = before.prev;
3835 } else {
3836 this.head = list.head;
3837 }
3838
3839 before.prev = list.tail;
3840 list.tail.next = before;
3841 } else {
3842 this.updateCursors(this.tail, list.tail, null, list.head);
3843
3844 // insert to end of the list
3845 if (this.tail !== null) {
3846 // if destination list has a tail, then it also has a head,
3847 // but head doesn't change
3848
3849 // dest tail -> source head
3850 this.tail.next = list.head;
3851
3852 // dest tail <- source head
3853 list.head.prev = this.tail;
3854 } else {
3855 // if list has no a tail, then it also has no a head
3856 // in this case points head to new item
3857 this.head = list.head;
3858 }
3859
3860 // tail always start point to new item
3861 this.tail = list.tail;
3862 }
3863
3864 list.head = null;
3865 list.tail = null;
3866
3867 return this;
3868};
3869
3870List$6.prototype.replace = function(oldItem, newItemOrList) {
3871 if ('head' in newItemOrList) {
3872 this.insertList(newItemOrList, oldItem);
3873 } else {
3874 this.insert(newItemOrList, oldItem);
3875 }
3876
3877 this.remove(oldItem);
3878};
3879
3880var List_1 = List$6;
3881
3882var createCustomError$3 = function createCustomError(name, message) {
3883 // use Object.create(), because some VMs prevent setting line/column otherwise
3884 // (iOS Safari 10 even throws an exception)
3885 var error = Object.create(SyntaxError.prototype);
3886 var errorStack = new Error();
3887
3888 error.name = name;
3889 error.message = message;
3890
3891 Object.defineProperty(error, 'stack', {
3892 get: function() {
3893 return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
3894 }
3895 });
3896
3897 return error;
3898};
3899
3900var createCustomError$2 = createCustomError$3;
3901var MAX_LINE_LENGTH = 100;
3902var OFFSET_CORRECTION = 60;
3903var TAB_REPLACEMENT = ' ';
3904
3905function sourceFragment(error, extraLines) {
3906 function processLines(start, end) {
3907 return lines.slice(start, end).map(function(line, idx) {
3908 var num = String(start + idx + 1);
3909
3910 while (num.length < maxNumLength) {
3911 num = ' ' + num;
3912 }
3913
3914 return num + ' |' + line;
3915 }).join('\n');
3916 }
3917
3918 var lines = error.source.split(/\r\n?|\n|\f/);
3919 var line = error.line;
3920 var column = error.column;
3921 var startLine = Math.max(1, line - extraLines) - 1;
3922 var endLine = Math.min(line + extraLines, lines.length + 1);
3923 var maxNumLength = Math.max(4, String(endLine).length) + 1;
3924 var cutLeft = 0;
3925
3926 // column correction according to replaced tab before column
3927 column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
3928
3929 if (column > MAX_LINE_LENGTH) {
3930 cutLeft = column - OFFSET_CORRECTION + 3;
3931 column = OFFSET_CORRECTION - 2;
3932 }
3933
3934 for (var i = startLine; i <= endLine; i++) {
3935 if (i >= 0 && i < lines.length) {
3936 lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
3937 lines[i] =
3938 (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
3939 lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
3940 (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
3941 }
3942 }
3943
3944 return [
3945 processLines(startLine, line),
3946 new Array(column + maxNumLength + 2).join('-') + '^',
3947 processLines(line, endLine)
3948 ].filter(Boolean).join('\n');
3949}
3950
3951var SyntaxError$4 = function(message, source, offset, line, column) {
3952 var error = createCustomError$2('SyntaxError', message);
3953
3954 error.source = source;
3955 error.offset = offset;
3956 error.line = line;
3957 error.column = column;
3958
3959 error.sourceFragment = function(extraLines) {
3960 return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
3961 };
3962 Object.defineProperty(error, 'formattedMessage', {
3963 get: function() {
3964 return (
3965 'Parse error: ' + error.message + '\n' +
3966 sourceFragment(error, 2)
3967 );
3968 }
3969 });
3970
3971 // for backward capability
3972 error.parseError = {
3973 offset: offset,
3974 line: line,
3975 column: column
3976 };
3977
3978 return error;
3979};
3980
3981var _SyntaxError$1 = SyntaxError$4;
3982
3983// CSS Syntax Module Level 3
3984// https://www.w3.org/TR/css-syntax-3/
3985var TYPE$H = {
3986 EOF: 0, // <EOF-token>
3987 Ident: 1, // <ident-token>
3988 Function: 2, // <function-token>
3989 AtKeyword: 3, // <at-keyword-token>
3990 Hash: 4, // <hash-token>
3991 String: 5, // <string-token>
3992 BadString: 6, // <bad-string-token>
3993 Url: 7, // <url-token>
3994 BadUrl: 8, // <bad-url-token>
3995 Delim: 9, // <delim-token>
3996 Number: 10, // <number-token>
3997 Percentage: 11, // <percentage-token>
3998 Dimension: 12, // <dimension-token>
3999 WhiteSpace: 13, // <whitespace-token>
4000 CDO: 14, // <CDO-token>
4001 CDC: 15, // <CDC-token>
4002 Colon: 16, // <colon-token> :
4003 Semicolon: 17, // <semicolon-token> ;
4004 Comma: 18, // <comma-token> ,
4005 LeftSquareBracket: 19, // <[-token>
4006 RightSquareBracket: 20, // <]-token>
4007 LeftParenthesis: 21, // <(-token>
4008 RightParenthesis: 22, // <)-token>
4009 LeftCurlyBracket: 23, // <{-token>
4010 RightCurlyBracket: 24, // <}-token>
4011 Comment: 25
4012};
4013
4014var NAME$3 = Object.keys(TYPE$H).reduce(function(result, key) {
4015 result[TYPE$H[key]] = key;
4016 return result;
4017}, {});
4018
4019var _const = {
4020 TYPE: TYPE$H,
4021 NAME: NAME$3
4022};
4023
4024var EOF$1 = 0;
4025
4026// https://drafts.csswg.org/css-syntax-3/
4027// § 4.2. Definitions
4028
4029// digit
4030// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
4031function isDigit$5(code) {
4032 return code >= 0x0030 && code <= 0x0039;
4033}
4034
4035// hex digit
4036// A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
4037// or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
4038function isHexDigit$4(code) {
4039 return (
4040 isDigit$5(code) || // 0 .. 9
4041 (code >= 0x0041 && code <= 0x0046) || // A .. F
4042 (code >= 0x0061 && code <= 0x0066) // a .. f
4043 );
4044}
4045
4046// uppercase letter
4047// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
4048function isUppercaseLetter$1(code) {
4049 return code >= 0x0041 && code <= 0x005A;
4050}
4051
4052// lowercase letter
4053// A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
4054function isLowercaseLetter(code) {
4055 return code >= 0x0061 && code <= 0x007A;
4056}
4057
4058// letter
4059// An uppercase letter or a lowercase letter.
4060function isLetter(code) {
4061 return isUppercaseLetter$1(code) || isLowercaseLetter(code);
4062}
4063
4064// non-ASCII code point
4065// A code point with a value equal to or greater than U+0080 <control>.
4066function isNonAscii(code) {
4067 return code >= 0x0080;
4068}
4069
4070// name-start code point
4071// A letter, a non-ASCII code point, or U+005F LOW LINE (_).
4072function isNameStart(code) {
4073 return isLetter(code) || isNonAscii(code) || code === 0x005F;
4074}
4075
4076// name code point
4077// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
4078function isName$2(code) {
4079 return isNameStart(code) || isDigit$5(code) || code === 0x002D;
4080}
4081
4082// non-printable code point
4083// A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
4084// or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
4085function isNonPrintable(code) {
4086 return (
4087 (code >= 0x0000 && code <= 0x0008) ||
4088 (code === 0x000B) ||
4089 (code >= 0x000E && code <= 0x001F) ||
4090 (code === 0x007F)
4091 );
4092}
4093
4094// newline
4095// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
4096// as they are converted to U+000A LINE FEED during preprocessing.
4097// TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
4098function isNewline$1(code) {
4099 return code === 0x000A || code === 0x000D || code === 0x000C;
4100}
4101
4102// whitespace
4103// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
4104function isWhiteSpace$2(code) {
4105 return isNewline$1(code) || code === 0x0020 || code === 0x0009;
4106}
4107
4108// § 4.3.8. Check if two code points are a valid escape
4109function isValidEscape$2(first, second) {
4110 // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
4111 if (first !== 0x005C) {
4112 return false;
4113 }
4114
4115 // Otherwise, if the second code point is a newline or EOF, return false.
4116 if (isNewline$1(second) || second === EOF$1) {
4117 return false;
4118 }
4119
4120 // Otherwise, return true.
4121 return true;
4122}
4123
4124// § 4.3.9. Check if three code points would start an identifier
4125function isIdentifierStart$2(first, second, third) {
4126 // Look at the first code point:
4127
4128 // U+002D HYPHEN-MINUS
4129 if (first === 0x002D) {
4130 // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
4131 // or the second and third code points are a valid escape, return true. Otherwise, return false.
4132 return (
4133 isNameStart(second) ||
4134 second === 0x002D ||
4135 isValidEscape$2(second, third)
4136 );
4137 }
4138
4139 // name-start code point
4140 if (isNameStart(first)) {
4141 // Return true.
4142 return true;
4143 }
4144
4145 // U+005C REVERSE SOLIDUS (\)
4146 if (first === 0x005C) {
4147 // If the first and second code points are a valid escape, return true. Otherwise, return false.
4148 return isValidEscape$2(first, second);
4149 }
4150
4151 // anything else
4152 // Return false.
4153 return false;
4154}
4155
4156// § 4.3.10. Check if three code points would start a number
4157function isNumberStart$1(first, second, third) {
4158 // Look at the first code point:
4159
4160 // U+002B PLUS SIGN (+)
4161 // U+002D HYPHEN-MINUS (-)
4162 if (first === 0x002B || first === 0x002D) {
4163 // If the second code point is a digit, return true.
4164 if (isDigit$5(second)) {
4165 return 2;
4166 }
4167
4168 // Otherwise, if the second code point is a U+002E FULL STOP (.)
4169 // and the third code point is a digit, return true.
4170 // Otherwise, return false.
4171 return second === 0x002E && isDigit$5(third) ? 3 : 0;
4172 }
4173
4174 // U+002E FULL STOP (.)
4175 if (first === 0x002E) {
4176 // If the second code point is a digit, return true. Otherwise, return false.
4177 return isDigit$5(second) ? 2 : 0;
4178 }
4179
4180 // digit
4181 if (isDigit$5(first)) {
4182 // Return true.
4183 return 1;
4184 }
4185
4186 // anything else
4187 // Return false.
4188 return 0;
4189}
4190
4191//
4192// Misc
4193//
4194
4195// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
4196function isBOM$2(code) {
4197 // UTF-16BE
4198 if (code === 0xFEFF) {
4199 return 1;
4200 }
4201
4202 // UTF-16LE
4203 if (code === 0xFFFE) {
4204 return 1;
4205 }
4206
4207 return 0;
4208}
4209
4210// Fast code category
4211//
4212// https://drafts.csswg.org/css-syntax/#tokenizer-definitions
4213// > non-ASCII code point
4214// > A code point with a value equal to or greater than U+0080 <control>
4215// > name-start code point
4216// > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
4217// > name code point
4218// > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
4219// That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
4220var CATEGORY = new Array(0x80);
4221charCodeCategory$1.Eof = 0x80;
4222charCodeCategory$1.WhiteSpace = 0x82;
4223charCodeCategory$1.Digit = 0x83;
4224charCodeCategory$1.NameStart = 0x84;
4225charCodeCategory$1.NonPrintable = 0x85;
4226
4227for (var i = 0; i < CATEGORY.length; i++) {
4228 switch (true) {
4229 case isWhiteSpace$2(i):
4230 CATEGORY[i] = charCodeCategory$1.WhiteSpace;
4231 break;
4232
4233 case isDigit$5(i):
4234 CATEGORY[i] = charCodeCategory$1.Digit;
4235 break;
4236
4237 case isNameStart(i):
4238 CATEGORY[i] = charCodeCategory$1.NameStart;
4239 break;
4240
4241 case isNonPrintable(i):
4242 CATEGORY[i] = charCodeCategory$1.NonPrintable;
4243 break;
4244
4245 default:
4246 CATEGORY[i] = i || charCodeCategory$1.Eof;
4247 }
4248}
4249
4250function charCodeCategory$1(code) {
4251 return code < 0x80 ? CATEGORY[code] : charCodeCategory$1.NameStart;
4252}
4253var charCodeDefinitions$1 = {
4254 isDigit: isDigit$5,
4255 isHexDigit: isHexDigit$4,
4256 isUppercaseLetter: isUppercaseLetter$1,
4257 isLowercaseLetter: isLowercaseLetter,
4258 isLetter: isLetter,
4259 isNonAscii: isNonAscii,
4260 isNameStart: isNameStart,
4261 isName: isName$2,
4262 isNonPrintable: isNonPrintable,
4263 isNewline: isNewline$1,
4264 isWhiteSpace: isWhiteSpace$2,
4265 isValidEscape: isValidEscape$2,
4266 isIdentifierStart: isIdentifierStart$2,
4267 isNumberStart: isNumberStart$1,
4268
4269 isBOM: isBOM$2,
4270 charCodeCategory: charCodeCategory$1
4271};
4272
4273var charCodeDef = charCodeDefinitions$1;
4274var isDigit$4 = charCodeDef.isDigit;
4275var isHexDigit$3 = charCodeDef.isHexDigit;
4276var isUppercaseLetter = charCodeDef.isUppercaseLetter;
4277var isName$1 = charCodeDef.isName;
4278var isWhiteSpace$1 = charCodeDef.isWhiteSpace;
4279var isValidEscape$1 = charCodeDef.isValidEscape;
4280
4281function getCharCode(source, offset) {
4282 return offset < source.length ? source.charCodeAt(offset) : 0;
4283}
4284
4285function getNewlineLength$1(source, offset, code) {
4286 if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
4287 return 2;
4288 }
4289
4290 return 1;
4291}
4292
4293function cmpChar$5(testStr, offset, referenceCode) {
4294 var code = testStr.charCodeAt(offset);
4295
4296 // code.toLowerCase() for A..Z
4297 if (isUppercaseLetter(code)) {
4298 code = code | 32;
4299 }
4300
4301 return code === referenceCode;
4302}
4303
4304function cmpStr$6(testStr, start, end, referenceStr) {
4305 if (end - start !== referenceStr.length) {
4306 return false;
4307 }
4308
4309 if (start < 0 || end > testStr.length) {
4310 return false;
4311 }
4312
4313 for (var i = start; i < end; i++) {
4314 var testCode = testStr.charCodeAt(i);
4315 var referenceCode = referenceStr.charCodeAt(i - start);
4316
4317 // testCode.toLowerCase() for A..Z
4318 if (isUppercaseLetter(testCode)) {
4319 testCode = testCode | 32;
4320 }
4321
4322 if (testCode !== referenceCode) {
4323 return false;
4324 }
4325 }
4326
4327 return true;
4328}
4329
4330function findWhiteSpaceStart$1(source, offset) {
4331 for (; offset >= 0; offset--) {
4332 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
4333 break;
4334 }
4335 }
4336
4337 return offset + 1;
4338}
4339
4340function findWhiteSpaceEnd$1(source, offset) {
4341 for (; offset < source.length; offset++) {
4342 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
4343 break;
4344 }
4345 }
4346
4347 return offset;
4348}
4349
4350function findDecimalNumberEnd(source, offset) {
4351 for (; offset < source.length; offset++) {
4352 if (!isDigit$4(source.charCodeAt(offset))) {
4353 break;
4354 }
4355 }
4356
4357 return offset;
4358}
4359
4360// § 4.3.7. Consume an escaped code point
4361function consumeEscaped$1(source, offset) {
4362 // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
4363 // that the next input code point has already been verified to be part of a valid escape.
4364 offset += 2;
4365
4366 // hex digit
4367 if (isHexDigit$3(getCharCode(source, offset - 1))) {
4368 // Consume as many hex digits as possible, but no more than 5.
4369 // Note that this means 1-6 hex digits have been consumed in total.
4370 for (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
4371 if (!isHexDigit$3(getCharCode(source, offset))) {
4372 break;
4373 }
4374 }
4375
4376 // If the next input code point is whitespace, consume it as well.
4377 var code = getCharCode(source, offset);
4378 if (isWhiteSpace$1(code)) {
4379 offset += getNewlineLength$1(source, offset, code);
4380 }
4381 }
4382
4383 return offset;
4384}
4385
4386// §4.3.11. Consume a name
4387// Note: This algorithm does not do the verification of the first few code points that are necessary
4388// to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
4389// ensure that the stream starts with an identifier before calling this algorithm.
4390function consumeName$1(source, offset) {
4391 // Let result initially be an empty string.
4392 // Repeatedly consume the next input code point from the stream:
4393 for (; offset < source.length; offset++) {
4394 var code = source.charCodeAt(offset);
4395
4396 // name code point
4397 if (isName$1(code)) {
4398 // Append the code point to result.
4399 continue;
4400 }
4401
4402 // the stream starts with a valid escape
4403 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
4404 // Consume an escaped code point. Append the returned code point to result.
4405 offset = consumeEscaped$1(source, offset) - 1;
4406 continue;
4407 }
4408
4409 // anything else
4410 // Reconsume the current input code point. Return result.
4411 break;
4412 }
4413
4414 return offset;
4415}
4416
4417// §4.3.12. Consume a number
4418function consumeNumber$5(source, offset) {
4419 var code = source.charCodeAt(offset);
4420
4421 // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
4422 // consume it and append it to repr.
4423 if (code === 0x002B || code === 0x002D) {
4424 code = source.charCodeAt(offset += 1);
4425 }
4426
4427 // 3. While the next input code point is a digit, consume it and append it to repr.
4428 if (isDigit$4(code)) {
4429 offset = findDecimalNumberEnd(source, offset + 1);
4430 code = source.charCodeAt(offset);
4431 }
4432
4433 // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
4434 if (code === 0x002E && isDigit$4(source.charCodeAt(offset + 1))) {
4435 // 4.1 Consume them.
4436 // 4.2 Append them to repr.
4437 code = source.charCodeAt(offset += 2);
4438
4439 // 4.3 Set type to "number".
4440 // TODO
4441
4442 // 4.4 While the next input code point is a digit, consume it and append it to repr.
4443
4444 offset = findDecimalNumberEnd(source, offset);
4445 }
4446
4447 // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
4448 // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
4449 if (cmpChar$5(source, offset, 101 /* e */)) {
4450 var sign = 0;
4451 code = source.charCodeAt(offset + 1);
4452
4453 // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
4454 if (code === 0x002D || code === 0x002B) {
4455 sign = 1;
4456 code = source.charCodeAt(offset + 2);
4457 }
4458
4459 // ... followed by a digit
4460 if (isDigit$4(code)) {
4461 // 5.1 Consume them.
4462 // 5.2 Append them to repr.
4463
4464 // 5.3 Set type to "number".
4465 // TODO
4466
4467 // 5.4 While the next input code point is a digit, consume it and append it to repr.
4468 offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
4469 }
4470 }
4471
4472 return offset;
4473}
4474
4475// § 4.3.14. Consume the remnants of a bad url
4476// ... its sole use is to consume enough of the input stream to reach a recovery point
4477// where normal tokenizing can resume.
4478function consumeBadUrlRemnants$1(source, offset) {
4479 // Repeatedly consume the next input code point from the stream:
4480 for (; offset < source.length; offset++) {
4481 var code = source.charCodeAt(offset);
4482
4483 // U+0029 RIGHT PARENTHESIS ())
4484 // EOF
4485 if (code === 0x0029) {
4486 // Return.
4487 offset++;
4488 break;
4489 }
4490
4491 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
4492 // Consume an escaped code point.
4493 // Note: This allows an escaped right parenthesis ("\)") to be encountered
4494 // without ending the <bad-url-token>. This is otherwise identical to
4495 // the "anything else" clause.
4496 offset = consumeEscaped$1(source, offset);
4497 }
4498 }
4499
4500 return offset;
4501}
4502
4503var utils$2 = {
4504 consumeEscaped: consumeEscaped$1,
4505 consumeName: consumeName$1,
4506 consumeNumber: consumeNumber$5,
4507 consumeBadUrlRemnants: consumeBadUrlRemnants$1,
4508
4509 cmpChar: cmpChar$5,
4510 cmpStr: cmpStr$6,
4511
4512 getNewlineLength: getNewlineLength$1,
4513 findWhiteSpaceStart: findWhiteSpaceStart$1,
4514 findWhiteSpaceEnd: findWhiteSpaceEnd$1
4515};
4516
4517var constants$2 = _const;
4518var TYPE$G = constants$2.TYPE;
4519var NAME$2 = constants$2.NAME;
4520
4521var utils$1 = utils$2;
4522var cmpStr$5 = utils$1.cmpStr;
4523
4524var EOF = TYPE$G.EOF;
4525var WHITESPACE$c = TYPE$G.WhiteSpace;
4526var COMMENT$a = TYPE$G.Comment;
4527
4528var OFFSET_MASK$1 = 0x00FFFFFF;
4529var TYPE_SHIFT$1 = 24;
4530
4531var TokenStream$4 = function() {
4532 this.offsetAndType = null;
4533 this.balance = null;
4534
4535 this.reset();
4536};
4537
4538TokenStream$4.prototype = {
4539 reset: function() {
4540 this.eof = false;
4541 this.tokenIndex = -1;
4542 this.tokenType = 0;
4543 this.tokenStart = this.firstCharOffset;
4544 this.tokenEnd = this.firstCharOffset;
4545 },
4546
4547 lookupType: function(offset) {
4548 offset += this.tokenIndex;
4549
4550 if (offset < this.tokenCount) {
4551 return this.offsetAndType[offset] >> TYPE_SHIFT$1;
4552 }
4553
4554 return EOF;
4555 },
4556 lookupOffset: function(offset) {
4557 offset += this.tokenIndex;
4558
4559 if (offset < this.tokenCount) {
4560 return this.offsetAndType[offset - 1] & OFFSET_MASK$1;
4561 }
4562
4563 return this.source.length;
4564 },
4565 lookupValue: function(offset, referenceStr) {
4566 offset += this.tokenIndex;
4567
4568 if (offset < this.tokenCount) {
4569 return cmpStr$5(
4570 this.source,
4571 this.offsetAndType[offset - 1] & OFFSET_MASK$1,
4572 this.offsetAndType[offset] & OFFSET_MASK$1,
4573 referenceStr
4574 );
4575 }
4576
4577 return false;
4578 },
4579 getTokenStart: function(tokenIndex) {
4580 if (tokenIndex === this.tokenIndex) {
4581 return this.tokenStart;
4582 }
4583
4584 if (tokenIndex > 0) {
4585 return tokenIndex < this.tokenCount
4586 ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK$1
4587 : this.offsetAndType[this.tokenCount] & OFFSET_MASK$1;
4588 }
4589
4590 return this.firstCharOffset;
4591 },
4592
4593 // TODO: -> skipUntilBalanced
4594 getRawLength: function(startToken, mode) {
4595 var cursor = startToken;
4596 var balanceEnd;
4597 var offset = this.offsetAndType[Math.max(cursor - 1, 0)] & OFFSET_MASK$1;
4598 var type;
4599
4600 loop:
4601 for (; cursor < this.tokenCount; cursor++) {
4602 balanceEnd = this.balance[cursor];
4603
4604 // stop scanning on balance edge that points to offset before start token
4605 if (balanceEnd < startToken) {
4606 break loop;
4607 }
4608
4609 type = this.offsetAndType[cursor] >> TYPE_SHIFT$1;
4610
4611 // check token is stop type
4612 switch (mode(type, this.source, offset)) {
4613 case 1:
4614 break loop;
4615
4616 case 2:
4617 cursor++;
4618 break loop;
4619
4620 default:
4621 // fast forward to the end of balanced block
4622 if (this.balance[balanceEnd] === cursor) {
4623 cursor = balanceEnd;
4624 }
4625
4626 offset = this.offsetAndType[cursor] & OFFSET_MASK$1;
4627 }
4628 }
4629
4630 return cursor - this.tokenIndex;
4631 },
4632 isBalanceEdge: function(pos) {
4633 return this.balance[this.tokenIndex] < pos;
4634 },
4635 isDelim: function(code, offset) {
4636 if (offset) {
4637 return (
4638 this.lookupType(offset) === TYPE$G.Delim &&
4639 this.source.charCodeAt(this.lookupOffset(offset)) === code
4640 );
4641 }
4642
4643 return (
4644 this.tokenType === TYPE$G.Delim &&
4645 this.source.charCodeAt(this.tokenStart) === code
4646 );
4647 },
4648
4649 getTokenValue: function() {
4650 return this.source.substring(this.tokenStart, this.tokenEnd);
4651 },
4652 getTokenLength: function() {
4653 return this.tokenEnd - this.tokenStart;
4654 },
4655 substrToCursor: function(start) {
4656 return this.source.substring(start, this.tokenStart);
4657 },
4658
4659 skipWS: function() {
4660 for (var i = this.tokenIndex, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
4661 if ((this.offsetAndType[i] >> TYPE_SHIFT$1) !== WHITESPACE$c) {
4662 break;
4663 }
4664 }
4665
4666 if (skipTokenCount > 0) {
4667 this.skip(skipTokenCount);
4668 }
4669 },
4670 skipSC: function() {
4671 while (this.tokenType === WHITESPACE$c || this.tokenType === COMMENT$a) {
4672 this.next();
4673 }
4674 },
4675 skip: function(tokenCount) {
4676 var next = this.tokenIndex + tokenCount;
4677
4678 if (next < this.tokenCount) {
4679 this.tokenIndex = next;
4680 this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK$1;
4681 next = this.offsetAndType[next];
4682 this.tokenType = next >> TYPE_SHIFT$1;
4683 this.tokenEnd = next & OFFSET_MASK$1;
4684 } else {
4685 this.tokenIndex = this.tokenCount;
4686 this.next();
4687 }
4688 },
4689 next: function() {
4690 var next = this.tokenIndex + 1;
4691
4692 if (next < this.tokenCount) {
4693 this.tokenIndex = next;
4694 this.tokenStart = this.tokenEnd;
4695 next = this.offsetAndType[next];
4696 this.tokenType = next >> TYPE_SHIFT$1;
4697 this.tokenEnd = next & OFFSET_MASK$1;
4698 } else {
4699 this.tokenIndex = this.tokenCount;
4700 this.eof = true;
4701 this.tokenType = EOF;
4702 this.tokenStart = this.tokenEnd = this.source.length;
4703 }
4704 },
4705
4706 forEachToken(fn) {
4707 for (var i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) {
4708 var start = offset;
4709 var item = this.offsetAndType[i];
4710 var end = item & OFFSET_MASK$1;
4711 var type = item >> TYPE_SHIFT$1;
4712
4713 offset = end;
4714
4715 fn(type, start, end, i);
4716 }
4717 },
4718
4719 dump() {
4720 var tokens = new Array(this.tokenCount);
4721
4722 this.forEachToken((type, start, end, index) => {
4723 tokens[index] = {
4724 idx: index,
4725 type: NAME$2[type],
4726 chunk: this.source.substring(start, end),
4727 balance: this.balance[index]
4728 };
4729 });
4730
4731 return tokens;
4732 }
4733};
4734
4735var TokenStream_1 = TokenStream$4;
4736
4737function noop$3(value) {
4738 return value;
4739}
4740
4741function generateMultiplier(multiplier) {
4742 if (multiplier.min === 0 && multiplier.max === 0) {
4743 return '*';
4744 }
4745
4746 if (multiplier.min === 0 && multiplier.max === 1) {
4747 return '?';
4748 }
4749
4750 if (multiplier.min === 1 && multiplier.max === 0) {
4751 return multiplier.comma ? '#' : '+';
4752 }
4753
4754 if (multiplier.min === 1 && multiplier.max === 1) {
4755 return '';
4756 }
4757
4758 return (
4759 (multiplier.comma ? '#' : '') +
4760 (multiplier.min === multiplier.max
4761 ? '{' + multiplier.min + '}'
4762 : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}'
4763 )
4764 );
4765}
4766
4767function generateTypeOpts(node) {
4768 switch (node.type) {
4769 case 'Range':
4770 return (
4771 ' [' +
4772 (node.min === null ? '-∞' : node.min) +
4773 ',' +
4774 (node.max === null ? '∞' : node.max) +
4775 ']'
4776 );
4777
4778 default:
4779 throw new Error('Unknown node type `' + node.type + '`');
4780 }
4781}
4782
4783function generateSequence(node, decorate, forceBraces, compact) {
4784 var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
4785 var result = node.terms.map(function(term) {
4786 return generate$2(term, decorate, forceBraces, compact);
4787 }).join(combinator);
4788
4789 if (node.explicit || forceBraces) {
4790 result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
4791 }
4792
4793 return result;
4794}
4795
4796function generate$2(node, decorate, forceBraces, compact) {
4797 var result;
4798
4799 switch (node.type) {
4800 case 'Group':
4801 result =
4802 generateSequence(node, decorate, forceBraces, compact) +
4803 (node.disallowEmpty ? '!' : '');
4804 break;
4805
4806 case 'Multiplier':
4807 // return since node is a composition
4808 return (
4809 generate$2(node.term, decorate, forceBraces, compact) +
4810 decorate(generateMultiplier(node), node)
4811 );
4812
4813 case 'Type':
4814 result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
4815 break;
4816
4817 case 'Property':
4818 result = '<\'' + node.name + '\'>';
4819 break;
4820
4821 case 'Keyword':
4822 result = node.name;
4823 break;
4824
4825 case 'AtKeyword':
4826 result = '@' + node.name;
4827 break;
4828
4829 case 'Function':
4830 result = node.name + '(';
4831 break;
4832
4833 case 'String':
4834 case 'Token':
4835 result = node.value;
4836 break;
4837
4838 case 'Comma':
4839 result = ',';
4840 break;
4841
4842 default:
4843 throw new Error('Unknown node type `' + node.type + '`');
4844 }
4845
4846 return decorate(result, node);
4847}
4848
4849var generate_1 = function(node, options) {
4850 var decorate = noop$3;
4851 var forceBraces = false;
4852 var compact = false;
4853
4854 if (typeof options === 'function') {
4855 decorate = options;
4856 } else if (options) {
4857 forceBraces = Boolean(options.forceBraces);
4858 compact = Boolean(options.compact);
4859 if (typeof options.decorate === 'function') {
4860 decorate = options.decorate;
4861 }
4862 }
4863
4864 return generate$2(node, decorate, forceBraces, compact);
4865};
4866
4867const createCustomError$1 = createCustomError$3;
4868const generate$1 = generate_1;
4869const defaultLoc = { offset: 0, line: 1, column: 1 };
4870
4871function locateMismatch(matchResult, node) {
4872 const tokens = matchResult.tokens;
4873 const longestMatch = matchResult.longestMatch;
4874 const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
4875 const badNode = mismatchNode !== node ? mismatchNode : null;
4876 let mismatchOffset = 0;
4877 let mismatchLength = 0;
4878 let entries = 0;
4879 let css = '';
4880 let start;
4881 let end;
4882
4883 for (let i = 0; i < tokens.length; i++) {
4884 const token = tokens[i].value;
4885
4886 if (i === longestMatch) {
4887 mismatchLength = token.length;
4888 mismatchOffset = css.length;
4889 }
4890
4891 if (badNode !== null && tokens[i].node === badNode) {
4892 if (i <= longestMatch) {
4893 entries++;
4894 } else {
4895 entries = 0;
4896 }
4897 }
4898
4899 css += token;
4900 }
4901
4902 if (longestMatch === tokens.length || entries > 1) { // last
4903 start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
4904 end = buildLoc(start);
4905 } else {
4906 start = fromLoc(badNode, 'start') ||
4907 buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));
4908 end = fromLoc(badNode, 'end') ||
4909 buildLoc(start, css.substr(mismatchOffset, mismatchLength));
4910 }
4911
4912 return {
4913 css,
4914 mismatchOffset,
4915 mismatchLength,
4916 start,
4917 end
4918 };
4919}
4920
4921function fromLoc(node, point) {
4922 const value = node && node.loc && node.loc[point];
4923
4924 if (value) {
4925 return 'line' in value ? buildLoc(value) : value;
4926 }
4927
4928 return null;
4929}
4930
4931function buildLoc({ offset, line, column }, extra) {
4932 const loc = {
4933 offset,
4934 line,
4935 column
4936 };
4937
4938 if (extra) {
4939 const lines = extra.split(/\n|\r\n?|\f/);
4940
4941 loc.offset += extra.length;
4942 loc.line += lines.length - 1;
4943 loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
4944 }
4945
4946 return loc;
4947}
4948
4949const SyntaxReferenceError$1 = function(type, referenceName) {
4950 const error = createCustomError$1(
4951 'SyntaxReferenceError',
4952 type + (referenceName ? ' `' + referenceName + '`' : '')
4953 );
4954
4955 error.reference = referenceName;
4956
4957 return error;
4958};
4959
4960const SyntaxMatchError$1 = function(message, syntax, node, matchResult) {
4961 const error = createCustomError$1('SyntaxMatchError', message);
4962 const {
4963 css,
4964 mismatchOffset,
4965 mismatchLength,
4966 start,
4967 end
4968 } = locateMismatch(matchResult, node);
4969
4970 error.rawMessage = message;
4971 error.syntax = syntax ? generate$1(syntax) : '<generic>';
4972 error.css = css;
4973 error.mismatchOffset = mismatchOffset;
4974 error.mismatchLength = mismatchLength;
4975 error.message = message + '\n' +
4976 ' syntax: ' + error.syntax + '\n' +
4977 ' value: ' + (css || '<empty string>') + '\n' +
4978 ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
4979
4980 Object.assign(error, start);
4981 error.loc = {
4982 source: (node && node.loc && node.loc.source) || '<unknown>',
4983 start,
4984 end
4985 };
4986
4987 return error;
4988};
4989
4990var error = {
4991 SyntaxReferenceError: SyntaxReferenceError$1,
4992 SyntaxMatchError: SyntaxMatchError$1
4993};
4994
4995var hasOwnProperty$7 = Object.prototype.hasOwnProperty;
4996var keywords$1 = Object.create(null);
4997var properties$1 = Object.create(null);
4998var HYPHENMINUS$5 = 45; // '-'.charCodeAt()
4999
5000function isCustomProperty$1(str, offset) {
5001 offset = offset || 0;
5002
5003 return str.length - offset >= 2 &&
5004 str.charCodeAt(offset) === HYPHENMINUS$5 &&
5005 str.charCodeAt(offset + 1) === HYPHENMINUS$5;
5006}
5007
5008function getVendorPrefix(str, offset) {
5009 offset = offset || 0;
5010
5011 // verdor prefix should be at least 3 chars length
5012 if (str.length - offset >= 3) {
5013 // vendor prefix starts with hyper minus following non-hyper minus
5014 if (str.charCodeAt(offset) === HYPHENMINUS$5 &&
5015 str.charCodeAt(offset + 1) !== HYPHENMINUS$5) {
5016 // vendor prefix should contain a hyper minus at the ending
5017 var secondDashIndex = str.indexOf('-', offset + 2);
5018
5019 if (secondDashIndex !== -1) {
5020 return str.substring(offset, secondDashIndex + 1);
5021 }
5022 }
5023 }
5024
5025 return '';
5026}
5027
5028function getKeywordDescriptor(keyword) {
5029 if (hasOwnProperty$7.call(keywords$1, keyword)) {
5030 return keywords$1[keyword];
5031 }
5032
5033 var name = keyword.toLowerCase();
5034
5035 if (hasOwnProperty$7.call(keywords$1, name)) {
5036 return keywords$1[keyword] = keywords$1[name];
5037 }
5038
5039 var custom = isCustomProperty$1(name, 0);
5040 var vendor = !custom ? getVendorPrefix(name, 0) : '';
5041
5042 return keywords$1[keyword] = Object.freeze({
5043 basename: name.substr(vendor.length),
5044 name: name,
5045 vendor: vendor,
5046 prefix: vendor,
5047 custom: custom
5048 });
5049}
5050
5051function getPropertyDescriptor(property) {
5052 if (hasOwnProperty$7.call(properties$1, property)) {
5053 return properties$1[property];
5054 }
5055
5056 var name = property;
5057 var hack = property[0];
5058
5059 if (hack === '/') {
5060 hack = property[1] === '/' ? '//' : '/';
5061 } else if (hack !== '_' &&
5062 hack !== '*' &&
5063 hack !== '$' &&
5064 hack !== '#' &&
5065 hack !== '+' &&
5066 hack !== '&') {
5067 hack = '';
5068 }
5069
5070 var custom = isCustomProperty$1(name, hack.length);
5071
5072 // re-use result when possible (the same as for lower case)
5073 if (!custom) {
5074 name = name.toLowerCase();
5075 if (hasOwnProperty$7.call(properties$1, name)) {
5076 return properties$1[property] = properties$1[name];
5077 }
5078 }
5079
5080 var vendor = !custom ? getVendorPrefix(name, hack.length) : '';
5081 var prefix = name.substr(0, hack.length + vendor.length);
5082
5083 return properties$1[property] = Object.freeze({
5084 basename: name.substr(prefix.length),
5085 name: name.substr(hack.length),
5086 hack: hack,
5087 vendor: vendor,
5088 prefix: prefix,
5089 custom: custom
5090 });
5091}
5092
5093var names$2 = {
5094 keyword: getKeywordDescriptor,
5095 property: getPropertyDescriptor,
5096 isCustomProperty: isCustomProperty$1,
5097 vendorPrefix: getVendorPrefix
5098};
5099
5100var MIN_SIZE = 16 * 1024;
5101var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
5102
5103var adoptBuffer$2 = function adoptBuffer(buffer, size) {
5104 if (buffer === null || buffer.length < size) {
5105 return new SafeUint32Array(Math.max(size + 1024, MIN_SIZE));
5106 }
5107
5108 return buffer;
5109};
5110
5111var TokenStream$3 = TokenStream_1;
5112var adoptBuffer$1 = adoptBuffer$2;
5113
5114var constants$1 = _const;
5115var TYPE$F = constants$1.TYPE;
5116
5117var charCodeDefinitions = charCodeDefinitions$1;
5118var isNewline = charCodeDefinitions.isNewline;
5119var isName = charCodeDefinitions.isName;
5120var isValidEscape = charCodeDefinitions.isValidEscape;
5121var isNumberStart = charCodeDefinitions.isNumberStart;
5122var isIdentifierStart$1 = charCodeDefinitions.isIdentifierStart;
5123var charCodeCategory = charCodeDefinitions.charCodeCategory;
5124var isBOM$1 = charCodeDefinitions.isBOM;
5125
5126var utils = utils$2;
5127var cmpStr$4 = utils.cmpStr;
5128var getNewlineLength = utils.getNewlineLength;
5129var findWhiteSpaceEnd = utils.findWhiteSpaceEnd;
5130var consumeEscaped = utils.consumeEscaped;
5131var consumeName = utils.consumeName;
5132var consumeNumber$4 = utils.consumeNumber;
5133var consumeBadUrlRemnants = utils.consumeBadUrlRemnants;
5134
5135var OFFSET_MASK = 0x00FFFFFF;
5136var TYPE_SHIFT = 24;
5137
5138function tokenize$3(source, stream) {
5139 function getCharCode(offset) {
5140 return offset < sourceLength ? source.charCodeAt(offset) : 0;
5141 }
5142
5143 // § 4.3.3. Consume a numeric token
5144 function consumeNumericToken() {
5145 // Consume a number and let number be the result.
5146 offset = consumeNumber$4(source, offset);
5147
5148 // If the next 3 input code points would start an identifier, then:
5149 if (isIdentifierStart$1(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
5150 // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
5151 // Consume a name. Set the <dimension-token>’s unit to the returned value.
5152 // Return the <dimension-token>.
5153 type = TYPE$F.Dimension;
5154 offset = consumeName(source, offset);
5155 return;
5156 }
5157
5158 // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
5159 if (getCharCode(offset) === 0x0025) {
5160 // Create a <percentage-token> with the same value as number, and return it.
5161 type = TYPE$F.Percentage;
5162 offset++;
5163 return;
5164 }
5165
5166 // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
5167 type = TYPE$F.Number;
5168 }
5169
5170 // § 4.3.4. Consume an ident-like token
5171 function consumeIdentLikeToken() {
5172 const nameStartOffset = offset;
5173
5174 // Consume a name, and let string be the result.
5175 offset = consumeName(source, offset);
5176
5177 // If string’s value is an ASCII case-insensitive match for "url",
5178 // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
5179 if (cmpStr$4(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
5180 // While the next two input code points are whitespace, consume the next input code point.
5181 offset = findWhiteSpaceEnd(source, offset + 1);
5182
5183 // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
5184 // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
5185 // then create a <function-token> with its value set to string and return it.
5186 if (getCharCode(offset) === 0x0022 ||
5187 getCharCode(offset) === 0x0027) {
5188 type = TYPE$F.Function;
5189 offset = nameStartOffset + 4;
5190 return;
5191 }
5192
5193 // Otherwise, consume a url token, and return it.
5194 consumeUrlToken();
5195 return;
5196 }
5197
5198 // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
5199 // Create a <function-token> with its value set to string and return it.
5200 if (getCharCode(offset) === 0x0028) {
5201 type = TYPE$F.Function;
5202 offset++;
5203 return;
5204 }
5205
5206 // Otherwise, create an <ident-token> with its value set to string and return it.
5207 type = TYPE$F.Ident;
5208 }
5209
5210 // § 4.3.5. Consume a string token
5211 function consumeStringToken(endingCodePoint) {
5212 // This algorithm may be called with an ending code point, which denotes the code point
5213 // that ends the string. If an ending code point is not specified,
5214 // the current input code point is used.
5215 if (!endingCodePoint) {
5216 endingCodePoint = getCharCode(offset++);
5217 }
5218
5219 // Initially create a <string-token> with its value set to the empty string.
5220 type = TYPE$F.String;
5221
5222 // Repeatedly consume the next input code point from the stream:
5223 for (; offset < source.length; offset++) {
5224 var code = source.charCodeAt(offset);
5225
5226 switch (charCodeCategory(code)) {
5227 // ending code point
5228 case endingCodePoint:
5229 // Return the <string-token>.
5230 offset++;
5231 return;
5232
5233 // EOF
5234 case charCodeCategory.Eof:
5235 // This is a parse error. Return the <string-token>.
5236 return;
5237
5238 // newline
5239 case charCodeCategory.WhiteSpace:
5240 if (isNewline(code)) {
5241 // This is a parse error. Reconsume the current input code point,
5242 // create a <bad-string-token>, and return it.
5243 offset += getNewlineLength(source, offset, code);
5244 type = TYPE$F.BadString;
5245 return;
5246 }
5247 break;
5248
5249 // U+005C REVERSE SOLIDUS (\)
5250 case 0x005C:
5251 // If the next input code point is EOF, do nothing.
5252 if (offset === source.length - 1) {
5253 break;
5254 }
5255
5256 var nextCode = getCharCode(offset + 1);
5257
5258 // Otherwise, if the next input code point is a newline, consume it.
5259 if (isNewline(nextCode)) {
5260 offset += getNewlineLength(source, offset + 1, nextCode);
5261 } else if (isValidEscape(code, nextCode)) {
5262 // Otherwise, (the stream starts with a valid escape) consume
5263 // an escaped code point and append the returned code point to
5264 // the <string-token>’s value.
5265 offset = consumeEscaped(source, offset) - 1;
5266 }
5267 break;
5268
5269 // anything else
5270 // Append the current input code point to the <string-token>’s value.
5271 }
5272 }
5273 }
5274
5275 // § 4.3.6. Consume a url token
5276 // Note: This algorithm assumes that the initial "url(" has already been consumed.
5277 // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
5278 // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
5279 // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
5280 function consumeUrlToken() {
5281 // Initially create a <url-token> with its value set to the empty string.
5282 type = TYPE$F.Url;
5283
5284 // Consume as much whitespace as possible.
5285 offset = findWhiteSpaceEnd(source, offset);
5286
5287 // Repeatedly consume the next input code point from the stream:
5288 for (; offset < source.length; offset++) {
5289 var code = source.charCodeAt(offset);
5290
5291 switch (charCodeCategory(code)) {
5292 // U+0029 RIGHT PARENTHESIS ())
5293 case 0x0029:
5294 // Return the <url-token>.
5295 offset++;
5296 return;
5297
5298 // EOF
5299 case charCodeCategory.Eof:
5300 // This is a parse error. Return the <url-token>.
5301 return;
5302
5303 // whitespace
5304 case charCodeCategory.WhiteSpace:
5305 // Consume as much whitespace as possible.
5306 offset = findWhiteSpaceEnd(source, offset);
5307
5308 // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
5309 // consume it and return the <url-token>
5310 // (if EOF was encountered, this is a parse error);
5311 if (getCharCode(offset) === 0x0029 || offset >= source.length) {
5312 if (offset < source.length) {
5313 offset++;
5314 }
5315 return;
5316 }
5317
5318 // otherwise, consume the remnants of a bad url, create a <bad-url-token>,
5319 // and return it.
5320 offset = consumeBadUrlRemnants(source, offset);
5321 type = TYPE$F.BadUrl;
5322 return;
5323
5324 // U+0022 QUOTATION MARK (")
5325 // U+0027 APOSTROPHE (')
5326 // U+0028 LEFT PARENTHESIS (()
5327 // non-printable code point
5328 case 0x0022:
5329 case 0x0027:
5330 case 0x0028:
5331 case charCodeCategory.NonPrintable:
5332 // This is a parse error. Consume the remnants of a bad url,
5333 // create a <bad-url-token>, and return it.
5334 offset = consumeBadUrlRemnants(source, offset);
5335 type = TYPE$F.BadUrl;
5336 return;
5337
5338 // U+005C REVERSE SOLIDUS (\)
5339 case 0x005C:
5340 // If the stream starts with a valid escape, consume an escaped code point and
5341 // append the returned code point to the <url-token>’s value.
5342 if (isValidEscape(code, getCharCode(offset + 1))) {
5343 offset = consumeEscaped(source, offset) - 1;
5344 break;
5345 }
5346
5347 // Otherwise, this is a parse error. Consume the remnants of a bad url,
5348 // create a <bad-url-token>, and return it.
5349 offset = consumeBadUrlRemnants(source, offset);
5350 type = TYPE$F.BadUrl;
5351 return;
5352
5353 // anything else
5354 // Append the current input code point to the <url-token>’s value.
5355 }
5356 }
5357 }
5358
5359 if (!stream) {
5360 stream = new TokenStream$3();
5361 }
5362
5363 // ensure source is a string
5364 source = String(source || '');
5365
5366 var sourceLength = source.length;
5367 var offsetAndType = adoptBuffer$1(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
5368 var balance = adoptBuffer$1(stream.balance, sourceLength + 1);
5369 var tokenCount = 0;
5370 var start = isBOM$1(getCharCode(0));
5371 var offset = start;
5372 var balanceCloseType = 0;
5373 var balanceStart = 0;
5374 var balancePrev = 0;
5375
5376 // https://drafts.csswg.org/css-syntax-3/#consume-token
5377 // § 4.3.1. Consume a token
5378 while (offset < sourceLength) {
5379 var code = source.charCodeAt(offset);
5380 var type = 0;
5381
5382 balance[tokenCount] = sourceLength;
5383
5384 switch (charCodeCategory(code)) {
5385 // whitespace
5386 case charCodeCategory.WhiteSpace:
5387 // Consume as much whitespace as possible. Return a <whitespace-token>.
5388 type = TYPE$F.WhiteSpace;
5389 offset = findWhiteSpaceEnd(source, offset + 1);
5390 break;
5391
5392 // U+0022 QUOTATION MARK (")
5393 case 0x0022:
5394 // Consume a string token and return it.
5395 consumeStringToken();
5396 break;
5397
5398 // U+0023 NUMBER SIGN (#)
5399 case 0x0023:
5400 // If the next input code point is a name code point or the next two input code points are a valid escape, then:
5401 if (isName(getCharCode(offset + 1)) || isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) {
5402 // Create a <hash-token>.
5403 type = TYPE$F.Hash;
5404
5405 // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
5406 // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
5407 // // TODO: set id flag
5408 // }
5409
5410 // Consume a name, and set the <hash-token>’s value to the returned string.
5411 offset = consumeName(source, offset + 1);
5412
5413 // Return the <hash-token>.
5414 } else {
5415 // Otherwise, return a <delim-token> with its value set to the current input code point.
5416 type = TYPE$F.Delim;
5417 offset++;
5418 }
5419
5420 break;
5421
5422 // U+0027 APOSTROPHE (')
5423 case 0x0027:
5424 // Consume a string token and return it.
5425 consumeStringToken();
5426 break;
5427
5428 // U+0028 LEFT PARENTHESIS (()
5429 case 0x0028:
5430 // Return a <(-token>.
5431 type = TYPE$F.LeftParenthesis;
5432 offset++;
5433 break;
5434
5435 // U+0029 RIGHT PARENTHESIS ())
5436 case 0x0029:
5437 // Return a <)-token>.
5438 type = TYPE$F.RightParenthesis;
5439 offset++;
5440 break;
5441
5442 // U+002B PLUS SIGN (+)
5443 case 0x002B:
5444 // If the input stream starts with a number, ...
5445 if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5446 // ... reconsume the current input code point, consume a numeric token, and return it.
5447 consumeNumericToken();
5448 } else {
5449 // Otherwise, return a <delim-token> with its value set to the current input code point.
5450 type = TYPE$F.Delim;
5451 offset++;
5452 }
5453 break;
5454
5455 // U+002C COMMA (,)
5456 case 0x002C:
5457 // Return a <comma-token>.
5458 type = TYPE$F.Comma;
5459 offset++;
5460 break;
5461
5462 // U+002D HYPHEN-MINUS (-)
5463 case 0x002D:
5464 // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
5465 if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5466 consumeNumericToken();
5467 } else {
5468 // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
5469 if (getCharCode(offset + 1) === 0x002D &&
5470 getCharCode(offset + 2) === 0x003E) {
5471 type = TYPE$F.CDC;
5472 offset = offset + 3;
5473 } else {
5474 // Otherwise, if the input stream starts with an identifier, ...
5475 if (isIdentifierStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5476 // ... reconsume the current input code point, consume an ident-like token, and return it.
5477 consumeIdentLikeToken();
5478 } else {
5479 // Otherwise, return a <delim-token> with its value set to the current input code point.
5480 type = TYPE$F.Delim;
5481 offset++;
5482 }
5483 }
5484 }
5485 break;
5486
5487 // U+002E FULL STOP (.)
5488 case 0x002E:
5489 // If the input stream starts with a number, ...
5490 if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
5491 // ... reconsume the current input code point, consume a numeric token, and return it.
5492 consumeNumericToken();
5493 } else {
5494 // Otherwise, return a <delim-token> with its value set to the current input code point.
5495 type = TYPE$F.Delim;
5496 offset++;
5497 }
5498
5499 break;
5500
5501 // U+002F SOLIDUS (/)
5502 case 0x002F:
5503 // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
5504 if (getCharCode(offset + 1) === 0x002A) {
5505 // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
5506 // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
5507 type = TYPE$F.Comment;
5508 offset = source.indexOf('*/', offset + 2) + 2;
5509 if (offset === 1) {
5510 offset = source.length;
5511 }
5512 } else {
5513 type = TYPE$F.Delim;
5514 offset++;
5515 }
5516 break;
5517
5518 // U+003A COLON (:)
5519 case 0x003A:
5520 // Return a <colon-token>.
5521 type = TYPE$F.Colon;
5522 offset++;
5523 break;
5524
5525 // U+003B SEMICOLON (;)
5526 case 0x003B:
5527 // Return a <semicolon-token>.
5528 type = TYPE$F.Semicolon;
5529 offset++;
5530 break;
5531
5532 // U+003C LESS-THAN SIGN (<)
5533 case 0x003C:
5534 // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
5535 if (getCharCode(offset + 1) === 0x0021 &&
5536 getCharCode(offset + 2) === 0x002D &&
5537 getCharCode(offset + 3) === 0x002D) {
5538 // ... consume them and return a <CDO-token>.
5539 type = TYPE$F.CDO;
5540 offset = offset + 4;
5541 } else {
5542 // Otherwise, return a <delim-token> with its value set to the current input code point.
5543 type = TYPE$F.Delim;
5544 offset++;
5545 }
5546
5547 break;
5548
5549 // U+0040 COMMERCIAL AT (@)
5550 case 0x0040:
5551 // If the next 3 input code points would start an identifier, ...
5552 if (isIdentifierStart$1(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
5553 // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
5554 type = TYPE$F.AtKeyword;
5555 offset = consumeName(source, offset + 1);
5556 } else {
5557 // Otherwise, return a <delim-token> with its value set to the current input code point.
5558 type = TYPE$F.Delim;
5559 offset++;
5560 }
5561
5562 break;
5563
5564 // U+005B LEFT SQUARE BRACKET ([)
5565 case 0x005B:
5566 // Return a <[-token>.
5567 type = TYPE$F.LeftSquareBracket;
5568 offset++;
5569 break;
5570
5571 // U+005C REVERSE SOLIDUS (\)
5572 case 0x005C:
5573 // If the input stream starts with a valid escape, ...
5574 if (isValidEscape(code, getCharCode(offset + 1))) {
5575 // ... reconsume the current input code point, consume an ident-like token, and return it.
5576 consumeIdentLikeToken();
5577 } else {
5578 // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
5579 type = TYPE$F.Delim;
5580 offset++;
5581 }
5582 break;
5583
5584 // U+005D RIGHT SQUARE BRACKET (])
5585 case 0x005D:
5586 // Return a <]-token>.
5587 type = TYPE$F.RightSquareBracket;
5588 offset++;
5589 break;
5590
5591 // U+007B LEFT CURLY BRACKET ({)
5592 case 0x007B:
5593 // Return a <{-token>.
5594 type = TYPE$F.LeftCurlyBracket;
5595 offset++;
5596 break;
5597
5598 // U+007D RIGHT CURLY BRACKET (})
5599 case 0x007D:
5600 // Return a <}-token>.
5601 type = TYPE$F.RightCurlyBracket;
5602 offset++;
5603 break;
5604
5605 // digit
5606 case charCodeCategory.Digit:
5607 // Reconsume the current input code point, consume a numeric token, and return it.
5608 consumeNumericToken();
5609 break;
5610
5611 // name-start code point
5612 case charCodeCategory.NameStart:
5613 // Reconsume the current input code point, consume an ident-like token, and return it.
5614 consumeIdentLikeToken();
5615 break;
5616
5617 // EOF
5618 case charCodeCategory.Eof:
5619 // Return an <EOF-token>.
5620 break;
5621
5622 // anything else
5623 default:
5624 // Return a <delim-token> with its value set to the current input code point.
5625 type = TYPE$F.Delim;
5626 offset++;
5627 }
5628
5629 switch (type) {
5630 case balanceCloseType:
5631 balancePrev = balanceStart & OFFSET_MASK;
5632 balanceStart = balance[balancePrev];
5633 balanceCloseType = balanceStart >> TYPE_SHIFT;
5634 balance[tokenCount] = balancePrev;
5635 balance[balancePrev++] = tokenCount;
5636 for (; balancePrev < tokenCount; balancePrev++) {
5637 if (balance[balancePrev] === sourceLength) {
5638 balance[balancePrev] = tokenCount;
5639 }
5640 }
5641 break;
5642
5643 case TYPE$F.LeftParenthesis:
5644 case TYPE$F.Function:
5645 balance[tokenCount] = balanceStart;
5646 balanceCloseType = TYPE$F.RightParenthesis;
5647 balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
5648 break;
5649
5650 case TYPE$F.LeftSquareBracket:
5651 balance[tokenCount] = balanceStart;
5652 balanceCloseType = TYPE$F.RightSquareBracket;
5653 balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
5654 break;
5655
5656 case TYPE$F.LeftCurlyBracket:
5657 balance[tokenCount] = balanceStart;
5658 balanceCloseType = TYPE$F.RightCurlyBracket;
5659 balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
5660 break;
5661 }
5662
5663 offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | offset;
5664 }
5665
5666 // finalize buffers
5667 offsetAndType[tokenCount] = (TYPE$F.EOF << TYPE_SHIFT) | offset; // <EOF-token>
5668 balance[tokenCount] = sourceLength;
5669 balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
5670 while (balanceStart !== 0) {
5671 balancePrev = balanceStart & OFFSET_MASK;
5672 balanceStart = balance[balancePrev];
5673 balance[balancePrev] = sourceLength;
5674 }
5675
5676 // update stream
5677 stream.source = source;
5678 stream.firstCharOffset = start;
5679 stream.offsetAndType = offsetAndType;
5680 stream.tokenCount = tokenCount;
5681 stream.balance = balance;
5682 stream.reset();
5683 stream.next();
5684
5685 return stream;
5686}
5687
5688// extend tokenizer with constants
5689Object.keys(constants$1).forEach(function(key) {
5690 tokenize$3[key] = constants$1[key];
5691});
5692
5693// extend tokenizer with static methods from utils
5694Object.keys(charCodeDefinitions).forEach(function(key) {
5695 tokenize$3[key] = charCodeDefinitions[key];
5696});
5697Object.keys(utils).forEach(function(key) {
5698 tokenize$3[key] = utils[key];
5699});
5700
5701var tokenizer$3 = tokenize$3;
5702
5703var isDigit$3 = tokenizer$3.isDigit;
5704var cmpChar$4 = tokenizer$3.cmpChar;
5705var TYPE$E = tokenizer$3.TYPE;
5706
5707var DELIM$6 = TYPE$E.Delim;
5708var WHITESPACE$b = TYPE$E.WhiteSpace;
5709var COMMENT$9 = TYPE$E.Comment;
5710var IDENT$i = TYPE$E.Ident;
5711var NUMBER$9 = TYPE$E.Number;
5712var DIMENSION$7 = TYPE$E.Dimension;
5713var PLUSSIGN$8 = 0x002B; // U+002B PLUS SIGN (+)
5714var HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)
5715var N$4 = 0x006E; // U+006E LATIN SMALL LETTER N (n)
5716var DISALLOW_SIGN$1 = true;
5717var ALLOW_SIGN$1 = false;
5718
5719function isDelim$1(token, code) {
5720 return token !== null && token.type === DELIM$6 && token.value.charCodeAt(0) === code;
5721}
5722
5723function skipSC(token, offset, getNextToken) {
5724 while (token !== null && (token.type === WHITESPACE$b || token.type === COMMENT$9)) {
5725 token = getNextToken(++offset);
5726 }
5727
5728 return offset;
5729}
5730
5731function checkInteger$1(token, valueOffset, disallowSign, offset) {
5732 if (!token) {
5733 return 0;
5734 }
5735
5736 var code = token.value.charCodeAt(valueOffset);
5737
5738 if (code === PLUSSIGN$8 || code === HYPHENMINUS$4) {
5739 if (disallowSign) {
5740 // Number sign is not allowed
5741 return 0;
5742 }
5743 valueOffset++;
5744 }
5745
5746 for (; valueOffset < token.value.length; valueOffset++) {
5747 if (!isDigit$3(token.value.charCodeAt(valueOffset))) {
5748 // Integer is expected
5749 return 0;
5750 }
5751 }
5752
5753 return offset + 1;
5754}
5755
5756// ... <signed-integer>
5757// ... ['+' | '-'] <signless-integer>
5758function consumeB$1(token, offset_, getNextToken) {
5759 var sign = false;
5760 var offset = skipSC(token, offset_, getNextToken);
5761
5762 token = getNextToken(offset);
5763
5764 if (token === null) {
5765 return offset_;
5766 }
5767
5768 if (token.type !== NUMBER$9) {
5769 if (isDelim$1(token, PLUSSIGN$8) || isDelim$1(token, HYPHENMINUS$4)) {
5770 sign = true;
5771 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5772 token = getNextToken(offset);
5773
5774 if (token === null && token.type !== NUMBER$9) {
5775 return 0;
5776 }
5777 } else {
5778 return offset_;
5779 }
5780 }
5781
5782 if (!sign) {
5783 var code = token.value.charCodeAt(0);
5784 if (code !== PLUSSIGN$8 && code !== HYPHENMINUS$4) {
5785 // Number sign is expected
5786 return 0;
5787 }
5788 }
5789
5790 return checkInteger$1(token, sign ? 0 : 1, sign, offset);
5791}
5792
5793// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
5794var genericAnPlusB = function anPlusB(token, getNextToken) {
5795 /* eslint-disable brace-style*/
5796 var offset = 0;
5797
5798 if (!token) {
5799 return 0;
5800 }
5801
5802 // <integer>
5803 if (token.type === NUMBER$9) {
5804 return checkInteger$1(token, 0, ALLOW_SIGN$1, offset); // b
5805 }
5806
5807 // -n
5808 // -n <signed-integer>
5809 // -n ['+' | '-'] <signless-integer>
5810 // -n- <signless-integer>
5811 // <dashndashdigit-ident>
5812 else if (token.type === IDENT$i && token.value.charCodeAt(0) === HYPHENMINUS$4) {
5813 // expect 1st char is N
5814 if (!cmpChar$4(token.value, 1, N$4)) {
5815 return 0;
5816 }
5817
5818 switch (token.value.length) {
5819 // -n
5820 // -n <signed-integer>
5821 // -n ['+' | '-'] <signless-integer>
5822 case 2:
5823 return consumeB$1(getNextToken(++offset), offset, getNextToken);
5824
5825 // -n- <signless-integer>
5826 case 3:
5827 if (token.value.charCodeAt(2) !== HYPHENMINUS$4) {
5828 return 0;
5829 }
5830
5831 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5832 token = getNextToken(offset);
5833
5834 return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);
5835
5836 // <dashndashdigit-ident>
5837 default:
5838 if (token.value.charCodeAt(2) !== HYPHENMINUS$4) {
5839 return 0;
5840 }
5841
5842 return checkInteger$1(token, 3, DISALLOW_SIGN$1, offset);
5843 }
5844 }
5845
5846 // '+'? n
5847 // '+'? n <signed-integer>
5848 // '+'? n ['+' | '-'] <signless-integer>
5849 // '+'? n- <signless-integer>
5850 // '+'? <ndashdigit-ident>
5851 else if (token.type === IDENT$i || (isDelim$1(token, PLUSSIGN$8) && getNextToken(offset + 1).type === IDENT$i)) {
5852 // just ignore a plus
5853 if (token.type !== IDENT$i) {
5854 token = getNextToken(++offset);
5855 }
5856
5857 if (token === null || !cmpChar$4(token.value, 0, N$4)) {
5858 return 0;
5859 }
5860
5861 switch (token.value.length) {
5862 // '+'? n
5863 // '+'? n <signed-integer>
5864 // '+'? n ['+' | '-'] <signless-integer>
5865 case 1:
5866 return consumeB$1(getNextToken(++offset), offset, getNextToken);
5867
5868 // '+'? n- <signless-integer>
5869 case 2:
5870 if (token.value.charCodeAt(1) !== HYPHENMINUS$4) {
5871 return 0;
5872 }
5873
5874 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5875 token = getNextToken(offset);
5876
5877 return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);
5878
5879 // '+'? <ndashdigit-ident>
5880 default:
5881 if (token.value.charCodeAt(1) !== HYPHENMINUS$4) {
5882 return 0;
5883 }
5884
5885 return checkInteger$1(token, 2, DISALLOW_SIGN$1, offset);
5886 }
5887 }
5888
5889 // <ndashdigit-dimension>
5890 // <ndash-dimension> <signless-integer>
5891 // <n-dimension>
5892 // <n-dimension> <signed-integer>
5893 // <n-dimension> ['+' | '-'] <signless-integer>
5894 else if (token.type === DIMENSION$7) {
5895 var code = token.value.charCodeAt(0);
5896 var sign = code === PLUSSIGN$8 || code === HYPHENMINUS$4 ? 1 : 0;
5897
5898 for (var i = sign; i < token.value.length; i++) {
5899 if (!isDigit$3(token.value.charCodeAt(i))) {
5900 break;
5901 }
5902 }
5903
5904 if (i === sign) {
5905 // Integer is expected
5906 return 0;
5907 }
5908
5909 if (!cmpChar$4(token.value, i, N$4)) {
5910 return 0;
5911 }
5912
5913 // <n-dimension>
5914 // <n-dimension> <signed-integer>
5915 // <n-dimension> ['+' | '-'] <signless-integer>
5916 if (i + 1 === token.value.length) {
5917 return consumeB$1(getNextToken(++offset), offset, getNextToken);
5918 } else {
5919 if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$4) {
5920 return 0;
5921 }
5922
5923 // <ndash-dimension> <signless-integer>
5924 if (i + 2 === token.value.length) {
5925 offset = skipSC(getNextToken(++offset), offset, getNextToken);
5926 token = getNextToken(offset);
5927
5928 return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);
5929 }
5930 // <ndashdigit-dimension>
5931 else {
5932 return checkInteger$1(token, i + 2, DISALLOW_SIGN$1, offset);
5933 }
5934 }
5935 }
5936
5937 return 0;
5938};
5939
5940var isHexDigit$2 = tokenizer$3.isHexDigit;
5941var cmpChar$3 = tokenizer$3.cmpChar;
5942var TYPE$D = tokenizer$3.TYPE;
5943
5944var IDENT$h = TYPE$D.Ident;
5945var DELIM$5 = TYPE$D.Delim;
5946var NUMBER$8 = TYPE$D.Number;
5947var DIMENSION$6 = TYPE$D.Dimension;
5948var PLUSSIGN$7 = 0x002B; // U+002B PLUS SIGN (+)
5949var HYPHENMINUS$3 = 0x002D; // U+002D HYPHEN-MINUS (-)
5950var QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)
5951var U$2 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
5952
5953function isDelim(token, code) {
5954 return token !== null && token.type === DELIM$5 && token.value.charCodeAt(0) === code;
5955}
5956
5957function startsWith$1(token, code) {
5958 return token.value.charCodeAt(0) === code;
5959}
5960
5961function hexSequence(token, offset, allowDash) {
5962 for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
5963 var code = token.value.charCodeAt(pos);
5964
5965 if (code === HYPHENMINUS$3 && allowDash && hexlen !== 0) {
5966 if (hexSequence(token, offset + hexlen + 1, false) > 0) {
5967 return 6; // dissallow following question marks
5968 }
5969
5970 return 0; // dash at the ending of a hex sequence is not allowed
5971 }
5972
5973 if (!isHexDigit$2(code)) {
5974 return 0; // not a hex digit
5975 }
5976
5977 if (++hexlen > 6) {
5978 return 0; // too many hex digits
5979 } }
5980
5981 return hexlen;
5982}
5983
5984function withQuestionMarkSequence(consumed, length, getNextToken) {
5985 if (!consumed) {
5986 return 0; // nothing consumed
5987 }
5988
5989 while (isDelim(getNextToken(length), QUESTIONMARK$2)) {
5990 if (++consumed > 6) {
5991 return 0; // too many question marks
5992 }
5993
5994 length++;
5995 }
5996
5997 return length;
5998}
5999
6000// https://drafts.csswg.org/css-syntax/#urange
6001// Informally, the <urange> production has three forms:
6002// U+0001
6003// Defines a range consisting of a single code point, in this case the code point "1".
6004// U+0001-00ff
6005// Defines a range of codepoints between the first and the second value, in this case
6006// the range between "1" and "ff" (255 in decimal) inclusive.
6007// U+00??
6008// Defines a range of codepoints where the "?" characters range over all hex digits,
6009// in this case defining the same as the value U+0000-00ff.
6010// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
6011//
6012// <urange> =
6013// u '+' <ident-token> '?'* |
6014// u <dimension-token> '?'* |
6015// u <number-token> '?'* |
6016// u <number-token> <dimension-token> |
6017// u <number-token> <number-token> |
6018// u '+' '?'+
6019var genericUrange = function urange(token, getNextToken) {
6020 var length = 0;
6021
6022 // should start with `u` or `U`
6023 if (token === null || token.type !== IDENT$h || !cmpChar$3(token.value, 0, U$2)) {
6024 return 0;
6025 }
6026
6027 token = getNextToken(++length);
6028 if (token === null) {
6029 return 0;
6030 }
6031
6032 // u '+' <ident-token> '?'*
6033 // u '+' '?'+
6034 if (isDelim(token, PLUSSIGN$7)) {
6035 token = getNextToken(++length);
6036 if (token === null) {
6037 return 0;
6038 }
6039
6040 if (token.type === IDENT$h) {
6041 // u '+' <ident-token> '?'*
6042 return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
6043 }
6044
6045 if (isDelim(token, QUESTIONMARK$2)) {
6046 // u '+' '?'+
6047 return withQuestionMarkSequence(1, ++length, getNextToken);
6048 }
6049
6050 // Hex digit or question mark is expected
6051 return 0;
6052 }
6053
6054 // u <number-token> '?'*
6055 // u <number-token> <dimension-token>
6056 // u <number-token> <number-token>
6057 if (token.type === NUMBER$8) {
6058 if (!startsWith$1(token, PLUSSIGN$7)) {
6059 return 0;
6060 }
6061
6062 var consumedHexLength = hexSequence(token, 1, true);
6063 if (consumedHexLength === 0) {
6064 return 0;
6065 }
6066
6067 token = getNextToken(++length);
6068 if (token === null) {
6069 // u <number-token> <eof>
6070 return length;
6071 }
6072
6073 if (token.type === DIMENSION$6 || token.type === NUMBER$8) {
6074 // u <number-token> <dimension-token>
6075 // u <number-token> <number-token>
6076 if (!startsWith$1(token, HYPHENMINUS$3) || !hexSequence(token, 1, false)) {
6077 return 0;
6078 }
6079
6080 return length + 1;
6081 }
6082
6083 // u <number-token> '?'*
6084 return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
6085 }
6086
6087 // u <dimension-token> '?'*
6088 if (token.type === DIMENSION$6) {
6089 if (!startsWith$1(token, PLUSSIGN$7)) {
6090 return 0;
6091 }
6092
6093 return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
6094 }
6095
6096 return 0;
6097};
6098
6099var tokenizer$2 = tokenizer$3;
6100var isIdentifierStart = tokenizer$2.isIdentifierStart;
6101var isHexDigit$1 = tokenizer$2.isHexDigit;
6102var isDigit$2 = tokenizer$2.isDigit;
6103var cmpStr$3 = tokenizer$2.cmpStr;
6104var consumeNumber$3 = tokenizer$2.consumeNumber;
6105var TYPE$C = tokenizer$2.TYPE;
6106var anPlusB = genericAnPlusB;
6107var urange = genericUrange;
6108
6109var cssWideKeywords$1 = ['unset', 'initial', 'inherit'];
6110var calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
6111
6112// https://www.w3.org/TR/css-values-3/#lengths
6113var LENGTH = {
6114 // absolute length units
6115 'px': true,
6116 'mm': true,
6117 'cm': true,
6118 'in': true,
6119 'pt': true,
6120 'pc': true,
6121 'q': true,
6122
6123 // relative length units
6124 'em': true,
6125 'ex': true,
6126 'ch': true,
6127 'rem': true,
6128
6129 // viewport-percentage lengths
6130 'vh': true,
6131 'vw': true,
6132 'vmin': true,
6133 'vmax': true,
6134 'vm': true
6135};
6136
6137var ANGLE = {
6138 'deg': true,
6139 'grad': true,
6140 'rad': true,
6141 'turn': true
6142};
6143
6144var TIME = {
6145 's': true,
6146 'ms': true
6147};
6148
6149var FREQUENCY = {
6150 'hz': true,
6151 'khz': true
6152};
6153
6154// https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
6155var RESOLUTION = {
6156 'dpi': true,
6157 'dpcm': true,
6158 'dppx': true,
6159 'x': true // https://github.com/w3c/csswg-drafts/issues/461
6160};
6161
6162// https://drafts.csswg.org/css-grid/#fr-unit
6163var FLEX = {
6164 'fr': true
6165};
6166
6167// https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
6168var DECIBEL = {
6169 'db': true
6170};
6171
6172// https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
6173var SEMITONES = {
6174 'st': true
6175};
6176
6177// safe char code getter
6178function charCode(str, index) {
6179 return index < str.length ? str.charCodeAt(index) : 0;
6180}
6181
6182function eqStr(actual, expected) {
6183 return cmpStr$3(actual, 0, actual.length, expected);
6184}
6185
6186function eqStrAny(actual, expected) {
6187 for (var i = 0; i < expected.length; i++) {
6188 if (eqStr(actual, expected[i])) {
6189 return true;
6190 }
6191 }
6192
6193 return false;
6194}
6195
6196// IE postfix hack, i.e. 123\0 or 123px\9
6197function isPostfixIeHack(str, offset) {
6198 if (offset !== str.length - 2) {
6199 return false;
6200 }
6201
6202 return (
6203 str.charCodeAt(offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
6204 isDigit$2(str.charCodeAt(offset + 1))
6205 );
6206}
6207
6208function outOfRange(opts, value, numEnd) {
6209 if (opts && opts.type === 'Range') {
6210 var num = Number(
6211 numEnd !== undefined && numEnd !== value.length
6212 ? value.substr(0, numEnd)
6213 : value
6214 );
6215
6216 if (isNaN(num)) {
6217 return true;
6218 }
6219
6220 if (opts.min !== null && num < opts.min) {
6221 return true;
6222 }
6223
6224 if (opts.max !== null && num > opts.max) {
6225 return true;
6226 }
6227 }
6228
6229 return false;
6230}
6231
6232function consumeFunction(token, getNextToken) {
6233 var startIdx = token.index;
6234 var length = 0;
6235
6236 // balanced token consuming
6237 do {
6238 length++;
6239
6240 if (token.balance <= startIdx) {
6241 break;
6242 }
6243 } while (token = getNextToken(length));
6244
6245 return length;
6246}
6247
6248// TODO: implement
6249// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
6250// https://drafts.csswg.org/css-values/#calc-notation
6251function calc(next) {
6252 return function(token, getNextToken, opts) {
6253 if (token === null) {
6254 return 0;
6255 }
6256
6257 if (token.type === TYPE$C.Function && eqStrAny(token.value, calcFunctionNames)) {
6258 return consumeFunction(token, getNextToken);
6259 }
6260
6261 return next(token, getNextToken, opts);
6262 };
6263}
6264
6265function tokenType(expectedTokenType) {
6266 return function(token) {
6267 if (token === null || token.type !== expectedTokenType) {
6268 return 0;
6269 }
6270
6271 return 1;
6272 };
6273}
6274
6275function func(name) {
6276 name = name + '(';
6277
6278 return function(token, getNextToken) {
6279 if (token !== null && eqStr(token.value, name)) {
6280 return consumeFunction(token, getNextToken);
6281 }
6282
6283 return 0;
6284 };
6285}
6286
6287// =========================
6288// Complex types
6289//
6290
6291// https://drafts.csswg.org/css-values-4/#custom-idents
6292// 4.2. Author-defined Identifiers: the <custom-ident> type
6293// Some properties accept arbitrary author-defined identifiers as a component value.
6294// This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
6295// that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
6296//
6297// See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
6298function customIdent(token) {
6299 if (token === null || token.type !== TYPE$C.Ident) {
6300 return 0;
6301 }
6302
6303 var name = token.value.toLowerCase();
6304
6305 // The CSS-wide keywords are not valid <custom-ident>s
6306 if (eqStrAny(name, cssWideKeywords$1)) {
6307 return 0;
6308 }
6309
6310 // The default keyword is reserved and is also not a valid <custom-ident>
6311 if (eqStr(name, 'default')) {
6312 return 0;
6313 }
6314
6315 // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
6316 // Specifications using <custom-ident> must specify clearly what other keywords
6317 // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
6318 // in that property’s value definition are excluded. Excluded keywords are excluded
6319 // in all ASCII case permutations.
6320
6321 return 1;
6322}
6323
6324// https://drafts.csswg.org/css-variables/#typedef-custom-property-name
6325// A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
6326// The <custom-property-name> production corresponds to this: it’s defined as any valid identifier
6327// that starts with two dashes, except -- itself, which is reserved for future use by CSS.
6328// NOTE: Current implementation treat `--` as a valid name since most (all?) major browsers treat it as valid.
6329function customPropertyName(token) {
6330 // ... defined as any valid identifier
6331 if (token === null || token.type !== TYPE$C.Ident) {
6332 return 0;
6333 }
6334
6335 // ... that starts with two dashes (U+002D HYPHEN-MINUS)
6336 if (charCode(token.value, 0) !== 0x002D || charCode(token.value, 1) !== 0x002D) {
6337 return 0;
6338 }
6339
6340 return 1;
6341}
6342
6343// https://drafts.csswg.org/css-color-4/#hex-notation
6344// The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
6345// In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
6346// letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
6347function hexColor(token) {
6348 if (token === null || token.type !== TYPE$C.Hash) {
6349 return 0;
6350 }
6351
6352 var length = token.value.length;
6353
6354 // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
6355 if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
6356 return 0;
6357 }
6358
6359 for (var i = 1; i < length; i++) {
6360 if (!isHexDigit$1(token.value.charCodeAt(i))) {
6361 return 0;
6362 }
6363 }
6364
6365 return 1;
6366}
6367
6368function idSelector(token) {
6369 if (token === null || token.type !== TYPE$C.Hash) {
6370 return 0;
6371 }
6372
6373 if (!isIdentifierStart(charCode(token.value, 1), charCode(token.value, 2), charCode(token.value, 3))) {
6374 return 0;
6375 }
6376
6377 return 1;
6378}
6379
6380// https://drafts.csswg.org/css-syntax/#any-value
6381// It represents the entirety of what a valid declaration can have as its value.
6382function declarationValue(token, getNextToken) {
6383 if (!token) {
6384 return 0;
6385 }
6386
6387 var length = 0;
6388 var level = 0;
6389 var startIdx = token.index;
6390
6391 // The <declaration-value> production matches any sequence of one or more tokens,
6392 // so long as the sequence ...
6393 scan:
6394 do {
6395 switch (token.type) {
6396 // ... does not contain <bad-string-token>, <bad-url-token>,
6397 case TYPE$C.BadString:
6398 case TYPE$C.BadUrl:
6399 break scan;
6400
6401 // ... unmatched <)-token>, <]-token>, or <}-token>,
6402 case TYPE$C.RightCurlyBracket:
6403 case TYPE$C.RightParenthesis:
6404 case TYPE$C.RightSquareBracket:
6405 if (token.balance > token.index || token.balance < startIdx) {
6406 break scan;
6407 }
6408
6409 level--;
6410 break;
6411
6412 // ... or top-level <semicolon-token> tokens
6413 case TYPE$C.Semicolon:
6414 if (level === 0) {
6415 break scan;
6416 }
6417
6418 break;
6419
6420 // ... or <delim-token> tokens with a value of "!"
6421 case TYPE$C.Delim:
6422 if (token.value === '!' && level === 0) {
6423 break scan;
6424 }
6425
6426 break;
6427
6428 case TYPE$C.Function:
6429 case TYPE$C.LeftParenthesis:
6430 case TYPE$C.LeftSquareBracket:
6431 case TYPE$C.LeftCurlyBracket:
6432 level++;
6433 break;
6434 }
6435
6436 length++;
6437
6438 // until balance closing
6439 if (token.balance <= startIdx) {
6440 break;
6441 }
6442 } while (token = getNextToken(length));
6443
6444 return length;
6445}
6446
6447// https://drafts.csswg.org/css-syntax/#any-value
6448// The <any-value> production is identical to <declaration-value>, but also
6449// allows top-level <semicolon-token> tokens and <delim-token> tokens
6450// with a value of "!". It represents the entirety of what valid CSS can be in any context.
6451function anyValue(token, getNextToken) {
6452 if (!token) {
6453 return 0;
6454 }
6455
6456 var startIdx = token.index;
6457 var length = 0;
6458
6459 // The <any-value> production matches any sequence of one or more tokens,
6460 // so long as the sequence ...
6461 scan:
6462 do {
6463 switch (token.type) {
6464 // ... does not contain <bad-string-token>, <bad-url-token>,
6465 case TYPE$C.BadString:
6466 case TYPE$C.BadUrl:
6467 break scan;
6468
6469 // ... unmatched <)-token>, <]-token>, or <}-token>,
6470 case TYPE$C.RightCurlyBracket:
6471 case TYPE$C.RightParenthesis:
6472 case TYPE$C.RightSquareBracket:
6473 if (token.balance > token.index || token.balance < startIdx) {
6474 break scan;
6475 }
6476
6477 break;
6478 }
6479
6480 length++;
6481
6482 // until balance closing
6483 if (token.balance <= startIdx) {
6484 break;
6485 }
6486 } while (token = getNextToken(length));
6487
6488 return length;
6489}
6490
6491// =========================
6492// Dimensions
6493//
6494
6495function dimension(type) {
6496 return function(token, getNextToken, opts) {
6497 if (token === null || token.type !== TYPE$C.Dimension) {
6498 return 0;
6499 }
6500
6501 var numberEnd = consumeNumber$3(token.value, 0);
6502
6503 // check unit
6504 if (type !== null) {
6505 // check for IE postfix hack, i.e. 123px\0 or 123px\9
6506 var reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
6507 var unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
6508 ? token.value.substr(numberEnd)
6509 : token.value.substring(numberEnd, reverseSolidusOffset);
6510
6511 if (type.hasOwnProperty(unit.toLowerCase()) === false) {
6512 return 0;
6513 }
6514 }
6515
6516 // check range if specified
6517 if (outOfRange(opts, token.value, numberEnd)) {
6518 return 0;
6519 }
6520
6521 return 1;
6522 };
6523}
6524
6525// =========================
6526// Percentage
6527//
6528
6529// §5.5. Percentages: the <percentage> type
6530// https://drafts.csswg.org/css-values-4/#percentages
6531function percentage(token, getNextToken, opts) {
6532 // ... corresponds to the <percentage-token> production
6533 if (token === null || token.type !== TYPE$C.Percentage) {
6534 return 0;
6535 }
6536
6537 // check range if specified
6538 if (outOfRange(opts, token.value, token.value.length - 1)) {
6539 return 0;
6540 }
6541
6542 return 1;
6543}
6544
6545// =========================
6546// Numeric
6547//
6548
6549// https://drafts.csswg.org/css-values-4/#numbers
6550// The value <zero> represents a literal number with the value 0. Expressions that merely
6551// evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
6552// only literal <number-token>s do.
6553function zero(next) {
6554 if (typeof next !== 'function') {
6555 next = function() {
6556 return 0;
6557 };
6558 }
6559
6560 return function(token, getNextToken, opts) {
6561 if (token !== null && token.type === TYPE$C.Number) {
6562 if (Number(token.value) === 0) {
6563 return 1;
6564 }
6565 }
6566
6567 return next(token, getNextToken, opts);
6568 };
6569}
6570
6571// § 5.3. Real Numbers: the <number> type
6572// https://drafts.csswg.org/css-values-4/#numbers
6573// Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
6574// ... It corresponds to the <number-token> production
6575function number(token, getNextToken, opts) {
6576 if (token === null) {
6577 return 0;
6578 }
6579
6580 var numberEnd = consumeNumber$3(token.value, 0);
6581 var isNumber = numberEnd === token.value.length;
6582 if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
6583 return 0;
6584 }
6585
6586 // check range if specified
6587 if (outOfRange(opts, token.value, numberEnd)) {
6588 return 0;
6589 }
6590
6591 return 1;
6592}
6593
6594// §5.2. Integers: the <integer> type
6595// https://drafts.csswg.org/css-values-4/#integers
6596function integer(token, getNextToken, opts) {
6597 // ... corresponds to a subset of the <number-token> production
6598 if (token === null || token.type !== TYPE$C.Number) {
6599 return 0;
6600 }
6601
6602 // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
6603 var i = token.value.charCodeAt(0) === 0x002B || // U+002B PLUS SIGN (+)
6604 token.value.charCodeAt(0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
6605
6606 // When written literally, an integer is one or more decimal digits 0 through 9 ...
6607 for (; i < token.value.length; i++) {
6608 if (!isDigit$2(token.value.charCodeAt(i))) {
6609 return 0;
6610 }
6611 }
6612
6613 // check range if specified
6614 if (outOfRange(opts, token.value, i)) {
6615 return 0;
6616 }
6617
6618 return 1;
6619}
6620
6621var generic$1 = {
6622 // token types
6623 'ident-token': tokenType(TYPE$C.Ident),
6624 'function-token': tokenType(TYPE$C.Function),
6625 'at-keyword-token': tokenType(TYPE$C.AtKeyword),
6626 'hash-token': tokenType(TYPE$C.Hash),
6627 'string-token': tokenType(TYPE$C.String),
6628 'bad-string-token': tokenType(TYPE$C.BadString),
6629 'url-token': tokenType(TYPE$C.Url),
6630 'bad-url-token': tokenType(TYPE$C.BadUrl),
6631 'delim-token': tokenType(TYPE$C.Delim),
6632 'number-token': tokenType(TYPE$C.Number),
6633 'percentage-token': tokenType(TYPE$C.Percentage),
6634 'dimension-token': tokenType(TYPE$C.Dimension),
6635 'whitespace-token': tokenType(TYPE$C.WhiteSpace),
6636 'CDO-token': tokenType(TYPE$C.CDO),
6637 'CDC-token': tokenType(TYPE$C.CDC),
6638 'colon-token': tokenType(TYPE$C.Colon),
6639 'semicolon-token': tokenType(TYPE$C.Semicolon),
6640 'comma-token': tokenType(TYPE$C.Comma),
6641 '[-token': tokenType(TYPE$C.LeftSquareBracket),
6642 ']-token': tokenType(TYPE$C.RightSquareBracket),
6643 '(-token': tokenType(TYPE$C.LeftParenthesis),
6644 ')-token': tokenType(TYPE$C.RightParenthesis),
6645 '{-token': tokenType(TYPE$C.LeftCurlyBracket),
6646 '}-token': tokenType(TYPE$C.RightCurlyBracket),
6647
6648 // token type aliases
6649 'string': tokenType(TYPE$C.String),
6650 'ident': tokenType(TYPE$C.Ident),
6651
6652 // complex types
6653 'custom-ident': customIdent,
6654 'custom-property-name': customPropertyName,
6655 'hex-color': hexColor,
6656 'id-selector': idSelector, // element( <id-selector> )
6657 'an-plus-b': anPlusB,
6658 'urange': urange,
6659 'declaration-value': declarationValue,
6660 'any-value': anyValue,
6661
6662 // dimensions
6663 'dimension': calc(dimension(null)),
6664 'angle': calc(dimension(ANGLE)),
6665 'decibel': calc(dimension(DECIBEL)),
6666 'frequency': calc(dimension(FREQUENCY)),
6667 'flex': calc(dimension(FLEX)),
6668 'length': calc(zero(dimension(LENGTH))),
6669 'resolution': calc(dimension(RESOLUTION)),
6670 'semitones': calc(dimension(SEMITONES)),
6671 'time': calc(dimension(TIME)),
6672
6673 // percentage
6674 'percentage': calc(percentage),
6675
6676 // numeric
6677 'zero': zero(),
6678 'number': calc(number),
6679 'integer': calc(integer),
6680
6681 // old IE stuff
6682 '-ms-legacy-expression': func('expression')
6683};
6684
6685var createCustomError = createCustomError$3;
6686
6687var _SyntaxError = function SyntaxError(message, input, offset) {
6688 var error = createCustomError('SyntaxError', message);
6689
6690 error.input = input;
6691 error.offset = offset;
6692 error.rawMessage = message;
6693 error.message = error.rawMessage + '\n' +
6694 ' ' + error.input + '\n' +
6695 '--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';
6696
6697 return error;
6698};
6699
6700var SyntaxError$3 = _SyntaxError;
6701
6702var TAB$1 = 9;
6703var N$3 = 10;
6704var F$2 = 12;
6705var R$2 = 13;
6706var SPACE$2 = 32;
6707
6708var Tokenizer$1 = function(str) {
6709 this.str = str;
6710 this.pos = 0;
6711};
6712
6713Tokenizer$1.prototype = {
6714 charCodeAt: function(pos) {
6715 return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
6716 },
6717 charCode: function() {
6718 return this.charCodeAt(this.pos);
6719 },
6720 nextCharCode: function() {
6721 return this.charCodeAt(this.pos + 1);
6722 },
6723 nextNonWsCode: function(pos) {
6724 return this.charCodeAt(this.findWsEnd(pos));
6725 },
6726 findWsEnd: function(pos) {
6727 for (; pos < this.str.length; pos++) {
6728 var code = this.str.charCodeAt(pos);
6729 if (code !== R$2 && code !== N$3 && code !== F$2 && code !== SPACE$2 && code !== TAB$1) {
6730 break;
6731 }
6732 }
6733
6734 return pos;
6735 },
6736 substringToPos: function(end) {
6737 return this.str.substring(this.pos, this.pos = end);
6738 },
6739 eat: function(code) {
6740 if (this.charCode() !== code) {
6741 this.error('Expect `' + String.fromCharCode(code) + '`');
6742 }
6743
6744 this.pos++;
6745 },
6746 peek: function() {
6747 return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
6748 },
6749 error: function(message) {
6750 throw new SyntaxError$3(message, this.str, this.pos);
6751 }
6752};
6753
6754var tokenizer$1 = Tokenizer$1;
6755
6756var Tokenizer = tokenizer$1;
6757var TAB = 9;
6758var N$2 = 10;
6759var F$1 = 12;
6760var R$1 = 13;
6761var SPACE$1 = 32;
6762var EXCLAMATIONMARK$3 = 33; // !
6763var NUMBERSIGN$4 = 35; // #
6764var AMPERSAND$1 = 38; // &
6765var APOSTROPHE = 39; // '
6766var LEFTPARENTHESIS$7 = 40; // (
6767var RIGHTPARENTHESIS$7 = 41; // )
6768var ASTERISK$6 = 42; // *
6769var PLUSSIGN$6 = 43; // +
6770var COMMA$4 = 44; // ,
6771var HYPERMINUS = 45; // -
6772var LESSTHANSIGN = 60; // <
6773var GREATERTHANSIGN$2 = 62; // >
6774var QUESTIONMARK$1 = 63; // ?
6775var COMMERCIALAT = 64; // @
6776var LEFTSQUAREBRACKET$4 = 91; // [
6777var RIGHTSQUAREBRACKET$2 = 93; // ]
6778var LEFTCURLYBRACKET$4 = 123; // {
6779var VERTICALLINE$3 = 124; // |
6780var RIGHTCURLYBRACKET$2 = 125; // }
6781var INFINITY = 8734; // ∞
6782var NAME_CHAR = createCharMap(function(ch) {
6783 return /[a-zA-Z0-9\-]/.test(ch);
6784});
6785var COMBINATOR_PRECEDENCE = {
6786 ' ': 1,
6787 '&&': 2,
6788 '||': 3,
6789 '|': 4
6790};
6791
6792function createCharMap(fn) {
6793 var array = typeof Uint32Array === 'function' ? new Uint32Array(128) : new Array(128);
6794 for (var i = 0; i < 128; i++) {
6795 array[i] = fn(String.fromCharCode(i)) ? 1 : 0;
6796 }
6797 return array;
6798}
6799
6800function scanSpaces(tokenizer) {
6801 return tokenizer.substringToPos(
6802 tokenizer.findWsEnd(tokenizer.pos)
6803 );
6804}
6805
6806function scanWord(tokenizer) {
6807 var end = tokenizer.pos;
6808
6809 for (; end < tokenizer.str.length; end++) {
6810 var code = tokenizer.str.charCodeAt(end);
6811 if (code >= 128 || NAME_CHAR[code] === 0) {
6812 break;
6813 }
6814 }
6815
6816 if (tokenizer.pos === end) {
6817 tokenizer.error('Expect a keyword');
6818 }
6819
6820 return tokenizer.substringToPos(end);
6821}
6822
6823function scanNumber(tokenizer) {
6824 var end = tokenizer.pos;
6825
6826 for (; end < tokenizer.str.length; end++) {
6827 var code = tokenizer.str.charCodeAt(end);
6828 if (code < 48 || code > 57) {
6829 break;
6830 }
6831 }
6832
6833 if (tokenizer.pos === end) {
6834 tokenizer.error('Expect a number');
6835 }
6836
6837 return tokenizer.substringToPos(end);
6838}
6839
6840function scanString(tokenizer) {
6841 var end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
6842
6843 if (end === -1) {
6844 tokenizer.pos = tokenizer.str.length;
6845 tokenizer.error('Expect an apostrophe');
6846 }
6847
6848 return tokenizer.substringToPos(end + 1);
6849}
6850
6851function readMultiplierRange(tokenizer) {
6852 var min = null;
6853 var max = null;
6854
6855 tokenizer.eat(LEFTCURLYBRACKET$4);
6856
6857 min = scanNumber(tokenizer);
6858
6859 if (tokenizer.charCode() === COMMA$4) {
6860 tokenizer.pos++;
6861 if (tokenizer.charCode() !== RIGHTCURLYBRACKET$2) {
6862 max = scanNumber(tokenizer);
6863 }
6864 } else {
6865 max = min;
6866 }
6867
6868 tokenizer.eat(RIGHTCURLYBRACKET$2);
6869
6870 return {
6871 min: Number(min),
6872 max: max ? Number(max) : 0
6873 };
6874}
6875
6876function readMultiplier(tokenizer) {
6877 var range = null;
6878 var comma = false;
6879
6880 switch (tokenizer.charCode()) {
6881 case ASTERISK$6:
6882 tokenizer.pos++;
6883
6884 range = {
6885 min: 0,
6886 max: 0
6887 };
6888
6889 break;
6890
6891 case PLUSSIGN$6:
6892 tokenizer.pos++;
6893
6894 range = {
6895 min: 1,
6896 max: 0
6897 };
6898
6899 break;
6900
6901 case QUESTIONMARK$1:
6902 tokenizer.pos++;
6903
6904 range = {
6905 min: 0,
6906 max: 1
6907 };
6908
6909 break;
6910
6911 case NUMBERSIGN$4:
6912 tokenizer.pos++;
6913
6914 comma = true;
6915
6916 if (tokenizer.charCode() === LEFTCURLYBRACKET$4) {
6917 range = readMultiplierRange(tokenizer);
6918 } else {
6919 range = {
6920 min: 1,
6921 max: 0
6922 };
6923 }
6924
6925 break;
6926
6927 case LEFTCURLYBRACKET$4:
6928 range = readMultiplierRange(tokenizer);
6929 break;
6930
6931 default:
6932 return null;
6933 }
6934
6935 return {
6936 type: 'Multiplier',
6937 comma: comma,
6938 min: range.min,
6939 max: range.max,
6940 term: null
6941 };
6942}
6943
6944function maybeMultiplied(tokenizer, node) {
6945 var multiplier = readMultiplier(tokenizer);
6946
6947 if (multiplier !== null) {
6948 multiplier.term = node;
6949 return multiplier;
6950 }
6951
6952 return node;
6953}
6954
6955function maybeToken(tokenizer) {
6956 var ch = tokenizer.peek();
6957
6958 if (ch === '') {
6959 return null;
6960 }
6961
6962 return {
6963 type: 'Token',
6964 value: ch
6965 };
6966}
6967
6968function readProperty$1(tokenizer) {
6969 var name;
6970
6971 tokenizer.eat(LESSTHANSIGN);
6972 tokenizer.eat(APOSTROPHE);
6973
6974 name = scanWord(tokenizer);
6975
6976 tokenizer.eat(APOSTROPHE);
6977 tokenizer.eat(GREATERTHANSIGN$2);
6978
6979 return maybeMultiplied(tokenizer, {
6980 type: 'Property',
6981 name: name
6982 });
6983}
6984
6985// https://drafts.csswg.org/css-values-3/#numeric-ranges
6986// 4.1. Range Restrictions and Range Definition Notation
6987//
6988// Range restrictions can be annotated in the numeric type notation using CSS bracketed
6989// range notation—[min,max]—within the angle brackets, after the identifying keyword,
6990// indicating a closed range between (and including) min and max.
6991// For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
6992function readTypeRange(tokenizer) {
6993 // use null for Infinity to make AST format JSON serializable/deserializable
6994 var min = null; // -Infinity
6995 var max = null; // Infinity
6996 var sign = 1;
6997
6998 tokenizer.eat(LEFTSQUAREBRACKET$4);
6999
7000 if (tokenizer.charCode() === HYPERMINUS) {
7001 tokenizer.peek();
7002 sign = -1;
7003 }
7004
7005 if (sign == -1 && tokenizer.charCode() === INFINITY) {
7006 tokenizer.peek();
7007 } else {
7008 min = sign * Number(scanNumber(tokenizer));
7009 }
7010
7011 scanSpaces(tokenizer);
7012 tokenizer.eat(COMMA$4);
7013 scanSpaces(tokenizer);
7014
7015 if (tokenizer.charCode() === INFINITY) {
7016 tokenizer.peek();
7017 } else {
7018 sign = 1;
7019
7020 if (tokenizer.charCode() === HYPERMINUS) {
7021 tokenizer.peek();
7022 sign = -1;
7023 }
7024
7025 max = sign * Number(scanNumber(tokenizer));
7026 }
7027
7028 tokenizer.eat(RIGHTSQUAREBRACKET$2);
7029
7030 // If no range is indicated, either by using the bracketed range notation
7031 // or in the property description, then [−∞,∞] is assumed.
7032 if (min === null && max === null) {
7033 return null;
7034 }
7035
7036 return {
7037 type: 'Range',
7038 min: min,
7039 max: max
7040 };
7041}
7042
7043function readType(tokenizer) {
7044 var name;
7045 var opts = null;
7046
7047 tokenizer.eat(LESSTHANSIGN);
7048 name = scanWord(tokenizer);
7049
7050 if (tokenizer.charCode() === LEFTPARENTHESIS$7 &&
7051 tokenizer.nextCharCode() === RIGHTPARENTHESIS$7) {
7052 tokenizer.pos += 2;
7053 name += '()';
7054 }
7055
7056 if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET$4) {
7057 scanSpaces(tokenizer);
7058 opts = readTypeRange(tokenizer);
7059 }
7060
7061 tokenizer.eat(GREATERTHANSIGN$2);
7062
7063 return maybeMultiplied(tokenizer, {
7064 type: 'Type',
7065 name: name,
7066 opts: opts
7067 });
7068}
7069
7070function readKeywordOrFunction(tokenizer) {
7071 var name;
7072
7073 name = scanWord(tokenizer);
7074
7075 if (tokenizer.charCode() === LEFTPARENTHESIS$7) {
7076 tokenizer.pos++;
7077
7078 return {
7079 type: 'Function',
7080 name: name
7081 };
7082 }
7083
7084 return maybeMultiplied(tokenizer, {
7085 type: 'Keyword',
7086 name: name
7087 });
7088}
7089
7090function regroupTerms(terms, combinators) {
7091 function createGroup(terms, combinator) {
7092 return {
7093 type: 'Group',
7094 terms: terms,
7095 combinator: combinator,
7096 disallowEmpty: false,
7097 explicit: false
7098 };
7099 }
7100
7101 combinators = Object.keys(combinators).sort(function(a, b) {
7102 return COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b];
7103 });
7104
7105 while (combinators.length > 0) {
7106 var combinator = combinators.shift();
7107 for (var i = 0, subgroupStart = 0; i < terms.length; i++) {
7108 var term = terms[i];
7109 if (term.type === 'Combinator') {
7110 if (term.value === combinator) {
7111 if (subgroupStart === -1) {
7112 subgroupStart = i - 1;
7113 }
7114 terms.splice(i, 1);
7115 i--;
7116 } else {
7117 if (subgroupStart !== -1 && i - subgroupStart > 1) {
7118 terms.splice(
7119 subgroupStart,
7120 i - subgroupStart,
7121 createGroup(terms.slice(subgroupStart, i), combinator)
7122 );
7123 i = subgroupStart + 1;
7124 }
7125 subgroupStart = -1;
7126 }
7127 }
7128 }
7129
7130 if (subgroupStart !== -1 && combinators.length) {
7131 terms.splice(
7132 subgroupStart,
7133 i - subgroupStart,
7134 createGroup(terms.slice(subgroupStart, i), combinator)
7135 );
7136 }
7137 }
7138
7139 return combinator;
7140}
7141
7142function readImplicitGroup(tokenizer) {
7143 var terms = [];
7144 var combinators = {};
7145 var token;
7146 var prevToken = null;
7147 var prevTokenPos = tokenizer.pos;
7148
7149 while (token = peek(tokenizer)) {
7150 if (token.type !== 'Spaces') {
7151 if (token.type === 'Combinator') {
7152 // check for combinator in group beginning and double combinator sequence
7153 if (prevToken === null || prevToken.type === 'Combinator') {
7154 tokenizer.pos = prevTokenPos;
7155 tokenizer.error('Unexpected combinator');
7156 }
7157
7158 combinators[token.value] = true;
7159 } else if (prevToken !== null && prevToken.type !== 'Combinator') {
7160 combinators[' '] = true; // a b
7161 terms.push({
7162 type: 'Combinator',
7163 value: ' '
7164 });
7165 }
7166
7167 terms.push(token);
7168 prevToken = token;
7169 prevTokenPos = tokenizer.pos;
7170 }
7171 }
7172
7173 // check for combinator in group ending
7174 if (prevToken !== null && prevToken.type === 'Combinator') {
7175 tokenizer.pos -= prevTokenPos;
7176 tokenizer.error('Unexpected combinator');
7177 }
7178
7179 return {
7180 type: 'Group',
7181 terms: terms,
7182 combinator: regroupTerms(terms, combinators) || ' ',
7183 disallowEmpty: false,
7184 explicit: false
7185 };
7186}
7187
7188function readGroup(tokenizer) {
7189 var result;
7190
7191 tokenizer.eat(LEFTSQUAREBRACKET$4);
7192 result = readImplicitGroup(tokenizer);
7193 tokenizer.eat(RIGHTSQUAREBRACKET$2);
7194
7195 result.explicit = true;
7196
7197 if (tokenizer.charCode() === EXCLAMATIONMARK$3) {
7198 tokenizer.pos++;
7199 result.disallowEmpty = true;
7200 }
7201
7202 return result;
7203}
7204
7205function peek(tokenizer) {
7206 var code = tokenizer.charCode();
7207
7208 if (code < 128 && NAME_CHAR[code] === 1) {
7209 return readKeywordOrFunction(tokenizer);
7210 }
7211
7212 switch (code) {
7213 case RIGHTSQUAREBRACKET$2:
7214 // don't eat, stop scan a group
7215 break;
7216
7217 case LEFTSQUAREBRACKET$4:
7218 return maybeMultiplied(tokenizer, readGroup(tokenizer));
7219
7220 case LESSTHANSIGN:
7221 return tokenizer.nextCharCode() === APOSTROPHE
7222 ? readProperty$1(tokenizer)
7223 : readType(tokenizer);
7224
7225 case VERTICALLINE$3:
7226 return {
7227 type: 'Combinator',
7228 value: tokenizer.substringToPos(
7229 tokenizer.nextCharCode() === VERTICALLINE$3
7230 ? tokenizer.pos + 2
7231 : tokenizer.pos + 1
7232 )
7233 };
7234
7235 case AMPERSAND$1:
7236 tokenizer.pos++;
7237 tokenizer.eat(AMPERSAND$1);
7238
7239 return {
7240 type: 'Combinator',
7241 value: '&&'
7242 };
7243
7244 case COMMA$4:
7245 tokenizer.pos++;
7246 return {
7247 type: 'Comma'
7248 };
7249
7250 case APOSTROPHE:
7251 return maybeMultiplied(tokenizer, {
7252 type: 'String',
7253 value: scanString(tokenizer)
7254 });
7255
7256 case SPACE$1:
7257 case TAB:
7258 case N$2:
7259 case R$1:
7260 case F$1:
7261 return {
7262 type: 'Spaces',
7263 value: scanSpaces(tokenizer)
7264 };
7265
7266 case COMMERCIALAT:
7267 code = tokenizer.nextCharCode();
7268
7269 if (code < 128 && NAME_CHAR[code] === 1) {
7270 tokenizer.pos++;
7271 return {
7272 type: 'AtKeyword',
7273 name: scanWord(tokenizer)
7274 };
7275 }
7276
7277 return maybeToken(tokenizer);
7278
7279 case ASTERISK$6:
7280 case PLUSSIGN$6:
7281 case QUESTIONMARK$1:
7282 case NUMBERSIGN$4:
7283 case EXCLAMATIONMARK$3:
7284 // prohibited tokens (used as a multiplier start)
7285 break;
7286
7287 case LEFTCURLYBRACKET$4:
7288 // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
7289 // check next char isn't a number, because it's likely a disjoined multiplier
7290 code = tokenizer.nextCharCode();
7291
7292 if (code < 48 || code > 57) {
7293 return maybeToken(tokenizer);
7294 }
7295
7296 break;
7297
7298 default:
7299 return maybeToken(tokenizer);
7300 }
7301}
7302
7303function parse$2(source) {
7304 var tokenizer = new Tokenizer(source);
7305 var result = readImplicitGroup(tokenizer);
7306
7307 if (tokenizer.pos !== source.length) {
7308 tokenizer.error('Unexpected input');
7309 }
7310
7311 // reduce redundant groups with single group term
7312 if (result.terms.length === 1 && result.terms[0].type === 'Group') {
7313 result = result.terms[0];
7314 }
7315
7316 return result;
7317}
7318
7319// warm up parse to elimitate code branches that never execute
7320// fix soft deoptimizations (insufficient type feedback)
7321parse$2('[a&&<b>#|<\'c\'>*||e() f{2} /,(% g#{1,2} h{2,})]!');
7322
7323var parse_1 = parse$2;
7324
7325var noop$2 = function() {};
7326
7327function ensureFunction$1(value) {
7328 return typeof value === 'function' ? value : noop$2;
7329}
7330
7331var walk$1 = function(node, options, context) {
7332 function walk(node) {
7333 enter.call(context, node);
7334
7335 switch (node.type) {
7336 case 'Group':
7337 node.terms.forEach(walk);
7338 break;
7339
7340 case 'Multiplier':
7341 walk(node.term);
7342 break;
7343
7344 case 'Type':
7345 case 'Property':
7346 case 'Keyword':
7347 case 'AtKeyword':
7348 case 'Function':
7349 case 'String':
7350 case 'Token':
7351 case 'Comma':
7352 break;
7353
7354 default:
7355 throw new Error('Unknown type: ' + node.type);
7356 }
7357
7358 leave.call(context, node);
7359 }
7360
7361 var enter = noop$2;
7362 var leave = noop$2;
7363
7364 if (typeof options === 'function') {
7365 enter = options;
7366 } else if (options) {
7367 enter = ensureFunction$1(options.enter);
7368 leave = ensureFunction$1(options.leave);
7369 }
7370
7371 if (enter === noop$2 && leave === noop$2) {
7372 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
7373 }
7374
7375 walk(node);
7376};
7377
7378var tokenize$2 = tokenizer$3;
7379var TokenStream$2 = TokenStream_1;
7380var tokenStream = new TokenStream$2();
7381var astToTokens = {
7382 decorator: function(handlers) {
7383 var curNode = null;
7384 var prev = { len: 0, node: null };
7385 var nodes = [prev];
7386 var buffer = '';
7387
7388 return {
7389 children: handlers.children,
7390 node: function(node) {
7391 var tmp = curNode;
7392 curNode = node;
7393 handlers.node.call(this, node);
7394 curNode = tmp;
7395 },
7396 chunk: function(chunk) {
7397 buffer += chunk;
7398 if (prev.node !== curNode) {
7399 nodes.push({
7400 len: chunk.length,
7401 node: curNode
7402 });
7403 } else {
7404 prev.len += chunk.length;
7405 }
7406 },
7407 result: function() {
7408 return prepareTokens$1(buffer, nodes);
7409 }
7410 };
7411 }
7412};
7413
7414function prepareTokens$1(str, nodes) {
7415 var tokens = [];
7416 var nodesOffset = 0;
7417 var nodesIndex = 0;
7418 var currentNode = nodes ? nodes[nodesIndex].node : null;
7419
7420 tokenize$2(str, tokenStream);
7421
7422 while (!tokenStream.eof) {
7423 if (nodes) {
7424 while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
7425 nodesOffset += nodes[nodesIndex++].len;
7426 currentNode = nodes[nodesIndex].node;
7427 }
7428 }
7429
7430 tokens.push({
7431 type: tokenStream.tokenType,
7432 value: tokenStream.getTokenValue(),
7433 index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
7434 balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
7435 node: currentNode
7436 });
7437 tokenStream.next();
7438 // console.log({ ...tokens[tokens.length - 1], node: undefined });
7439 }
7440
7441 return tokens;
7442}
7443
7444var prepareTokens_1 = function(value, syntax) {
7445 if (typeof value === 'string') {
7446 return prepareTokens$1(value, null);
7447 }
7448
7449 return syntax.generate(value, astToTokens);
7450};
7451
7452var parse$1 = parse_1;
7453
7454var MATCH$1 = { type: 'Match' };
7455var MISMATCH$1 = { type: 'Mismatch' };
7456var DISALLOW_EMPTY$1 = { type: 'DisallowEmpty' };
7457var LEFTPARENTHESIS$6 = 40; // (
7458var RIGHTPARENTHESIS$6 = 41; // )
7459
7460function createCondition(match, thenBranch, elseBranch) {
7461 // reduce node count
7462 if (thenBranch === MATCH$1 && elseBranch === MISMATCH$1) {
7463 return match;
7464 }
7465
7466 if (match === MATCH$1 && thenBranch === MATCH$1 && elseBranch === MATCH$1) {
7467 return match;
7468 }
7469
7470 if (match.type === 'If' && match.else === MISMATCH$1 && thenBranch === MATCH$1) {
7471 thenBranch = match.then;
7472 match = match.match;
7473 }
7474
7475 return {
7476 type: 'If',
7477 match: match,
7478 then: thenBranch,
7479 else: elseBranch
7480 };
7481}
7482
7483function isFunctionType(name) {
7484 return (
7485 name.length > 2 &&
7486 name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$6 &&
7487 name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$6
7488 );
7489}
7490
7491function isEnumCapatible(term) {
7492 return (
7493 term.type === 'Keyword' ||
7494 term.type === 'AtKeyword' ||
7495 term.type === 'Function' ||
7496 term.type === 'Type' && isFunctionType(term.name)
7497 );
7498}
7499
7500function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
7501 switch (combinator) {
7502 case ' ':
7503 // Juxtaposing components means that all of them must occur, in the given order.
7504 //
7505 // a b c
7506 // =
7507 // match a
7508 // then match b
7509 // then match c
7510 // then MATCH
7511 // else MISMATCH
7512 // else MISMATCH
7513 // else MISMATCH
7514 var result = MATCH$1;
7515
7516 for (var i = terms.length - 1; i >= 0; i--) {
7517 var term = terms[i];
7518
7519 result = createCondition(
7520 term,
7521 result,
7522 MISMATCH$1
7523 );
7524 }
7525 return result;
7526
7527 case '|':
7528 // A bar (|) separates two or more alternatives: exactly one of them must occur.
7529 //
7530 // a | b | c
7531 // =
7532 // match a
7533 // then MATCH
7534 // else match b
7535 // then MATCH
7536 // else match c
7537 // then MATCH
7538 // else MISMATCH
7539
7540 var result = MISMATCH$1;
7541 var map = null;
7542
7543 for (var i = terms.length - 1; i >= 0; i--) {
7544 var term = terms[i];
7545
7546 // reduce sequence of keywords into a Enum
7547 if (isEnumCapatible(term)) {
7548 if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
7549 map = Object.create(null);
7550 result = createCondition(
7551 {
7552 type: 'Enum',
7553 map: map
7554 },
7555 MATCH$1,
7556 result
7557 );
7558 }
7559
7560 if (map !== null) {
7561 var key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
7562 if (key in map === false) {
7563 map[key] = term;
7564 continue;
7565 }
7566 }
7567 }
7568
7569 map = null;
7570
7571 // create a new conditonal node
7572 result = createCondition(
7573 term,
7574 MATCH$1,
7575 result
7576 );
7577 }
7578 return result;
7579
7580 case '&&':
7581 // A double ampersand (&&) separates two or more components,
7582 // all of which must occur, in any order.
7583
7584 // Use MatchOnce for groups with a large number of terms,
7585 // since &&-groups produces at least N!-node trees
7586 if (terms.length > 5) {
7587 return {
7588 type: 'MatchOnce',
7589 terms: terms,
7590 all: true
7591 };
7592 }
7593
7594 // Use a combination tree for groups with small number of terms
7595 //
7596 // a && b && c
7597 // =
7598 // match a
7599 // then [b && c]
7600 // else match b
7601 // then [a && c]
7602 // else match c
7603 // then [a && b]
7604 // else MISMATCH
7605 //
7606 // a && b
7607 // =
7608 // match a
7609 // then match b
7610 // then MATCH
7611 // else MISMATCH
7612 // else match b
7613 // then match a
7614 // then MATCH
7615 // else MISMATCH
7616 // else MISMATCH
7617 var result = MISMATCH$1;
7618
7619 for (var i = terms.length - 1; i >= 0; i--) {
7620 var term = terms[i];
7621 var thenClause;
7622
7623 if (terms.length > 1) {
7624 thenClause = buildGroupMatchGraph(
7625 combinator,
7626 terms.filter(function(newGroupTerm) {
7627 return newGroupTerm !== term;
7628 }),
7629 false
7630 );
7631 } else {
7632 thenClause = MATCH$1;
7633 }
7634
7635 result = createCondition(
7636 term,
7637 thenClause,
7638 result
7639 );
7640 }
7641 return result;
7642
7643 case '||':
7644 // A double bar (||) separates two or more options:
7645 // one or more of them must occur, in any order.
7646
7647 // Use MatchOnce for groups with a large number of terms,
7648 // since ||-groups produces at least N!-node trees
7649 if (terms.length > 5) {
7650 return {
7651 type: 'MatchOnce',
7652 terms: terms,
7653 all: false
7654 };
7655 }
7656
7657 // Use a combination tree for groups with small number of terms
7658 //
7659 // a || b || c
7660 // =
7661 // match a
7662 // then [b || c]
7663 // else match b
7664 // then [a || c]
7665 // else match c
7666 // then [a || b]
7667 // else MISMATCH
7668 //
7669 // a || b
7670 // =
7671 // match a
7672 // then match b
7673 // then MATCH
7674 // else MATCH
7675 // else match b
7676 // then match a
7677 // then MATCH
7678 // else MATCH
7679 // else MISMATCH
7680 var result = atLeastOneTermMatched ? MATCH$1 : MISMATCH$1;
7681
7682 for (var i = terms.length - 1; i >= 0; i--) {
7683 var term = terms[i];
7684 var thenClause;
7685
7686 if (terms.length > 1) {
7687 thenClause = buildGroupMatchGraph(
7688 combinator,
7689 terms.filter(function(newGroupTerm) {
7690 return newGroupTerm !== term;
7691 }),
7692 true
7693 );
7694 } else {
7695 thenClause = MATCH$1;
7696 }
7697
7698 result = createCondition(
7699 term,
7700 thenClause,
7701 result
7702 );
7703 }
7704 return result;
7705 }
7706}
7707
7708function buildMultiplierMatchGraph(node) {
7709 var result = MATCH$1;
7710 var matchTerm = buildMatchGraph$1(node.term);
7711
7712 if (node.max === 0) {
7713 // disable repeating of empty match to prevent infinite loop
7714 matchTerm = createCondition(
7715 matchTerm,
7716 DISALLOW_EMPTY$1,
7717 MISMATCH$1
7718 );
7719
7720 // an occurrence count is not limited, make a cycle;
7721 // to collect more terms on each following matching mismatch
7722 result = createCondition(
7723 matchTerm,
7724 null, // will be a loop
7725 MISMATCH$1
7726 );
7727
7728 result.then = createCondition(
7729 MATCH$1,
7730 MATCH$1,
7731 result // make a loop
7732 );
7733
7734 if (node.comma) {
7735 result.then.else = createCondition(
7736 { type: 'Comma', syntax: node },
7737 result,
7738 MISMATCH$1
7739 );
7740 }
7741 } else {
7742 // create a match node chain for [min .. max] interval with optional matches
7743 for (var i = node.min || 1; i <= node.max; i++) {
7744 if (node.comma && result !== MATCH$1) {
7745 result = createCondition(
7746 { type: 'Comma', syntax: node },
7747 result,
7748 MISMATCH$1
7749 );
7750 }
7751
7752 result = createCondition(
7753 matchTerm,
7754 createCondition(
7755 MATCH$1,
7756 MATCH$1,
7757 result
7758 ),
7759 MISMATCH$1
7760 );
7761 }
7762 }
7763
7764 if (node.min === 0) {
7765 // allow zero match
7766 result = createCondition(
7767 MATCH$1,
7768 MATCH$1,
7769 result
7770 );
7771 } else {
7772 // create a match node chain to collect [0 ... min - 1] required matches
7773 for (var i = 0; i < node.min - 1; i++) {
7774 if (node.comma && result !== MATCH$1) {
7775 result = createCondition(
7776 { type: 'Comma', syntax: node },
7777 result,
7778 MISMATCH$1
7779 );
7780 }
7781
7782 result = createCondition(
7783 matchTerm,
7784 result,
7785 MISMATCH$1
7786 );
7787 }
7788 }
7789
7790 return result;
7791}
7792
7793function buildMatchGraph$1(node) {
7794 if (typeof node === 'function') {
7795 return {
7796 type: 'Generic',
7797 fn: node
7798 };
7799 }
7800
7801 switch (node.type) {
7802 case 'Group':
7803 var result = buildGroupMatchGraph(
7804 node.combinator,
7805 node.terms.map(buildMatchGraph$1),
7806 false
7807 );
7808
7809 if (node.disallowEmpty) {
7810 result = createCondition(
7811 result,
7812 DISALLOW_EMPTY$1,
7813 MISMATCH$1
7814 );
7815 }
7816
7817 return result;
7818
7819 case 'Multiplier':
7820 return buildMultiplierMatchGraph(node);
7821
7822 case 'Type':
7823 case 'Property':
7824 return {
7825 type: node.type,
7826 name: node.name,
7827 syntax: node
7828 };
7829
7830 case 'Keyword':
7831 return {
7832 type: node.type,
7833 name: node.name.toLowerCase(),
7834 syntax: node
7835 };
7836
7837 case 'AtKeyword':
7838 return {
7839 type: node.type,
7840 name: '@' + node.name.toLowerCase(),
7841 syntax: node
7842 };
7843
7844 case 'Function':
7845 return {
7846 type: node.type,
7847 name: node.name.toLowerCase() + '(',
7848 syntax: node
7849 };
7850
7851 case 'String':
7852 // convert a one char length String to a Token
7853 if (node.value.length === 3) {
7854 return {
7855 type: 'Token',
7856 value: node.value.charAt(1),
7857 syntax: node
7858 };
7859 }
7860
7861 // otherwise use it as is
7862 return {
7863 type: node.type,
7864 value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
7865 syntax: node
7866 };
7867
7868 case 'Token':
7869 return {
7870 type: node.type,
7871 value: node.value,
7872 syntax: node
7873 };
7874
7875 case 'Comma':
7876 return {
7877 type: node.type,
7878 syntax: node
7879 };
7880
7881 default:
7882 throw new Error('Unknown node type:', node.type);
7883 }
7884}
7885
7886var matchGraph$1 = {
7887 MATCH: MATCH$1,
7888 MISMATCH: MISMATCH$1,
7889 DISALLOW_EMPTY: DISALLOW_EMPTY$1,
7890 buildMatchGraph: function(syntaxTree, ref) {
7891 if (typeof syntaxTree === 'string') {
7892 syntaxTree = parse$1(syntaxTree);
7893 }
7894
7895 return {
7896 type: 'MatchGraph',
7897 match: buildMatchGraph$1(syntaxTree),
7898 syntax: ref || null,
7899 source: syntaxTree
7900 };
7901 }
7902};
7903
7904var hasOwnProperty$6 = Object.prototype.hasOwnProperty;
7905var matchGraph = matchGraph$1;
7906var MATCH = matchGraph.MATCH;
7907var MISMATCH = matchGraph.MISMATCH;
7908var DISALLOW_EMPTY = matchGraph.DISALLOW_EMPTY;
7909var TYPE$B = _const.TYPE;
7910
7911var STUB = 0;
7912var TOKEN = 1;
7913var OPEN_SYNTAX = 2;
7914var CLOSE_SYNTAX = 3;
7915
7916var EXIT_REASON_MATCH = 'Match';
7917var EXIT_REASON_MISMATCH = 'Mismatch';
7918var EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';
7919
7920var ITERATION_LIMIT = 15000;
7921var totalIterationCount = 0;
7922
7923function reverseList(list) {
7924 var prev = null;
7925 var next = null;
7926 var item = list;
7927
7928 while (item !== null) {
7929 next = item.prev;
7930 item.prev = prev;
7931 prev = item;
7932 item = next;
7933 }
7934
7935 return prev;
7936}
7937
7938function areStringsEqualCaseInsensitive(testStr, referenceStr) {
7939 if (testStr.length !== referenceStr.length) {
7940 return false;
7941 }
7942
7943 for (var i = 0; i < testStr.length; i++) {
7944 var testCode = testStr.charCodeAt(i);
7945 var referenceCode = referenceStr.charCodeAt(i);
7946
7947 // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).
7948 if (testCode >= 0x0041 && testCode <= 0x005A) {
7949 testCode = testCode | 32;
7950 }
7951
7952 if (testCode !== referenceCode) {
7953 return false;
7954 }
7955 }
7956
7957 return true;
7958}
7959
7960function isContextEdgeDelim(token) {
7961 if (token.type !== TYPE$B.Delim) {
7962 return false;
7963 }
7964
7965 // Fix matching for unicode-range: U+30??, U+FF00-FF9F
7966 // Probably we need to check out previous match instead
7967 return token.value !== '?';
7968}
7969
7970function isCommaContextStart(token) {
7971 if (token === null) {
7972 return true;
7973 }
7974
7975 return (
7976 token.type === TYPE$B.Comma ||
7977 token.type === TYPE$B.Function ||
7978 token.type === TYPE$B.LeftParenthesis ||
7979 token.type === TYPE$B.LeftSquareBracket ||
7980 token.type === TYPE$B.LeftCurlyBracket ||
7981 isContextEdgeDelim(token)
7982 );
7983}
7984
7985function isCommaContextEnd(token) {
7986 if (token === null) {
7987 return true;
7988 }
7989
7990 return (
7991 token.type === TYPE$B.RightParenthesis ||
7992 token.type === TYPE$B.RightSquareBracket ||
7993 token.type === TYPE$B.RightCurlyBracket ||
7994 token.type === TYPE$B.Delim
7995 );
7996}
7997
7998function internalMatch(tokens, state, syntaxes) {
7999 function moveToNextToken() {
8000 do {
8001 tokenIndex++;
8002 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
8003 } while (token !== null && (token.type === TYPE$B.WhiteSpace || token.type === TYPE$B.Comment));
8004 }
8005
8006 function getNextToken(offset) {
8007 var nextIndex = tokenIndex + offset;
8008
8009 return nextIndex < tokens.length ? tokens[nextIndex] : null;
8010 }
8011
8012 function stateSnapshotFromSyntax(nextState, prev) {
8013 return {
8014 nextState: nextState,
8015 matchStack: matchStack,
8016 syntaxStack: syntaxStack,
8017 thenStack: thenStack,
8018 tokenIndex: tokenIndex,
8019 prev: prev
8020 };
8021 }
8022
8023 function pushThenStack(nextState) {
8024 thenStack = {
8025 nextState: nextState,
8026 matchStack: matchStack,
8027 syntaxStack: syntaxStack,
8028 prev: thenStack
8029 };
8030 }
8031
8032 function pushElseStack(nextState) {
8033 elseStack = stateSnapshotFromSyntax(nextState, elseStack);
8034 }
8035
8036 function addTokenToMatch() {
8037 matchStack = {
8038 type: TOKEN,
8039 syntax: state.syntax,
8040 token: token,
8041 prev: matchStack
8042 };
8043
8044 moveToNextToken();
8045 syntaxStash = null;
8046
8047 if (tokenIndex > longestMatch) {
8048 longestMatch = tokenIndex;
8049 }
8050 }
8051
8052 function openSyntax() {
8053 syntaxStack = {
8054 syntax: state.syntax,
8055 opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,
8056 prev: syntaxStack
8057 };
8058
8059 matchStack = {
8060 type: OPEN_SYNTAX,
8061 syntax: state.syntax,
8062 token: matchStack.token,
8063 prev: matchStack
8064 };
8065 }
8066
8067 function closeSyntax() {
8068 if (matchStack.type === OPEN_SYNTAX) {
8069 matchStack = matchStack.prev;
8070 } else {
8071 matchStack = {
8072 type: CLOSE_SYNTAX,
8073 syntax: syntaxStack.syntax,
8074 token: matchStack.token,
8075 prev: matchStack
8076 };
8077 }
8078
8079 syntaxStack = syntaxStack.prev;
8080 }
8081
8082 var syntaxStack = null;
8083 var thenStack = null;
8084 var elseStack = null;
8085
8086 // null – stashing allowed, nothing stashed
8087 // false – stashing disabled, nothing stashed
8088 // anithing else – fail stashable syntaxes, some syntax stashed
8089 var syntaxStash = null;
8090
8091 var iterationCount = 0; // count iterations and prevent infinite loop
8092 var exitReason = null;
8093
8094 var token = null;
8095 var tokenIndex = -1;
8096 var longestMatch = 0;
8097 var matchStack = {
8098 type: STUB,
8099 syntax: null,
8100 token: null,
8101 prev: null
8102 };
8103
8104 moveToNextToken();
8105
8106 while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {
8107 // function mapList(list, fn) {
8108 // var result = [];
8109 // while (list) {
8110 // result.unshift(fn(list));
8111 // list = list.prev;
8112 // }
8113 // return result;
8114 // }
8115 // console.log('--\n',
8116 // '#' + iterationCount,
8117 // require('util').inspect({
8118 // match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null),
8119 // token: token && token.value,
8120 // tokenIndex,
8121 // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')
8122 // }, { depth: null })
8123 // );
8124 switch (state.type) {
8125 case 'Match':
8126 if (thenStack === null) {
8127 // turn to MISMATCH when some tokens left unmatched
8128 if (token !== null) {
8129 // doesn't mismatch if just one token left and it's an IE hack
8130 if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) {
8131 state = MISMATCH;
8132 break;
8133 }
8134 }
8135
8136 // break the main loop, return a result - MATCH
8137 exitReason = EXIT_REASON_MATCH;
8138 break;
8139 }
8140
8141 // go to next syntax (`then` branch)
8142 state = thenStack.nextState;
8143
8144 // check match is not empty
8145 if (state === DISALLOW_EMPTY) {
8146 if (thenStack.matchStack === matchStack) {
8147 state = MISMATCH;
8148 break;
8149 } else {
8150 state = MATCH;
8151 }
8152 }
8153
8154 // close syntax if needed
8155 while (thenStack.syntaxStack !== syntaxStack) {
8156 closeSyntax();
8157 }
8158
8159 // pop stack
8160 thenStack = thenStack.prev;
8161 break;
8162
8163 case 'Mismatch':
8164 // when some syntax is stashed
8165 if (syntaxStash !== null && syntaxStash !== false) {
8166 // there is no else branches or a branch reduce match stack
8167 if (elseStack === null || tokenIndex > elseStack.tokenIndex) {
8168 // restore state from the stash
8169 elseStack = syntaxStash;
8170 syntaxStash = false; // disable stashing
8171 }
8172 } else if (elseStack === null) {
8173 // no else branches -> break the main loop
8174 // return a result - MISMATCH
8175 exitReason = EXIT_REASON_MISMATCH;
8176 break;
8177 }
8178
8179 // go to next syntax (`else` branch)
8180 state = elseStack.nextState;
8181
8182 // restore all the rest stack states
8183 thenStack = elseStack.thenStack;
8184 syntaxStack = elseStack.syntaxStack;
8185 matchStack = elseStack.matchStack;
8186 tokenIndex = elseStack.tokenIndex;
8187 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
8188
8189 // pop stack
8190 elseStack = elseStack.prev;
8191 break;
8192
8193 case 'MatchGraph':
8194 state = state.match;
8195 break;
8196
8197 case 'If':
8198 // IMPORTANT: else stack push must go first,
8199 // since it stores the state of thenStack before changes
8200 if (state.else !== MISMATCH) {
8201 pushElseStack(state.else);
8202 }
8203
8204 if (state.then !== MATCH) {
8205 pushThenStack(state.then);
8206 }
8207
8208 state = state.match;
8209 break;
8210
8211 case 'MatchOnce':
8212 state = {
8213 type: 'MatchOnceBuffer',
8214 syntax: state,
8215 index: 0,
8216 mask: 0
8217 };
8218 break;
8219
8220 case 'MatchOnceBuffer':
8221 var terms = state.syntax.terms;
8222
8223 if (state.index === terms.length) {
8224 // no matches at all or it's required all terms to be matched
8225 if (state.mask === 0 || state.syntax.all) {
8226 state = MISMATCH;
8227 break;
8228 }
8229
8230 // a partial match is ok
8231 state = MATCH;
8232 break;
8233 }
8234
8235 // all terms are matched
8236 if (state.mask === (1 << terms.length) - 1) {
8237 state = MATCH;
8238 break;
8239 }
8240
8241 for (; state.index < terms.length; state.index++) {
8242 var matchFlag = 1 << state.index;
8243
8244 if ((state.mask & matchFlag) === 0) {
8245 // IMPORTANT: else stack push must go first,
8246 // since it stores the state of thenStack before changes
8247 pushElseStack(state);
8248 pushThenStack({
8249 type: 'AddMatchOnce',
8250 syntax: state.syntax,
8251 mask: state.mask | matchFlag
8252 });
8253
8254 // match
8255 state = terms[state.index++];
8256 break;
8257 }
8258 }
8259 break;
8260
8261 case 'AddMatchOnce':
8262 state = {
8263 type: 'MatchOnceBuffer',
8264 syntax: state.syntax,
8265 index: 0,
8266 mask: state.mask
8267 };
8268 break;
8269
8270 case 'Enum':
8271 if (token !== null) {
8272 var name = token.value.toLowerCase();
8273
8274 // drop \0 and \9 hack from keyword name
8275 if (name.indexOf('\\') !== -1) {
8276 name = name.replace(/\\[09].*$/, '');
8277 }
8278
8279 if (hasOwnProperty$6.call(state.map, name)) {
8280 state = state.map[name];
8281 break;
8282 }
8283 }
8284
8285 state = MISMATCH;
8286 break;
8287
8288 case 'Generic':
8289 var opts = syntaxStack !== null ? syntaxStack.opts : null;
8290 var lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));
8291
8292 if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {
8293 while (tokenIndex < lastTokenIndex) {
8294 addTokenToMatch();
8295 }
8296
8297 state = MATCH;
8298 } else {
8299 state = MISMATCH;
8300 }
8301
8302 break;
8303
8304 case 'Type':
8305 case 'Property':
8306 var syntaxDict = state.type === 'Type' ? 'types' : 'properties';
8307 var dictSyntax = hasOwnProperty$6.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;
8308
8309 if (!dictSyntax || !dictSyntax.match) {
8310 throw new Error(
8311 'Bad syntax reference: ' +
8312 (state.type === 'Type'
8313 ? '<' + state.name + '>'
8314 : '<\'' + state.name + '\'>')
8315 );
8316 }
8317
8318 // stash a syntax for types with low priority
8319 if (syntaxStash !== false && token !== null && state.type === 'Type') {
8320 var lowPriorityMatching =
8321 // https://drafts.csswg.org/css-values-4/#custom-idents
8322 // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production
8323 // can only claim the keyword if no other unfulfilled production can claim it.
8324 (state.name === 'custom-ident' && token.type === TYPE$B.Ident) ||
8325
8326 // https://drafts.csswg.org/css-values-4/#lengths
8327 // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),
8328 // it must parse as a <number>
8329 (state.name === 'length' && token.value === '0');
8330
8331 if (lowPriorityMatching) {
8332 if (syntaxStash === null) {
8333 syntaxStash = stateSnapshotFromSyntax(state, elseStack);
8334 }
8335
8336 state = MISMATCH;
8337 break;
8338 }
8339 }
8340
8341 openSyntax();
8342 state = dictSyntax.match;
8343 break;
8344
8345 case 'Keyword':
8346 var name = state.name;
8347
8348 if (token !== null) {
8349 var keywordName = token.value;
8350
8351 // drop \0 and \9 hack from keyword name
8352 if (keywordName.indexOf('\\') !== -1) {
8353 keywordName = keywordName.replace(/\\[09].*$/, '');
8354 }
8355
8356 if (areStringsEqualCaseInsensitive(keywordName, name)) {
8357 addTokenToMatch();
8358 state = MATCH;
8359 break;
8360 }
8361 }
8362
8363 state = MISMATCH;
8364 break;
8365
8366 case 'AtKeyword':
8367 case 'Function':
8368 if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {
8369 addTokenToMatch();
8370 state = MATCH;
8371 break;
8372 }
8373
8374 state = MISMATCH;
8375 break;
8376
8377 case 'Token':
8378 if (token !== null && token.value === state.value) {
8379 addTokenToMatch();
8380 state = MATCH;
8381 break;
8382 }
8383
8384 state = MISMATCH;
8385 break;
8386
8387 case 'Comma':
8388 if (token !== null && token.type === TYPE$B.Comma) {
8389 if (isCommaContextStart(matchStack.token)) {
8390 state = MISMATCH;
8391 } else {
8392 addTokenToMatch();
8393 state = isCommaContextEnd(token) ? MISMATCH : MATCH;
8394 }
8395 } else {
8396 state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH : MISMATCH;
8397 }
8398
8399 break;
8400
8401 case 'String':
8402 var string = '';
8403
8404 for (var lastTokenIndex = tokenIndex; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {
8405 string += tokens[lastTokenIndex].value;
8406 }
8407
8408 if (areStringsEqualCaseInsensitive(string, state.value)) {
8409 while (tokenIndex < lastTokenIndex) {
8410 addTokenToMatch();
8411 }
8412
8413 state = MATCH;
8414 } else {
8415 state = MISMATCH;
8416 }
8417
8418 break;
8419
8420 default:
8421 throw new Error('Unknown node type: ' + state.type);
8422 }
8423 }
8424
8425 totalIterationCount += iterationCount;
8426
8427 switch (exitReason) {
8428 case null:
8429 console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');
8430 exitReason = EXIT_REASON_ITERATION_LIMIT;
8431 matchStack = null;
8432 break;
8433
8434 case EXIT_REASON_MATCH:
8435 while (syntaxStack !== null) {
8436 closeSyntax();
8437 }
8438 break;
8439
8440 default:
8441 matchStack = null;
8442 }
8443
8444 return {
8445 tokens: tokens,
8446 reason: exitReason,
8447 iterations: iterationCount,
8448 match: matchStack,
8449 longestMatch: longestMatch
8450 };
8451}
8452
8453function matchAsList(tokens, matchGraph, syntaxes) {
8454 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
8455
8456 if (matchResult.match !== null) {
8457 var item = reverseList(matchResult.match).prev;
8458
8459 matchResult.match = [];
8460
8461 while (item !== null) {
8462 switch (item.type) {
8463 case STUB:
8464 break;
8465
8466 case OPEN_SYNTAX:
8467 case CLOSE_SYNTAX:
8468 matchResult.match.push({
8469 type: item.type,
8470 syntax: item.syntax
8471 });
8472 break;
8473
8474 default:
8475 matchResult.match.push({
8476 token: item.token.value,
8477 node: item.token.node
8478 });
8479 break;
8480 }
8481
8482 item = item.prev;
8483 }
8484 }
8485
8486 return matchResult;
8487}
8488
8489function matchAsTree$1(tokens, matchGraph, syntaxes) {
8490 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
8491
8492 if (matchResult.match === null) {
8493 return matchResult;
8494 }
8495
8496 var item = matchResult.match;
8497 var host = matchResult.match = {
8498 syntax: matchGraph.syntax || null,
8499 match: []
8500 };
8501 var hostStack = [host];
8502
8503 // revert a list and start with 2nd item since 1st is a stub item
8504 item = reverseList(item).prev;
8505
8506 // build a tree
8507 while (item !== null) {
8508 switch (item.type) {
8509 case OPEN_SYNTAX:
8510 host.match.push(host = {
8511 syntax: item.syntax,
8512 match: []
8513 });
8514 hostStack.push(host);
8515 break;
8516
8517 case CLOSE_SYNTAX:
8518 hostStack.pop();
8519 host = hostStack[hostStack.length - 1];
8520 break;
8521
8522 default:
8523 host.match.push({
8524 syntax: item.syntax || null,
8525 token: item.token.value,
8526 node: item.token.node
8527 });
8528 }
8529
8530 item = item.prev;
8531 }
8532
8533 return matchResult;
8534}
8535
8536var match = {
8537 matchAsList: matchAsList,
8538 matchAsTree: matchAsTree$1,
8539 getTotalIterationCount: function() {
8540 return totalIterationCount;
8541 }
8542};
8543
8544function getTrace(node) {
8545 function shouldPutToTrace(syntax) {
8546 if (syntax === null) {
8547 return false;
8548 }
8549
8550 return (
8551 syntax.type === 'Type' ||
8552 syntax.type === 'Property' ||
8553 syntax.type === 'Keyword'
8554 );
8555 }
8556
8557 function hasMatch(matchNode) {
8558 if (Array.isArray(matchNode.match)) {
8559 // use for-loop for better perfomance
8560 for (var i = 0; i < matchNode.match.length; i++) {
8561 if (hasMatch(matchNode.match[i])) {
8562 if (shouldPutToTrace(matchNode.syntax)) {
8563 result.unshift(matchNode.syntax);
8564 }
8565
8566 return true;
8567 }
8568 }
8569 } else if (matchNode.node === node) {
8570 result = shouldPutToTrace(matchNode.syntax)
8571 ? [matchNode.syntax]
8572 : [];
8573
8574 return true;
8575 }
8576
8577 return false;
8578 }
8579
8580 var result = null;
8581
8582 if (this.matched !== null) {
8583 hasMatch(this.matched);
8584 }
8585
8586 return result;
8587}
8588
8589function testNode(match, node, fn) {
8590 var trace = getTrace.call(match, node);
8591
8592 if (trace === null) {
8593 return false;
8594 }
8595
8596 return trace.some(fn);
8597}
8598
8599function isType(node, type) {
8600 return testNode(this, node, function(matchNode) {
8601 return matchNode.type === 'Type' && matchNode.name === type;
8602 });
8603}
8604
8605function isProperty(node, property) {
8606 return testNode(this, node, function(matchNode) {
8607 return matchNode.type === 'Property' && matchNode.name === property;
8608 });
8609}
8610
8611function isKeyword(node) {
8612 return testNode(this, node, function(matchNode) {
8613 return matchNode.type === 'Keyword';
8614 });
8615}
8616
8617var trace$1 = {
8618 getTrace: getTrace,
8619 isType: isType,
8620 isProperty: isProperty,
8621 isKeyword: isKeyword
8622};
8623
8624var List$5 = List_1;
8625
8626function getFirstMatchNode(matchNode) {
8627 if ('node' in matchNode) {
8628 return matchNode.node;
8629 }
8630
8631 return getFirstMatchNode(matchNode.match[0]);
8632}
8633
8634function getLastMatchNode(matchNode) {
8635 if ('node' in matchNode) {
8636 return matchNode.node;
8637 }
8638
8639 return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
8640}
8641
8642function matchFragments(lexer, ast, match, type, name) {
8643 function findFragments(matchNode) {
8644 if (matchNode.syntax !== null &&
8645 matchNode.syntax.type === type &&
8646 matchNode.syntax.name === name) {
8647 var start = getFirstMatchNode(matchNode);
8648 var end = getLastMatchNode(matchNode);
8649
8650 lexer.syntax.walk(ast, function(node, item, list) {
8651 if (node === start) {
8652 var nodes = new List$5();
8653
8654 do {
8655 nodes.appendData(item.data);
8656
8657 if (item.data === end) {
8658 break;
8659 }
8660
8661 item = item.next;
8662 } while (item !== null);
8663
8664 fragments.push({
8665 parent: list,
8666 nodes: nodes
8667 });
8668 }
8669 });
8670 }
8671
8672 if (Array.isArray(matchNode.match)) {
8673 matchNode.match.forEach(findFragments);
8674 }
8675 }
8676
8677 var fragments = [];
8678
8679 if (match.matched !== null) {
8680 findFragments(match.matched);
8681 }
8682
8683 return fragments;
8684}
8685
8686var search$1 = {
8687 matchFragments: matchFragments
8688};
8689
8690var List$4 = List_1;
8691var hasOwnProperty$5 = Object.prototype.hasOwnProperty;
8692
8693function isValidNumber(value) {
8694 // Number.isInteger(value) && value >= 0
8695 return (
8696 typeof value === 'number' &&
8697 isFinite(value) &&
8698 Math.floor(value) === value &&
8699 value >= 0
8700 );
8701}
8702
8703function isValidLocation(loc) {
8704 return (
8705 Boolean(loc) &&
8706 isValidNumber(loc.offset) &&
8707 isValidNumber(loc.line) &&
8708 isValidNumber(loc.column)
8709 );
8710}
8711
8712function createNodeStructureChecker(type, fields) {
8713 return function checkNode(node, warn) {
8714 if (!node || node.constructor !== Object) {
8715 return warn(node, 'Type of node should be an Object');
8716 }
8717
8718 for (var key in node) {
8719 var valid = true;
8720
8721 if (hasOwnProperty$5.call(node, key) === false) {
8722 continue;
8723 }
8724
8725 if (key === 'type') {
8726 if (node.type !== type) {
8727 warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
8728 }
8729 } else if (key === 'loc') {
8730 if (node.loc === null) {
8731 continue;
8732 } else if (node.loc && node.loc.constructor === Object) {
8733 if (typeof node.loc.source !== 'string') {
8734 key += '.source';
8735 } else if (!isValidLocation(node.loc.start)) {
8736 key += '.start';
8737 } else if (!isValidLocation(node.loc.end)) {
8738 key += '.end';
8739 } else {
8740 continue;
8741 }
8742 }
8743
8744 valid = false;
8745 } else if (fields.hasOwnProperty(key)) {
8746 for (var i = 0, valid = false; !valid && i < fields[key].length; i++) {
8747 var fieldType = fields[key][i];
8748
8749 switch (fieldType) {
8750 case String:
8751 valid = typeof node[key] === 'string';
8752 break;
8753
8754 case Boolean:
8755 valid = typeof node[key] === 'boolean';
8756 break;
8757
8758 case null:
8759 valid = node[key] === null;
8760 break;
8761
8762 default:
8763 if (typeof fieldType === 'string') {
8764 valid = node[key] && node[key].type === fieldType;
8765 } else if (Array.isArray(fieldType)) {
8766 valid = node[key] instanceof List$4;
8767 }
8768 }
8769 }
8770 } else {
8771 warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
8772 }
8773
8774 if (!valid) {
8775 warn(node, 'Bad value for `' + type + '.' + key + '`');
8776 }
8777 }
8778
8779 for (var key in fields) {
8780 if (hasOwnProperty$5.call(fields, key) &&
8781 hasOwnProperty$5.call(node, key) === false) {
8782 warn(node, 'Field `' + type + '.' + key + '` is missed');
8783 }
8784 }
8785 };
8786}
8787
8788function processStructure(name, nodeType) {
8789 var structure = nodeType.structure;
8790 var fields = {
8791 type: String,
8792 loc: true
8793 };
8794 var docs = {
8795 type: '"' + name + '"'
8796 };
8797
8798 for (var key in structure) {
8799 if (hasOwnProperty$5.call(structure, key) === false) {
8800 continue;
8801 }
8802
8803 var docsTypes = [];
8804 var fieldTypes = fields[key] = Array.isArray(structure[key])
8805 ? structure[key].slice()
8806 : [structure[key]];
8807
8808 for (var i = 0; i < fieldTypes.length; i++) {
8809 var fieldType = fieldTypes[i];
8810 if (fieldType === String || fieldType === Boolean) {
8811 docsTypes.push(fieldType.name);
8812 } else if (fieldType === null) {
8813 docsTypes.push('null');
8814 } else if (typeof fieldType === 'string') {
8815 docsTypes.push('<' + fieldType + '>');
8816 } else if (Array.isArray(fieldType)) {
8817 docsTypes.push('List'); // TODO: use type enum
8818 } else {
8819 throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
8820 }
8821 }
8822
8823 docs[key] = docsTypes.join(' | ');
8824 }
8825
8826 return {
8827 docs: docs,
8828 check: createNodeStructureChecker(name, fields)
8829 };
8830}
8831
8832var structure = {
8833 getStructureFromConfig: function(config) {
8834 var structure = {};
8835
8836 if (config.node) {
8837 for (var name in config.node) {
8838 if (hasOwnProperty$5.call(config.node, name)) {
8839 var nodeType = config.node[name];
8840
8841 if (nodeType.structure) {
8842 structure[name] = processStructure(name, nodeType);
8843 } else {
8844 throw new Error('Missed `structure` field in `' + name + '` node type definition');
8845 }
8846 }
8847 }
8848 }
8849
8850 return structure;
8851 }
8852};
8853
8854var SyntaxReferenceError = error.SyntaxReferenceError;
8855var SyntaxMatchError = error.SyntaxMatchError;
8856var names$1 = names$2;
8857var generic = generic$1;
8858var parse = parse_1;
8859var generate = generate_1;
8860var walk = walk$1;
8861var prepareTokens = prepareTokens_1;
8862var buildMatchGraph = matchGraph$1.buildMatchGraph;
8863var matchAsTree = match.matchAsTree;
8864var trace = trace$1;
8865var search = search$1;
8866var getStructureFromConfig = structure.getStructureFromConfig;
8867var cssWideKeywords = buildMatchGraph('inherit | initial | unset');
8868var cssWideKeywordsWithExpression = buildMatchGraph('inherit | initial | unset | <-ms-legacy-expression>');
8869
8870function dumpMapSyntax(map, compact, syntaxAsAst) {
8871 var result = {};
8872
8873 for (var name in map) {
8874 if (map[name].syntax) {
8875 result[name] = syntaxAsAst
8876 ? map[name].syntax
8877 : generate(map[name].syntax, { compact: compact });
8878 }
8879 }
8880
8881 return result;
8882}
8883
8884function dumpAtruleMapSyntax(map, compact, syntaxAsAst) {
8885 const result = {};
8886
8887 for (const [name, atrule] of Object.entries(map)) {
8888 result[name] = {
8889 prelude: atrule.prelude && (
8890 syntaxAsAst
8891 ? atrule.prelude.syntax
8892 : generate(atrule.prelude.syntax, { compact })
8893 ),
8894 descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst)
8895 };
8896 }
8897
8898 return result;
8899}
8900
8901function valueHasVar(tokens) {
8902 for (var i = 0; i < tokens.length; i++) {
8903 if (tokens[i].value.toLowerCase() === 'var(') {
8904 return true;
8905 }
8906 }
8907
8908 return false;
8909}
8910
8911function buildMatchResult(match, error, iterations) {
8912 return {
8913 matched: match,
8914 iterations: iterations,
8915 error: error,
8916 getTrace: trace.getTrace,
8917 isType: trace.isType,
8918 isProperty: trace.isProperty,
8919 isKeyword: trace.isKeyword
8920 };
8921}
8922
8923function matchSyntax(lexer, syntax, value, useCommon) {
8924 var tokens = prepareTokens(value, lexer.syntax);
8925 var result;
8926
8927 if (valueHasVar(tokens)) {
8928 return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
8929 }
8930
8931 if (useCommon) {
8932 result = matchAsTree(tokens, lexer.valueCommonSyntax, lexer);
8933 }
8934
8935 if (!useCommon || !result.match) {
8936 result = matchAsTree(tokens, syntax.match, lexer);
8937 if (!result.match) {
8938 return buildMatchResult(
8939 null,
8940 new SyntaxMatchError(result.reason, syntax.syntax, value, result),
8941 result.iterations
8942 );
8943 }
8944 }
8945
8946 return buildMatchResult(result.match, null, result.iterations);
8947}
8948
8949var Lexer$1 = function(config, syntax, structure) {
8950 this.valueCommonSyntax = cssWideKeywords;
8951 this.syntax = syntax;
8952 this.generic = false;
8953 this.atrules = {};
8954 this.properties = {};
8955 this.types = {};
8956 this.structure = structure || getStructureFromConfig(config);
8957
8958 if (config) {
8959 if (config.types) {
8960 for (var name in config.types) {
8961 this.addType_(name, config.types[name]);
8962 }
8963 }
8964
8965 if (config.generic) {
8966 this.generic = true;
8967 for (var name in generic) {
8968 this.addType_(name, generic[name]);
8969 }
8970 }
8971
8972 if (config.atrules) {
8973 for (var name in config.atrules) {
8974 this.addAtrule_(name, config.atrules[name]);
8975 }
8976 }
8977
8978 if (config.properties) {
8979 for (var name in config.properties) {
8980 this.addProperty_(name, config.properties[name]);
8981 }
8982 }
8983 }
8984};
8985
8986Lexer$1.prototype = {
8987 structure: {},
8988 checkStructure: function(ast) {
8989 function collectWarning(node, message) {
8990 warns.push({
8991 node: node,
8992 message: message
8993 });
8994 }
8995
8996 var structure = this.structure;
8997 var warns = [];
8998
8999 this.syntax.walk(ast, function(node) {
9000 if (structure.hasOwnProperty(node.type)) {
9001 structure[node.type].check(node, collectWarning);
9002 } else {
9003 collectWarning(node, 'Unknown node type `' + node.type + '`');
9004 }
9005 });
9006
9007 return warns.length ? warns : false;
9008 },
9009
9010 createDescriptor: function(syntax, type, name, parent = null) {
9011 var ref = {
9012 type: type,
9013 name: name
9014 };
9015 var descriptor = {
9016 type: type,
9017 name: name,
9018 parent: parent,
9019 syntax: null,
9020 match: null
9021 };
9022
9023 if (typeof syntax === 'function') {
9024 descriptor.match = buildMatchGraph(syntax, ref);
9025 } else {
9026 if (typeof syntax === 'string') {
9027 // lazy parsing on first access
9028 Object.defineProperty(descriptor, 'syntax', {
9029 get: function() {
9030 Object.defineProperty(descriptor, 'syntax', {
9031 value: parse(syntax)
9032 });
9033
9034 return descriptor.syntax;
9035 }
9036 });
9037 } else {
9038 descriptor.syntax = syntax;
9039 }
9040
9041 // lazy graph build on first access
9042 Object.defineProperty(descriptor, 'match', {
9043 get: function() {
9044 Object.defineProperty(descriptor, 'match', {
9045 value: buildMatchGraph(descriptor.syntax, ref)
9046 });
9047
9048 return descriptor.match;
9049 }
9050 });
9051 }
9052
9053 return descriptor;
9054 },
9055 addAtrule_: function(name, syntax) {
9056 if (!syntax) {
9057 return;
9058 }
9059
9060 this.atrules[name] = {
9061 type: 'Atrule',
9062 name: name,
9063 prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null,
9064 descriptors: syntax.descriptors
9065 ? Object.keys(syntax.descriptors).reduce((res, descName) => {
9066 res[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name);
9067 return res;
9068 }, {})
9069 : null
9070 };
9071 },
9072 addProperty_: function(name, syntax) {
9073 if (!syntax) {
9074 return;
9075 }
9076
9077 this.properties[name] = this.createDescriptor(syntax, 'Property', name);
9078 },
9079 addType_: function(name, syntax) {
9080 if (!syntax) {
9081 return;
9082 }
9083
9084 this.types[name] = this.createDescriptor(syntax, 'Type', name);
9085
9086 if (syntax === generic['-ms-legacy-expression']) {
9087 this.valueCommonSyntax = cssWideKeywordsWithExpression;
9088 }
9089 },
9090
9091 checkAtruleName: function(atruleName) {
9092 if (!this.getAtrule(atruleName)) {
9093 return new SyntaxReferenceError('Unknown at-rule', '@' + atruleName);
9094 }
9095 },
9096 checkAtrulePrelude: function(atruleName, prelude) {
9097 let error = this.checkAtruleName(atruleName);
9098
9099 if (error) {
9100 return error;
9101 }
9102
9103 var atrule = this.getAtrule(atruleName);
9104
9105 if (!atrule.prelude && prelude) {
9106 return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude');
9107 }
9108
9109 if (atrule.prelude && !prelude) {
9110 return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude');
9111 }
9112 },
9113 checkAtruleDescriptorName: function(atruleName, descriptorName) {
9114 let error = this.checkAtruleName(atruleName);
9115
9116 if (error) {
9117 return error;
9118 }
9119
9120 var atrule = this.getAtrule(atruleName);
9121 var descriptor = names$1.keyword(descriptorName);
9122
9123 if (!atrule.descriptors) {
9124 return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors');
9125 }
9126
9127 if (!atrule.descriptors[descriptor.name] &&
9128 !atrule.descriptors[descriptor.basename]) {
9129 return new SyntaxReferenceError('Unknown at-rule descriptor', descriptorName);
9130 }
9131 },
9132 checkPropertyName: function(propertyName) {
9133 var property = names$1.property(propertyName);
9134
9135 // don't match syntax for a custom property
9136 if (property.custom) {
9137 return new Error('Lexer matching doesn\'t applicable for custom properties');
9138 }
9139
9140 if (!this.getProperty(propertyName)) {
9141 return new SyntaxReferenceError('Unknown property', propertyName);
9142 }
9143 },
9144
9145 matchAtrulePrelude: function(atruleName, prelude) {
9146 var error = this.checkAtrulePrelude(atruleName, prelude);
9147
9148 if (error) {
9149 return buildMatchResult(null, error);
9150 }
9151
9152 if (!prelude) {
9153 return buildMatchResult(null, null);
9154 }
9155
9156 return matchSyntax(this, this.getAtrule(atruleName).prelude, prelude, false);
9157 },
9158 matchAtruleDescriptor: function(atruleName, descriptorName, value) {
9159 var error = this.checkAtruleDescriptorName(atruleName, descriptorName);
9160
9161 if (error) {
9162 return buildMatchResult(null, error);
9163 }
9164
9165 var atrule = this.getAtrule(atruleName);
9166 var descriptor = names$1.keyword(descriptorName);
9167
9168 return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false);
9169 },
9170 matchDeclaration: function(node) {
9171 if (node.type !== 'Declaration') {
9172 return buildMatchResult(null, new Error('Not a Declaration node'));
9173 }
9174
9175 return this.matchProperty(node.property, node.value);
9176 },
9177 matchProperty: function(propertyName, value) {
9178 var error = this.checkPropertyName(propertyName);
9179
9180 if (error) {
9181 return buildMatchResult(null, error);
9182 }
9183
9184 return matchSyntax(this, this.getProperty(propertyName), value, true);
9185 },
9186 matchType: function(typeName, value) {
9187 var typeSyntax = this.getType(typeName);
9188
9189 if (!typeSyntax) {
9190 return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName));
9191 }
9192
9193 return matchSyntax(this, typeSyntax, value, false);
9194 },
9195 match: function(syntax, value) {
9196 if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
9197 return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));
9198 }
9199
9200 if (typeof syntax === 'string' || !syntax.match) {
9201 syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
9202 }
9203
9204 return matchSyntax(this, syntax, value, false);
9205 },
9206
9207 findValueFragments: function(propertyName, value, type, name) {
9208 return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
9209 },
9210 findDeclarationValueFragments: function(declaration, type, name) {
9211 return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
9212 },
9213 findAllFragments: function(ast, type, name) {
9214 var result = [];
9215
9216 this.syntax.walk(ast, {
9217 visit: 'Declaration',
9218 enter: function(declaration) {
9219 result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
9220 }.bind(this)
9221 });
9222
9223 return result;
9224 },
9225
9226 getAtrule: function(atruleName, fallbackBasename = true) {
9227 var atrule = names$1.keyword(atruleName);
9228 var atruleEntry = atrule.vendor && fallbackBasename
9229 ? this.atrules[atrule.name] || this.atrules[atrule.basename]
9230 : this.atrules[atrule.name];
9231
9232 return atruleEntry || null;
9233 },
9234 getAtrulePrelude: function(atruleName, fallbackBasename = true) {
9235 const atrule = this.getAtrule(atruleName, fallbackBasename);
9236
9237 return atrule && atrule.prelude || null;
9238 },
9239 getAtruleDescriptor: function(atruleName, name) {
9240 return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators
9241 ? this.atrules[atruleName].declarators[name] || null
9242 : null;
9243 },
9244 getProperty: function(propertyName, fallbackBasename = true) {
9245 var property = names$1.property(propertyName);
9246 var propertyEntry = property.vendor && fallbackBasename
9247 ? this.properties[property.name] || this.properties[property.basename]
9248 : this.properties[property.name];
9249
9250 return propertyEntry || null;
9251 },
9252 getType: function(name) {
9253 return this.types.hasOwnProperty(name) ? this.types[name] : null;
9254 },
9255
9256 validate: function() {
9257 function validate(syntax, name, broken, descriptor) {
9258 if (broken.hasOwnProperty(name)) {
9259 return broken[name];
9260 }
9261
9262 broken[name] = false;
9263 if (descriptor.syntax !== null) {
9264 walk(descriptor.syntax, function(node) {
9265 if (node.type !== 'Type' && node.type !== 'Property') {
9266 return;
9267 }
9268
9269 var map = node.type === 'Type' ? syntax.types : syntax.properties;
9270 var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
9271
9272 if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
9273 broken[name] = true;
9274 }
9275 }, this);
9276 }
9277 }
9278
9279 var brokenTypes = {};
9280 var brokenProperties = {};
9281
9282 for (var key in this.types) {
9283 validate(this, key, brokenTypes, this.types[key]);
9284 }
9285
9286 for (var key in this.properties) {
9287 validate(this, key, brokenProperties, this.properties[key]);
9288 }
9289
9290 brokenTypes = Object.keys(brokenTypes).filter(function(name) {
9291 return brokenTypes[name];
9292 });
9293 brokenProperties = Object.keys(brokenProperties).filter(function(name) {
9294 return brokenProperties[name];
9295 });
9296
9297 if (brokenTypes.length || brokenProperties.length) {
9298 return {
9299 types: brokenTypes,
9300 properties: brokenProperties
9301 };
9302 }
9303
9304 return null;
9305 },
9306 dump: function(syntaxAsAst, pretty) {
9307 return {
9308 generic: this.generic,
9309 types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
9310 properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst),
9311 atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst)
9312 };
9313 },
9314 toString: function() {
9315 return JSON.stringify(this.dump());
9316 }
9317};
9318
9319var Lexer_1 = Lexer$1;
9320
9321var definitionSyntax$1 = {
9322 SyntaxError: _SyntaxError,
9323 parse: parse_1,
9324 generate: generate_1,
9325 walk: walk$1
9326};
9327
9328var adoptBuffer = adoptBuffer$2;
9329var isBOM = tokenizer$3.isBOM;
9330
9331var N$1 = 10;
9332var F = 12;
9333var R = 13;
9334
9335function computeLinesAndColumns(host, source) {
9336 var sourceLength = source.length;
9337 var lines = adoptBuffer(host.lines, sourceLength); // +1
9338 var line = host.startLine;
9339 var columns = adoptBuffer(host.columns, sourceLength);
9340 var column = host.startColumn;
9341 var startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0;
9342
9343 for (var i = startOffset; i < sourceLength; i++) { // -1
9344 var code = source.charCodeAt(i);
9345
9346 lines[i] = line;
9347 columns[i] = column++;
9348
9349 if (code === N$1 || code === R || code === F) {
9350 if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$1) {
9351 i++;
9352 lines[i] = line;
9353 columns[i] = column;
9354 }
9355
9356 line++;
9357 column = 1;
9358 }
9359 }
9360
9361 lines[i] = line;
9362 columns[i] = column;
9363
9364 host.lines = lines;
9365 host.columns = columns;
9366}
9367
9368var OffsetToLocation$1 = function() {
9369 this.lines = null;
9370 this.columns = null;
9371 this.linesAndColumnsComputed = false;
9372};
9373
9374OffsetToLocation$1.prototype = {
9375 setSource: function(source, startOffset, startLine, startColumn) {
9376 this.source = source;
9377 this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
9378 this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
9379 this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
9380 this.linesAndColumnsComputed = false;
9381 },
9382
9383 ensureLinesAndColumnsComputed: function() {
9384 if (!this.linesAndColumnsComputed) {
9385 computeLinesAndColumns(this, this.source);
9386 this.linesAndColumnsComputed = true;
9387 }
9388 },
9389 getLocation: function(offset, filename) {
9390 this.ensureLinesAndColumnsComputed();
9391
9392 return {
9393 source: filename,
9394 offset: this.startOffset + offset,
9395 line: this.lines[offset],
9396 column: this.columns[offset]
9397 };
9398 },
9399 getLocationRange: function(start, end, filename) {
9400 this.ensureLinesAndColumnsComputed();
9401
9402 return {
9403 source: filename,
9404 start: {
9405 offset: this.startOffset + start,
9406 line: this.lines[start],
9407 column: this.columns[start]
9408 },
9409 end: {
9410 offset: this.startOffset + end,
9411 line: this.lines[end],
9412 column: this.columns[end]
9413 }
9414 };
9415 }
9416};
9417
9418var OffsetToLocation_1 = OffsetToLocation$1;
9419
9420var TYPE$A = tokenizer$3.TYPE;
9421var WHITESPACE$a = TYPE$A.WhiteSpace;
9422var COMMENT$8 = TYPE$A.Comment;
9423
9424var sequence$1 = function readSequence(recognizer) {
9425 var children = this.createList();
9426 var child = null;
9427 var context = {
9428 recognizer: recognizer,
9429 space: null,
9430 ignoreWS: false,
9431 ignoreWSAfter: false
9432 };
9433
9434 this.scanner.skipSC();
9435
9436 while (!this.scanner.eof) {
9437 switch (this.scanner.tokenType) {
9438 case COMMENT$8:
9439 this.scanner.next();
9440 continue;
9441
9442 case WHITESPACE$a:
9443 if (context.ignoreWS) {
9444 this.scanner.next();
9445 } else {
9446 context.space = this.WhiteSpace();
9447 }
9448 continue;
9449 }
9450
9451 child = recognizer.getNode.call(this, context);
9452
9453 if (child === undefined) {
9454 break;
9455 }
9456
9457 if (context.space !== null) {
9458 children.push(context.space);
9459 context.space = null;
9460 }
9461
9462 children.push(child);
9463
9464 if (context.ignoreWSAfter) {
9465 context.ignoreWSAfter = false;
9466 context.ignoreWS = true;
9467 } else {
9468 context.ignoreWS = false;
9469 }
9470 }
9471
9472 return children;
9473};
9474
9475var OffsetToLocation = OffsetToLocation_1;
9476var SyntaxError$2 = _SyntaxError$1;
9477var TokenStream$1 = TokenStream_1;
9478var List$3 = List_1;
9479var tokenize$1 = tokenizer$3;
9480var constants = _const;
9481var { findWhiteSpaceStart, cmpStr: cmpStr$2 } = utils$2;
9482var sequence = sequence$1;
9483var noop$1 = function() {};
9484
9485var TYPE$z = constants.TYPE;
9486var NAME$1 = constants.NAME;
9487var WHITESPACE$9 = TYPE$z.WhiteSpace;
9488var COMMENT$7 = TYPE$z.Comment;
9489var IDENT$g = TYPE$z.Ident;
9490var FUNCTION$6 = TYPE$z.Function;
9491var URL$4 = TYPE$z.Url;
9492var HASH$5 = TYPE$z.Hash;
9493var PERCENTAGE$3 = TYPE$z.Percentage;
9494var NUMBER$7 = TYPE$z.Number;
9495var NUMBERSIGN$3 = 0x0023; // U+0023 NUMBER SIGN (#)
9496var NULL = 0;
9497
9498function createParseContext(name) {
9499 return function() {
9500 return this[name]();
9501 };
9502}
9503
9504function processConfig(config) {
9505 var parserConfig = {
9506 context: {},
9507 scope: {},
9508 atrule: {},
9509 pseudo: {}
9510 };
9511
9512 if (config.parseContext) {
9513 for (var name in config.parseContext) {
9514 switch (typeof config.parseContext[name]) {
9515 case 'function':
9516 parserConfig.context[name] = config.parseContext[name];
9517 break;
9518
9519 case 'string':
9520 parserConfig.context[name] = createParseContext(config.parseContext[name]);
9521 break;
9522 }
9523 }
9524 }
9525
9526 if (config.scope) {
9527 for (var name in config.scope) {
9528 parserConfig.scope[name] = config.scope[name];
9529 }
9530 }
9531
9532 if (config.atrule) {
9533 for (var name in config.atrule) {
9534 var atrule = config.atrule[name];
9535
9536 if (atrule.parse) {
9537 parserConfig.atrule[name] = atrule.parse;
9538 }
9539 }
9540 }
9541
9542 if (config.pseudo) {
9543 for (var name in config.pseudo) {
9544 var pseudo = config.pseudo[name];
9545
9546 if (pseudo.parse) {
9547 parserConfig.pseudo[name] = pseudo.parse;
9548 }
9549 }
9550 }
9551
9552 if (config.node) {
9553 for (var name in config.node) {
9554 parserConfig[name] = config.node[name].parse;
9555 }
9556 }
9557
9558 return parserConfig;
9559}
9560
9561var create$3 = function createParser(config) {
9562 var parser = {
9563 scanner: new TokenStream$1(),
9564 locationMap: new OffsetToLocation(),
9565
9566 filename: '<unknown>',
9567 needPositions: false,
9568 onParseError: noop$1,
9569 onParseErrorThrow: false,
9570 parseAtrulePrelude: true,
9571 parseRulePrelude: true,
9572 parseValue: true,
9573 parseCustomProperty: false,
9574
9575 readSequence: sequence,
9576
9577 createList: function() {
9578 return new List$3();
9579 },
9580 createSingleNodeList: function(node) {
9581 return new List$3().appendData(node);
9582 },
9583 getFirstListNode: function(list) {
9584 return list && list.first();
9585 },
9586 getLastListNode: function(list) {
9587 return list.last();
9588 },
9589
9590 parseWithFallback: function(consumer, fallback) {
9591 var startToken = this.scanner.tokenIndex;
9592
9593 try {
9594 return consumer.call(this);
9595 } catch (e) {
9596 if (this.onParseErrorThrow) {
9597 throw e;
9598 }
9599
9600 var fallbackNode = fallback.call(this, startToken);
9601
9602 this.onParseErrorThrow = true;
9603 this.onParseError(e, fallbackNode);
9604 this.onParseErrorThrow = false;
9605
9606 return fallbackNode;
9607 }
9608 },
9609
9610 lookupNonWSType: function(offset) {
9611 do {
9612 var type = this.scanner.lookupType(offset++);
9613 if (type !== WHITESPACE$9) {
9614 return type;
9615 }
9616 } while (type !== NULL);
9617
9618 return NULL;
9619 },
9620
9621 eat: function(tokenType) {
9622 if (this.scanner.tokenType !== tokenType) {
9623 var offset = this.scanner.tokenStart;
9624 var message = NAME$1[tokenType] + ' is expected';
9625
9626 // tweak message and offset
9627 switch (tokenType) {
9628 case IDENT$g:
9629 // when identifier is expected but there is a function or url
9630 if (this.scanner.tokenType === FUNCTION$6 || this.scanner.tokenType === URL$4) {
9631 offset = this.scanner.tokenEnd - 1;
9632 message = 'Identifier is expected but function found';
9633 } else {
9634 message = 'Identifier is expected';
9635 }
9636 break;
9637
9638 case HASH$5:
9639 if (this.scanner.isDelim(NUMBERSIGN$3)) {
9640 this.scanner.next();
9641 offset++;
9642 message = 'Name is expected';
9643 }
9644 break;
9645
9646 case PERCENTAGE$3:
9647 if (this.scanner.tokenType === NUMBER$7) {
9648 offset = this.scanner.tokenEnd;
9649 message = 'Percent sign is expected';
9650 }
9651 break;
9652
9653 default:
9654 // when test type is part of another token show error for current position + 1
9655 // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
9656 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === tokenType) {
9657 offset = offset + 1;
9658 }
9659 }
9660
9661 this.error(message, offset);
9662 }
9663
9664 this.scanner.next();
9665 },
9666
9667 consume: function(tokenType) {
9668 var value = this.scanner.getTokenValue();
9669
9670 this.eat(tokenType);
9671
9672 return value;
9673 },
9674 consumeFunctionName: function() {
9675 var name = this.scanner.source.substring(this.scanner.tokenStart, this.scanner.tokenEnd - 1);
9676
9677 this.eat(FUNCTION$6);
9678
9679 return name;
9680 },
9681
9682 getLocation: function(start, end) {
9683 if (this.needPositions) {
9684 return this.locationMap.getLocationRange(
9685 start,
9686 end,
9687 this.filename
9688 );
9689 }
9690
9691 return null;
9692 },
9693 getLocationFromList: function(list) {
9694 if (this.needPositions) {
9695 var head = this.getFirstListNode(list);
9696 var tail = this.getLastListNode(list);
9697 return this.locationMap.getLocationRange(
9698 head !== null ? head.loc.start.offset - this.locationMap.startOffset : this.scanner.tokenStart,
9699 tail !== null ? tail.loc.end.offset - this.locationMap.startOffset : this.scanner.tokenStart,
9700 this.filename
9701 );
9702 }
9703
9704 return null;
9705 },
9706
9707 error: function(message, offset) {
9708 var location = typeof offset !== 'undefined' && offset < this.scanner.source.length
9709 ? this.locationMap.getLocation(offset)
9710 : this.scanner.eof
9711 ? this.locationMap.getLocation(findWhiteSpaceStart(this.scanner.source, this.scanner.source.length - 1))
9712 : this.locationMap.getLocation(this.scanner.tokenStart);
9713
9714 throw new SyntaxError$2(
9715 message || 'Unexpected input',
9716 this.scanner.source,
9717 location.offset,
9718 location.line,
9719 location.column
9720 );
9721 }
9722 };
9723
9724 config = processConfig(config || {});
9725 for (var key in config) {
9726 parser[key] = config[key];
9727 }
9728
9729 return function(source, options) {
9730 options = options || {};
9731
9732 var context = options.context || 'default';
9733 var onComment = options.onComment;
9734 var ast;
9735
9736 tokenize$1(source, parser.scanner);
9737 parser.locationMap.setSource(
9738 source,
9739 options.offset,
9740 options.line,
9741 options.column
9742 );
9743
9744 parser.filename = options.filename || '<unknown>';
9745 parser.needPositions = Boolean(options.positions);
9746 parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$1;
9747 parser.onParseErrorThrow = false;
9748 parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
9749 parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
9750 parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
9751 parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
9752
9753 if (!parser.context.hasOwnProperty(context)) {
9754 throw new Error('Unknown context `' + context + '`');
9755 }
9756
9757 if (typeof onComment === 'function') {
9758 parser.scanner.forEachToken((type, start, end) => {
9759 if (type === COMMENT$7) {
9760 const loc = parser.getLocation(start, end);
9761 const value = cmpStr$2(source, end - 2, end, '*/')
9762 ? source.slice(start + 2, end - 2)
9763 : source.slice(start + 2, end);
9764
9765 onComment(value, loc);
9766 }
9767 });
9768 }
9769
9770 ast = parser.context[context].call(parser, options);
9771
9772 if (!parser.scanner.eof) {
9773 parser.error();
9774 }
9775
9776 return ast;
9777 };
9778};
9779
9780var sourceMapGenerator = {};
9781
9782var base64Vlq = {};
9783
9784var base64$1 = {};
9785
9786/* -*- Mode: js; js-indent-level: 2; -*- */
9787
9788/*
9789 * Copyright 2011 Mozilla Foundation and contributors
9790 * Licensed under the New BSD license. See LICENSE or:
9791 * http://opensource.org/licenses/BSD-3-Clause
9792 */
9793
9794var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
9795
9796/**
9797 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
9798 */
9799base64$1.encode = function (number) {
9800 if (0 <= number && number < intToCharMap.length) {
9801 return intToCharMap[number];
9802 }
9803 throw new TypeError("Must be between 0 and 63: " + number);
9804};
9805
9806/**
9807 * Decode a single base 64 character code digit to an integer. Returns -1 on
9808 * failure.
9809 */
9810base64$1.decode = function (charCode) {
9811 var bigA = 65; // 'A'
9812 var bigZ = 90; // 'Z'
9813
9814 var littleA = 97; // 'a'
9815 var littleZ = 122; // 'z'
9816
9817 var zero = 48; // '0'
9818 var nine = 57; // '9'
9819
9820 var plus = 43; // '+'
9821 var slash = 47; // '/'
9822
9823 var littleOffset = 26;
9824 var numberOffset = 52;
9825
9826 // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
9827 if (bigA <= charCode && charCode <= bigZ) {
9828 return (charCode - bigA);
9829 }
9830
9831 // 26 - 51: abcdefghijklmnopqrstuvwxyz
9832 if (littleA <= charCode && charCode <= littleZ) {
9833 return (charCode - littleA + littleOffset);
9834 }
9835
9836 // 52 - 61: 0123456789
9837 if (zero <= charCode && charCode <= nine) {
9838 return (charCode - zero + numberOffset);
9839 }
9840
9841 // 62: +
9842 if (charCode == plus) {
9843 return 62;
9844 }
9845
9846 // 63: /
9847 if (charCode == slash) {
9848 return 63;
9849 }
9850
9851 // Invalid base64 digit.
9852 return -1;
9853};
9854
9855/* -*- Mode: js; js-indent-level: 2; -*- */
9856
9857/*
9858 * Copyright 2011 Mozilla Foundation and contributors
9859 * Licensed under the New BSD license. See LICENSE or:
9860 * http://opensource.org/licenses/BSD-3-Clause
9861 *
9862 * Based on the Base 64 VLQ implementation in Closure Compiler:
9863 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
9864 *
9865 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
9866 * Redistribution and use in source and binary forms, with or without
9867 * modification, are permitted provided that the following conditions are
9868 * met:
9869 *
9870 * * Redistributions of source code must retain the above copyright
9871 * notice, this list of conditions and the following disclaimer.
9872 * * Redistributions in binary form must reproduce the above
9873 * copyright notice, this list of conditions and the following
9874 * disclaimer in the documentation and/or other materials provided
9875 * with the distribution.
9876 * * Neither the name of Google Inc. nor the names of its
9877 * contributors may be used to endorse or promote products derived
9878 * from this software without specific prior written permission.
9879 *
9880 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9881 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
9882 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9883 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9884 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9885 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9886 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9887 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9888 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9889 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9890 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9891 */
9892
9893var base64 = base64$1;
9894
9895// A single base 64 digit can contain 6 bits of data. For the base 64 variable
9896// length quantities we use in the source map spec, the first bit is the sign,
9897// the next four bits are the actual value, and the 6th bit is the
9898// continuation bit. The continuation bit tells us whether there are more
9899// digits in this value following this digit.
9900//
9901// Continuation
9902// | Sign
9903// | |
9904// V V
9905// 101011
9906
9907var VLQ_BASE_SHIFT = 5;
9908
9909// binary: 100000
9910var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
9911
9912// binary: 011111
9913var VLQ_BASE_MASK = VLQ_BASE - 1;
9914
9915// binary: 100000
9916var VLQ_CONTINUATION_BIT = VLQ_BASE;
9917
9918/**
9919 * Converts from a two-complement value to a value where the sign bit is
9920 * placed in the least significant bit. For example, as decimals:
9921 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
9922 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
9923 */
9924function toVLQSigned(aValue) {
9925 return aValue < 0
9926 ? ((-aValue) << 1) + 1
9927 : (aValue << 1) + 0;
9928}
9929
9930/**
9931 * Converts to a two-complement value from a value where the sign bit is
9932 * placed in the least significant bit. For example, as decimals:
9933 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
9934 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
9935 */
9936function fromVLQSigned(aValue) {
9937 var isNegative = (aValue & 1) === 1;
9938 var shifted = aValue >> 1;
9939 return isNegative
9940 ? -shifted
9941 : shifted;
9942}
9943
9944/**
9945 * Returns the base 64 VLQ encoded value.
9946 */
9947base64Vlq.encode = function base64VLQ_encode(aValue) {
9948 var encoded = "";
9949 var digit;
9950
9951 var vlq = toVLQSigned(aValue);
9952
9953 do {
9954 digit = vlq & VLQ_BASE_MASK;
9955 vlq >>>= VLQ_BASE_SHIFT;
9956 if (vlq > 0) {
9957 // There are still more digits in this value, so we must make sure the
9958 // continuation bit is marked.
9959 digit |= VLQ_CONTINUATION_BIT;
9960 }
9961 encoded += base64.encode(digit);
9962 } while (vlq > 0);
9963
9964 return encoded;
9965};
9966
9967/**
9968 * Decodes the next base 64 VLQ value from the given string and returns the
9969 * value and the rest of the string via the out parameter.
9970 */
9971base64Vlq.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
9972 var strLen = aStr.length;
9973 var result = 0;
9974 var shift = 0;
9975 var continuation, digit;
9976
9977 do {
9978 if (aIndex >= strLen) {
9979 throw new Error("Expected more digits in base 64 VLQ value.");
9980 }
9981
9982 digit = base64.decode(aStr.charCodeAt(aIndex++));
9983 if (digit === -1) {
9984 throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
9985 }
9986
9987 continuation = !!(digit & VLQ_CONTINUATION_BIT);
9988 digit &= VLQ_BASE_MASK;
9989 result = result + (digit << shift);
9990 shift += VLQ_BASE_SHIFT;
9991 } while (continuation);
9992
9993 aOutParam.value = fromVLQSigned(result);
9994 aOutParam.rest = aIndex;
9995};
9996
9997var util$3 = {};
9998
9999/* -*- Mode: js; js-indent-level: 2; -*- */
10000
10001(function (exports) {
10002 /*
10003 * Copyright 2011 Mozilla Foundation and contributors
10004 * Licensed under the New BSD license. See LICENSE or:
10005 * http://opensource.org/licenses/BSD-3-Clause
10006 */
10007
10008 /**
10009 * This is a helper function for getting values from parameter/options
10010 * objects.
10011 *
10012 * @param args The object we are extracting values from
10013 * @param name The name of the property we are getting.
10014 * @param defaultValue An optional value to return if the property is missing
10015 * from the object. If this is not specified and the property is missing, an
10016 * error will be thrown.
10017 */
10018 function getArg(aArgs, aName, aDefaultValue) {
10019 if (aName in aArgs) {
10020 return aArgs[aName];
10021 } else if (arguments.length === 3) {
10022 return aDefaultValue;
10023 } else {
10024 throw new Error('"' + aName + '" is a required argument.');
10025 }
10026 }
10027 exports.getArg = getArg;
10028
10029 var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
10030 var dataUrlRegexp = /^data:.+\,.+$/;
10031
10032 function urlParse(aUrl) {
10033 var match = aUrl.match(urlRegexp);
10034 if (!match) {
10035 return null;
10036 }
10037 return {
10038 scheme: match[1],
10039 auth: match[2],
10040 host: match[3],
10041 port: match[4],
10042 path: match[5]
10043 };
10044 }
10045 exports.urlParse = urlParse;
10046
10047 function urlGenerate(aParsedUrl) {
10048 var url = '';
10049 if (aParsedUrl.scheme) {
10050 url += aParsedUrl.scheme + ':';
10051 }
10052 url += '//';
10053 if (aParsedUrl.auth) {
10054 url += aParsedUrl.auth + '@';
10055 }
10056 if (aParsedUrl.host) {
10057 url += aParsedUrl.host;
10058 }
10059 if (aParsedUrl.port) {
10060 url += ":" + aParsedUrl.port;
10061 }
10062 if (aParsedUrl.path) {
10063 url += aParsedUrl.path;
10064 }
10065 return url;
10066 }
10067 exports.urlGenerate = urlGenerate;
10068
10069 /**
10070 * Normalizes a path, or the path portion of a URL:
10071 *
10072 * - Replaces consecutive slashes with one slash.
10073 * - Removes unnecessary '.' parts.
10074 * - Removes unnecessary '<dir>/..' parts.
10075 *
10076 * Based on code in the Node.js 'path' core module.
10077 *
10078 * @param aPath The path or url to normalize.
10079 */
10080 function normalize(aPath) {
10081 var path = aPath;
10082 var url = urlParse(aPath);
10083 if (url) {
10084 if (!url.path) {
10085 return aPath;
10086 }
10087 path = url.path;
10088 }
10089 var isAbsolute = exports.isAbsolute(path);
10090
10091 var parts = path.split(/\/+/);
10092 for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
10093 part = parts[i];
10094 if (part === '.') {
10095 parts.splice(i, 1);
10096 } else if (part === '..') {
10097 up++;
10098 } else if (up > 0) {
10099 if (part === '') {
10100 // The first part is blank if the path is absolute. Trying to go
10101 // above the root is a no-op. Therefore we can remove all '..' parts
10102 // directly after the root.
10103 parts.splice(i + 1, up);
10104 up = 0;
10105 } else {
10106 parts.splice(i, 2);
10107 up--;
10108 }
10109 }
10110 }
10111 path = parts.join('/');
10112
10113 if (path === '') {
10114 path = isAbsolute ? '/' : '.';
10115 }
10116
10117 if (url) {
10118 url.path = path;
10119 return urlGenerate(url);
10120 }
10121 return path;
10122 }
10123 exports.normalize = normalize;
10124
10125 /**
10126 * Joins two paths/URLs.
10127 *
10128 * @param aRoot The root path or URL.
10129 * @param aPath The path or URL to be joined with the root.
10130 *
10131 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
10132 * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
10133 * first.
10134 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
10135 * is updated with the result and aRoot is returned. Otherwise the result
10136 * is returned.
10137 * - If aPath is absolute, the result is aPath.
10138 * - Otherwise the two paths are joined with a slash.
10139 * - Joining for example 'http://' and 'www.example.com' is also supported.
10140 */
10141 function join(aRoot, aPath) {
10142 if (aRoot === "") {
10143 aRoot = ".";
10144 }
10145 if (aPath === "") {
10146 aPath = ".";
10147 }
10148 var aPathUrl = urlParse(aPath);
10149 var aRootUrl = urlParse(aRoot);
10150 if (aRootUrl) {
10151 aRoot = aRootUrl.path || '/';
10152 }
10153
10154 // `join(foo, '//www.example.org')`
10155 if (aPathUrl && !aPathUrl.scheme) {
10156 if (aRootUrl) {
10157 aPathUrl.scheme = aRootUrl.scheme;
10158 }
10159 return urlGenerate(aPathUrl);
10160 }
10161
10162 if (aPathUrl || aPath.match(dataUrlRegexp)) {
10163 return aPath;
10164 }
10165
10166 // `join('http://', 'www.example.com')`
10167 if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
10168 aRootUrl.host = aPath;
10169 return urlGenerate(aRootUrl);
10170 }
10171
10172 var joined = aPath.charAt(0) === '/'
10173 ? aPath
10174 : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
10175
10176 if (aRootUrl) {
10177 aRootUrl.path = joined;
10178 return urlGenerate(aRootUrl);
10179 }
10180 return joined;
10181 }
10182 exports.join = join;
10183
10184 exports.isAbsolute = function (aPath) {
10185 return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
10186 };
10187
10188 /**
10189 * Make a path relative to a URL or another path.
10190 *
10191 * @param aRoot The root path or URL.
10192 * @param aPath The path or URL to be made relative to aRoot.
10193 */
10194 function relative(aRoot, aPath) {
10195 if (aRoot === "") {
10196 aRoot = ".";
10197 }
10198
10199 aRoot = aRoot.replace(/\/$/, '');
10200
10201 // It is possible for the path to be above the root. In this case, simply
10202 // checking whether the root is a prefix of the path won't work. Instead, we
10203 // need to remove components from the root one by one, until either we find
10204 // a prefix that fits, or we run out of components to remove.
10205 var level = 0;
10206 while (aPath.indexOf(aRoot + '/') !== 0) {
10207 var index = aRoot.lastIndexOf("/");
10208 if (index < 0) {
10209 return aPath;
10210 }
10211
10212 // If the only part of the root that is left is the scheme (i.e. http://,
10213 // file:///, etc.), one or more slashes (/), or simply nothing at all, we
10214 // have exhausted all components, so the path is not relative to the root.
10215 aRoot = aRoot.slice(0, index);
10216 if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
10217 return aPath;
10218 }
10219
10220 ++level;
10221 }
10222
10223 // Make sure we add a "../" for each component we removed from the root.
10224 return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
10225 }
10226 exports.relative = relative;
10227
10228 var supportsNullProto = (function () {
10229 var obj = Object.create(null);
10230 return !('__proto__' in obj);
10231 }());
10232
10233 function identity (s) {
10234 return s;
10235 }
10236
10237 /**
10238 * Because behavior goes wacky when you set `__proto__` on objects, we
10239 * have to prefix all the strings in our set with an arbitrary character.
10240 *
10241 * See https://github.com/mozilla/source-map/pull/31 and
10242 * https://github.com/mozilla/source-map/issues/30
10243 *
10244 * @param String aStr
10245 */
10246 function toSetString(aStr) {
10247 if (isProtoString(aStr)) {
10248 return '$' + aStr;
10249 }
10250
10251 return aStr;
10252 }
10253 exports.toSetString = supportsNullProto ? identity : toSetString;
10254
10255 function fromSetString(aStr) {
10256 if (isProtoString(aStr)) {
10257 return aStr.slice(1);
10258 }
10259
10260 return aStr;
10261 }
10262 exports.fromSetString = supportsNullProto ? identity : fromSetString;
10263
10264 function isProtoString(s) {
10265 if (!s) {
10266 return false;
10267 }
10268
10269 var length = s.length;
10270
10271 if (length < 9 /* "__proto__".length */) {
10272 return false;
10273 }
10274
10275 if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
10276 s.charCodeAt(length - 2) !== 95 /* '_' */ ||
10277 s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
10278 s.charCodeAt(length - 4) !== 116 /* 't' */ ||
10279 s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
10280 s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
10281 s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
10282 s.charCodeAt(length - 8) !== 95 /* '_' */ ||
10283 s.charCodeAt(length - 9) !== 95 /* '_' */) {
10284 return false;
10285 }
10286
10287 for (var i = length - 10; i >= 0; i--) {
10288 if (s.charCodeAt(i) !== 36 /* '$' */) {
10289 return false;
10290 }
10291 }
10292
10293 return true;
10294 }
10295
10296 /**
10297 * Comparator between two mappings where the original positions are compared.
10298 *
10299 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
10300 * mappings with the same original source/line/column, but different generated
10301 * line and column the same. Useful when searching for a mapping with a
10302 * stubbed out mapping.
10303 */
10304 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
10305 var cmp = strcmp(mappingA.source, mappingB.source);
10306 if (cmp !== 0) {
10307 return cmp;
10308 }
10309
10310 cmp = mappingA.originalLine - mappingB.originalLine;
10311 if (cmp !== 0) {
10312 return cmp;
10313 }
10314
10315 cmp = mappingA.originalColumn - mappingB.originalColumn;
10316 if (cmp !== 0 || onlyCompareOriginal) {
10317 return cmp;
10318 }
10319
10320 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
10321 if (cmp !== 0) {
10322 return cmp;
10323 }
10324
10325 cmp = mappingA.generatedLine - mappingB.generatedLine;
10326 if (cmp !== 0) {
10327 return cmp;
10328 }
10329
10330 return strcmp(mappingA.name, mappingB.name);
10331 }
10332 exports.compareByOriginalPositions = compareByOriginalPositions;
10333
10334 /**
10335 * Comparator between two mappings with deflated source and name indices where
10336 * the generated positions are compared.
10337 *
10338 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
10339 * mappings with the same generated line and column, but different
10340 * source/name/original line and column the same. Useful when searching for a
10341 * mapping with a stubbed out mapping.
10342 */
10343 function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
10344 var cmp = mappingA.generatedLine - mappingB.generatedLine;
10345 if (cmp !== 0) {
10346 return cmp;
10347 }
10348
10349 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
10350 if (cmp !== 0 || onlyCompareGenerated) {
10351 return cmp;
10352 }
10353
10354 cmp = strcmp(mappingA.source, mappingB.source);
10355 if (cmp !== 0) {
10356 return cmp;
10357 }
10358
10359 cmp = mappingA.originalLine - mappingB.originalLine;
10360 if (cmp !== 0) {
10361 return cmp;
10362 }
10363
10364 cmp = mappingA.originalColumn - mappingB.originalColumn;
10365 if (cmp !== 0) {
10366 return cmp;
10367 }
10368
10369 return strcmp(mappingA.name, mappingB.name);
10370 }
10371 exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
10372
10373 function strcmp(aStr1, aStr2) {
10374 if (aStr1 === aStr2) {
10375 return 0;
10376 }
10377
10378 if (aStr1 === null) {
10379 return 1; // aStr2 !== null
10380 }
10381
10382 if (aStr2 === null) {
10383 return -1; // aStr1 !== null
10384 }
10385
10386 if (aStr1 > aStr2) {
10387 return 1;
10388 }
10389
10390 return -1;
10391 }
10392
10393 /**
10394 * Comparator between two mappings with inflated source and name strings where
10395 * the generated positions are compared.
10396 */
10397 function compareByGeneratedPositionsInflated(mappingA, mappingB) {
10398 var cmp = mappingA.generatedLine - mappingB.generatedLine;
10399 if (cmp !== 0) {
10400 return cmp;
10401 }
10402
10403 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
10404 if (cmp !== 0) {
10405 return cmp;
10406 }
10407
10408 cmp = strcmp(mappingA.source, mappingB.source);
10409 if (cmp !== 0) {
10410 return cmp;
10411 }
10412
10413 cmp = mappingA.originalLine - mappingB.originalLine;
10414 if (cmp !== 0) {
10415 return cmp;
10416 }
10417
10418 cmp = mappingA.originalColumn - mappingB.originalColumn;
10419 if (cmp !== 0) {
10420 return cmp;
10421 }
10422
10423 return strcmp(mappingA.name, mappingB.name);
10424 }
10425 exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
10426
10427 /**
10428 * Strip any JSON XSSI avoidance prefix from the string (as documented
10429 * in the source maps specification), and then parse the string as
10430 * JSON.
10431 */
10432 function parseSourceMapInput(str) {
10433 return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
10434 }
10435 exports.parseSourceMapInput = parseSourceMapInput;
10436
10437 /**
10438 * Compute the URL of a source given the the source root, the source's
10439 * URL, and the source map's URL.
10440 */
10441 function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
10442 sourceURL = sourceURL || '';
10443
10444 if (sourceRoot) {
10445 // This follows what Chrome does.
10446 if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
10447 sourceRoot += '/';
10448 }
10449 // The spec says:
10450 // Line 4: An optional source root, useful for relocating source
10451 // files on a server or removing repeated values in the
10452 // “sources” entry. This value is prepended to the individual
10453 // entries in the “source” field.
10454 sourceURL = sourceRoot + sourceURL;
10455 }
10456
10457 // Historically, SourceMapConsumer did not take the sourceMapURL as
10458 // a parameter. This mode is still somewhat supported, which is why
10459 // this code block is conditional. However, it's preferable to pass
10460 // the source map URL to SourceMapConsumer, so that this function
10461 // can implement the source URL resolution algorithm as outlined in
10462 // the spec. This block is basically the equivalent of:
10463 // new URL(sourceURL, sourceMapURL).toString()
10464 // ... except it avoids using URL, which wasn't available in the
10465 // older releases of node still supported by this library.
10466 //
10467 // The spec says:
10468 // If the sources are not absolute URLs after prepending of the
10469 // “sourceRoot”, the sources are resolved relative to the
10470 // SourceMap (like resolving script src in a html document).
10471 if (sourceMapURL) {
10472 var parsed = urlParse(sourceMapURL);
10473 if (!parsed) {
10474 throw new Error("sourceMapURL could not be parsed");
10475 }
10476 if (parsed.path) {
10477 // Strip the last path component, but keep the "/".
10478 var index = parsed.path.lastIndexOf('/');
10479 if (index >= 0) {
10480 parsed.path = parsed.path.substring(0, index + 1);
10481 }
10482 }
10483 sourceURL = join(urlGenerate(parsed), sourceURL);
10484 }
10485
10486 return normalize(sourceURL);
10487 }
10488 exports.computeSourceURL = computeSourceURL;
10489} (util$3));
10490
10491var arraySet = {};
10492
10493/* -*- Mode: js; js-indent-level: 2; -*- */
10494
10495/*
10496 * Copyright 2011 Mozilla Foundation and contributors
10497 * Licensed under the New BSD license. See LICENSE or:
10498 * http://opensource.org/licenses/BSD-3-Clause
10499 */
10500
10501var util$2 = util$3;
10502var has$1 = Object.prototype.hasOwnProperty;
10503var hasNativeMap = typeof Map !== "undefined";
10504
10505/**
10506 * A data structure which is a combination of an array and a set. Adding a new
10507 * member is O(1), testing for membership is O(1), and finding the index of an
10508 * element is O(1). Removing elements from the set is not supported. Only
10509 * strings are supported for membership.
10510 */
10511function ArraySet$1() {
10512 this._array = [];
10513 this._set = hasNativeMap ? new Map() : Object.create(null);
10514}
10515
10516/**
10517 * Static method for creating ArraySet instances from an existing array.
10518 */
10519ArraySet$1.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
10520 var set = new ArraySet$1();
10521 for (var i = 0, len = aArray.length; i < len; i++) {
10522 set.add(aArray[i], aAllowDuplicates);
10523 }
10524 return set;
10525};
10526
10527/**
10528 * Return how many unique items are in this ArraySet. If duplicates have been
10529 * added, than those do not count towards the size.
10530 *
10531 * @returns Number
10532 */
10533ArraySet$1.prototype.size = function ArraySet_size() {
10534 return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
10535};
10536
10537/**
10538 * Add the given string to this set.
10539 *
10540 * @param String aStr
10541 */
10542ArraySet$1.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
10543 var sStr = hasNativeMap ? aStr : util$2.toSetString(aStr);
10544 var isDuplicate = hasNativeMap ? this.has(aStr) : has$1.call(this._set, sStr);
10545 var idx = this._array.length;
10546 if (!isDuplicate || aAllowDuplicates) {
10547 this._array.push(aStr);
10548 }
10549 if (!isDuplicate) {
10550 if (hasNativeMap) {
10551 this._set.set(aStr, idx);
10552 } else {
10553 this._set[sStr] = idx;
10554 }
10555 }
10556};
10557
10558/**
10559 * Is the given string a member of this set?
10560 *
10561 * @param String aStr
10562 */
10563ArraySet$1.prototype.has = function ArraySet_has(aStr) {
10564 if (hasNativeMap) {
10565 return this._set.has(aStr);
10566 } else {
10567 var sStr = util$2.toSetString(aStr);
10568 return has$1.call(this._set, sStr);
10569 }
10570};
10571
10572/**
10573 * What is the index of the given string in the array?
10574 *
10575 * @param String aStr
10576 */
10577ArraySet$1.prototype.indexOf = function ArraySet_indexOf(aStr) {
10578 if (hasNativeMap) {
10579 var idx = this._set.get(aStr);
10580 if (idx >= 0) {
10581 return idx;
10582 }
10583 } else {
10584 var sStr = util$2.toSetString(aStr);
10585 if (has$1.call(this._set, sStr)) {
10586 return this._set[sStr];
10587 }
10588 }
10589
10590 throw new Error('"' + aStr + '" is not in the set.');
10591};
10592
10593/**
10594 * What is the element at the given index?
10595 *
10596 * @param Number aIdx
10597 */
10598ArraySet$1.prototype.at = function ArraySet_at(aIdx) {
10599 if (aIdx >= 0 && aIdx < this._array.length) {
10600 return this._array[aIdx];
10601 }
10602 throw new Error('No element indexed by ' + aIdx);
10603};
10604
10605/**
10606 * Returns the array representation of this set (which has the proper indices
10607 * indicated by indexOf). Note that this is a copy of the internal array used
10608 * for storing the members so that no one can mess with internal state.
10609 */
10610ArraySet$1.prototype.toArray = function ArraySet_toArray() {
10611 return this._array.slice();
10612};
10613
10614arraySet.ArraySet = ArraySet$1;
10615
10616var mappingList = {};
10617
10618/* -*- Mode: js; js-indent-level: 2; -*- */
10619
10620/*
10621 * Copyright 2014 Mozilla Foundation and contributors
10622 * Licensed under the New BSD license. See LICENSE or:
10623 * http://opensource.org/licenses/BSD-3-Clause
10624 */
10625
10626var util$1 = util$3;
10627
10628/**
10629 * Determine whether mappingB is after mappingA with respect to generated
10630 * position.
10631 */
10632function generatedPositionAfter(mappingA, mappingB) {
10633 // Optimized for most common case
10634 var lineA = mappingA.generatedLine;
10635 var lineB = mappingB.generatedLine;
10636 var columnA = mappingA.generatedColumn;
10637 var columnB = mappingB.generatedColumn;
10638 return lineB > lineA || lineB == lineA && columnB >= columnA ||
10639 util$1.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
10640}
10641
10642/**
10643 * A data structure to provide a sorted view of accumulated mappings in a
10644 * performance conscious manner. It trades a neglibable overhead in general
10645 * case for a large speedup in case of mappings being added in order.
10646 */
10647function MappingList$1() {
10648 this._array = [];
10649 this._sorted = true;
10650 // Serves as infimum
10651 this._last = {generatedLine: -1, generatedColumn: 0};
10652}
10653
10654/**
10655 * Iterate through internal items. This method takes the same arguments that
10656 * `Array.prototype.forEach` takes.
10657 *
10658 * NOTE: The order of the mappings is NOT guaranteed.
10659 */
10660MappingList$1.prototype.unsortedForEach =
10661 function MappingList_forEach(aCallback, aThisArg) {
10662 this._array.forEach(aCallback, aThisArg);
10663 };
10664
10665/**
10666 * Add the given source mapping.
10667 *
10668 * @param Object aMapping
10669 */
10670MappingList$1.prototype.add = function MappingList_add(aMapping) {
10671 if (generatedPositionAfter(this._last, aMapping)) {
10672 this._last = aMapping;
10673 this._array.push(aMapping);
10674 } else {
10675 this._sorted = false;
10676 this._array.push(aMapping);
10677 }
10678};
10679
10680/**
10681 * Returns the flat, sorted array of mappings. The mappings are sorted by
10682 * generated position.
10683 *
10684 * WARNING: This method returns internal data without copying, for
10685 * performance. The return value must NOT be mutated, and should be treated as
10686 * an immutable borrow. If you want to take ownership, you must make your own
10687 * copy.
10688 */
10689MappingList$1.prototype.toArray = function MappingList_toArray() {
10690 if (!this._sorted) {
10691 this._array.sort(util$1.compareByGeneratedPositionsInflated);
10692 this._sorted = true;
10693 }
10694 return this._array;
10695};
10696
10697mappingList.MappingList = MappingList$1;
10698
10699/* -*- Mode: js; js-indent-level: 2; -*- */
10700
10701/*
10702 * Copyright 2011 Mozilla Foundation and contributors
10703 * Licensed under the New BSD license. See LICENSE or:
10704 * http://opensource.org/licenses/BSD-3-Clause
10705 */
10706
10707var base64VLQ = base64Vlq;
10708var util = util$3;
10709var ArraySet = arraySet.ArraySet;
10710var MappingList = mappingList.MappingList;
10711
10712/**
10713 * An instance of the SourceMapGenerator represents a source map which is
10714 * being built incrementally. You may pass an object with the following
10715 * properties:
10716 *
10717 * - file: The filename of the generated source.
10718 * - sourceRoot: A root for all relative URLs in this source map.
10719 */
10720function SourceMapGenerator$1(aArgs) {
10721 if (!aArgs) {
10722 aArgs = {};
10723 }
10724 this._file = util.getArg(aArgs, 'file', null);
10725 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
10726 this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
10727 this._sources = new ArraySet();
10728 this._names = new ArraySet();
10729 this._mappings = new MappingList();
10730 this._sourcesContents = null;
10731}
10732
10733SourceMapGenerator$1.prototype._version = 3;
10734
10735/**
10736 * Creates a new SourceMapGenerator based on a SourceMapConsumer
10737 *
10738 * @param aSourceMapConsumer The SourceMap.
10739 */
10740SourceMapGenerator$1.fromSourceMap =
10741 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
10742 var sourceRoot = aSourceMapConsumer.sourceRoot;
10743 var generator = new SourceMapGenerator$1({
10744 file: aSourceMapConsumer.file,
10745 sourceRoot: sourceRoot
10746 });
10747 aSourceMapConsumer.eachMapping(function (mapping) {
10748 var newMapping = {
10749 generated: {
10750 line: mapping.generatedLine,
10751 column: mapping.generatedColumn
10752 }
10753 };
10754
10755 if (mapping.source != null) {
10756 newMapping.source = mapping.source;
10757 if (sourceRoot != null) {
10758 newMapping.source = util.relative(sourceRoot, newMapping.source);
10759 }
10760
10761 newMapping.original = {
10762 line: mapping.originalLine,
10763 column: mapping.originalColumn
10764 };
10765
10766 if (mapping.name != null) {
10767 newMapping.name = mapping.name;
10768 }
10769 }
10770
10771 generator.addMapping(newMapping);
10772 });
10773 aSourceMapConsumer.sources.forEach(function (sourceFile) {
10774 var sourceRelative = sourceFile;
10775 if (sourceRoot !== null) {
10776 sourceRelative = util.relative(sourceRoot, sourceFile);
10777 }
10778
10779 if (!generator._sources.has(sourceRelative)) {
10780 generator._sources.add(sourceRelative);
10781 }
10782
10783 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10784 if (content != null) {
10785 generator.setSourceContent(sourceFile, content);
10786 }
10787 });
10788 return generator;
10789 };
10790
10791/**
10792 * Add a single mapping from original source line and column to the generated
10793 * source's line and column for this source map being created. The mapping
10794 * object should have the following properties:
10795 *
10796 * - generated: An object with the generated line and column positions.
10797 * - original: An object with the original line and column positions.
10798 * - source: The original source file (relative to the sourceRoot).
10799 * - name: An optional original token name for this mapping.
10800 */
10801SourceMapGenerator$1.prototype.addMapping =
10802 function SourceMapGenerator_addMapping(aArgs) {
10803 var generated = util.getArg(aArgs, 'generated');
10804 var original = util.getArg(aArgs, 'original', null);
10805 var source = util.getArg(aArgs, 'source', null);
10806 var name = util.getArg(aArgs, 'name', null);
10807
10808 if (!this._skipValidation) {
10809 this._validateMapping(generated, original, source, name);
10810 }
10811
10812 if (source != null) {
10813 source = String(source);
10814 if (!this._sources.has(source)) {
10815 this._sources.add(source);
10816 }
10817 }
10818
10819 if (name != null) {
10820 name = String(name);
10821 if (!this._names.has(name)) {
10822 this._names.add(name);
10823 }
10824 }
10825
10826 this._mappings.add({
10827 generatedLine: generated.line,
10828 generatedColumn: generated.column,
10829 originalLine: original != null && original.line,
10830 originalColumn: original != null && original.column,
10831 source: source,
10832 name: name
10833 });
10834 };
10835
10836/**
10837 * Set the source content for a source file.
10838 */
10839SourceMapGenerator$1.prototype.setSourceContent =
10840 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
10841 var source = aSourceFile;
10842 if (this._sourceRoot != null) {
10843 source = util.relative(this._sourceRoot, source);
10844 }
10845
10846 if (aSourceContent != null) {
10847 // Add the source content to the _sourcesContents map.
10848 // Create a new _sourcesContents map if the property is null.
10849 if (!this._sourcesContents) {
10850 this._sourcesContents = Object.create(null);
10851 }
10852 this._sourcesContents[util.toSetString(source)] = aSourceContent;
10853 } else if (this._sourcesContents) {
10854 // Remove the source file from the _sourcesContents map.
10855 // If the _sourcesContents map is empty, set the property to null.
10856 delete this._sourcesContents[util.toSetString(source)];
10857 if (Object.keys(this._sourcesContents).length === 0) {
10858 this._sourcesContents = null;
10859 }
10860 }
10861 };
10862
10863/**
10864 * Applies the mappings of a sub-source-map for a specific source file to the
10865 * source map being generated. Each mapping to the supplied source file is
10866 * rewritten using the supplied source map. Note: The resolution for the
10867 * resulting mappings is the minimium of this map and the supplied map.
10868 *
10869 * @param aSourceMapConsumer The source map to be applied.
10870 * @param aSourceFile Optional. The filename of the source file.
10871 * If omitted, SourceMapConsumer's file property will be used.
10872 * @param aSourceMapPath Optional. The dirname of the path to the source map
10873 * to be applied. If relative, it is relative to the SourceMapConsumer.
10874 * This parameter is needed when the two source maps aren't in the same
10875 * directory, and the source map to be applied contains relative source
10876 * paths. If so, those relative source paths need to be rewritten
10877 * relative to the SourceMapGenerator.
10878 */
10879SourceMapGenerator$1.prototype.applySourceMap =
10880 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
10881 var sourceFile = aSourceFile;
10882 // If aSourceFile is omitted, we will use the file property of the SourceMap
10883 if (aSourceFile == null) {
10884 if (aSourceMapConsumer.file == null) {
10885 throw new Error(
10886 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
10887 'or the source map\'s "file" property. Both were omitted.'
10888 );
10889 }
10890 sourceFile = aSourceMapConsumer.file;
10891 }
10892 var sourceRoot = this._sourceRoot;
10893 // Make "sourceFile" relative if an absolute Url is passed.
10894 if (sourceRoot != null) {
10895 sourceFile = util.relative(sourceRoot, sourceFile);
10896 }
10897 // Applying the SourceMap can add and remove items from the sources and
10898 // the names array.
10899 var newSources = new ArraySet();
10900 var newNames = new ArraySet();
10901
10902 // Find mappings for the "sourceFile"
10903 this._mappings.unsortedForEach(function (mapping) {
10904 if (mapping.source === sourceFile && mapping.originalLine != null) {
10905 // Check if it can be mapped by the source map, then update the mapping.
10906 var original = aSourceMapConsumer.originalPositionFor({
10907 line: mapping.originalLine,
10908 column: mapping.originalColumn
10909 });
10910 if (original.source != null) {
10911 // Copy mapping
10912 mapping.source = original.source;
10913 if (aSourceMapPath != null) {
10914 mapping.source = util.join(aSourceMapPath, mapping.source);
10915 }
10916 if (sourceRoot != null) {
10917 mapping.source = util.relative(sourceRoot, mapping.source);
10918 }
10919 mapping.originalLine = original.line;
10920 mapping.originalColumn = original.column;
10921 if (original.name != null) {
10922 mapping.name = original.name;
10923 }
10924 }
10925 }
10926
10927 var source = mapping.source;
10928 if (source != null && !newSources.has(source)) {
10929 newSources.add(source);
10930 }
10931
10932 var name = mapping.name;
10933 if (name != null && !newNames.has(name)) {
10934 newNames.add(name);
10935 }
10936
10937 }, this);
10938 this._sources = newSources;
10939 this._names = newNames;
10940
10941 // Copy sourcesContents of applied map.
10942 aSourceMapConsumer.sources.forEach(function (sourceFile) {
10943 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
10944 if (content != null) {
10945 if (aSourceMapPath != null) {
10946 sourceFile = util.join(aSourceMapPath, sourceFile);
10947 }
10948 if (sourceRoot != null) {
10949 sourceFile = util.relative(sourceRoot, sourceFile);
10950 }
10951 this.setSourceContent(sourceFile, content);
10952 }
10953 }, this);
10954 };
10955
10956/**
10957 * A mapping can have one of the three levels of data:
10958 *
10959 * 1. Just the generated position.
10960 * 2. The Generated position, original position, and original source.
10961 * 3. Generated and original position, original source, as well as a name
10962 * token.
10963 *
10964 * To maintain consistency, we validate that any new mapping being added falls
10965 * in to one of these categories.
10966 */
10967SourceMapGenerator$1.prototype._validateMapping =
10968 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
10969 aName) {
10970 // When aOriginal is truthy but has empty values for .line and .column,
10971 // it is most likely a programmer error. In this case we throw a very
10972 // specific error message to try to guide them the right way.
10973 // For example: https://github.com/Polymer/polymer-bundler/pull/519
10974 if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
10975 throw new Error(
10976 'original.line and original.column are not numbers -- you probably meant to omit ' +
10977 'the original mapping entirely and only map the generated position. If so, pass ' +
10978 'null for the original mapping instead of an object with empty or null values.'
10979 );
10980 }
10981
10982 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
10983 && aGenerated.line > 0 && aGenerated.column >= 0
10984 && !aOriginal && !aSource && !aName) {
10985 // Case 1.
10986 return;
10987 }
10988 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
10989 && aOriginal && 'line' in aOriginal && 'column' in aOriginal
10990 && aGenerated.line > 0 && aGenerated.column >= 0
10991 && aOriginal.line > 0 && aOriginal.column >= 0
10992 && aSource) {
10993 // Cases 2 and 3.
10994 return;
10995 }
10996 else {
10997 throw new Error('Invalid mapping: ' + JSON.stringify({
10998 generated: aGenerated,
10999 source: aSource,
11000 original: aOriginal,
11001 name: aName
11002 }));
11003 }
11004 };
11005
11006/**
11007 * Serialize the accumulated mappings in to the stream of base 64 VLQs
11008 * specified by the source map format.
11009 */
11010SourceMapGenerator$1.prototype._serializeMappings =
11011 function SourceMapGenerator_serializeMappings() {
11012 var previousGeneratedColumn = 0;
11013 var previousGeneratedLine = 1;
11014 var previousOriginalColumn = 0;
11015 var previousOriginalLine = 0;
11016 var previousName = 0;
11017 var previousSource = 0;
11018 var result = '';
11019 var next;
11020 var mapping;
11021 var nameIdx;
11022 var sourceIdx;
11023
11024 var mappings = this._mappings.toArray();
11025 for (var i = 0, len = mappings.length; i < len; i++) {
11026 mapping = mappings[i];
11027 next = '';
11028
11029 if (mapping.generatedLine !== previousGeneratedLine) {
11030 previousGeneratedColumn = 0;
11031 while (mapping.generatedLine !== previousGeneratedLine) {
11032 next += ';';
11033 previousGeneratedLine++;
11034 }
11035 }
11036 else {
11037 if (i > 0) {
11038 if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
11039 continue;
11040 }
11041 next += ',';
11042 }
11043 }
11044
11045 next += base64VLQ.encode(mapping.generatedColumn
11046 - previousGeneratedColumn);
11047 previousGeneratedColumn = mapping.generatedColumn;
11048
11049 if (mapping.source != null) {
11050 sourceIdx = this._sources.indexOf(mapping.source);
11051 next += base64VLQ.encode(sourceIdx - previousSource);
11052 previousSource = sourceIdx;
11053
11054 // lines are stored 0-based in SourceMap spec version 3
11055 next += base64VLQ.encode(mapping.originalLine - 1
11056 - previousOriginalLine);
11057 previousOriginalLine = mapping.originalLine - 1;
11058
11059 next += base64VLQ.encode(mapping.originalColumn
11060 - previousOriginalColumn);
11061 previousOriginalColumn = mapping.originalColumn;
11062
11063 if (mapping.name != null) {
11064 nameIdx = this._names.indexOf(mapping.name);
11065 next += base64VLQ.encode(nameIdx - previousName);
11066 previousName = nameIdx;
11067 }
11068 }
11069
11070 result += next;
11071 }
11072
11073 return result;
11074 };
11075
11076SourceMapGenerator$1.prototype._generateSourcesContent =
11077 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
11078 return aSources.map(function (source) {
11079 if (!this._sourcesContents) {
11080 return null;
11081 }
11082 if (aSourceRoot != null) {
11083 source = util.relative(aSourceRoot, source);
11084 }
11085 var key = util.toSetString(source);
11086 return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
11087 ? this._sourcesContents[key]
11088 : null;
11089 }, this);
11090 };
11091
11092/**
11093 * Externalize the source map.
11094 */
11095SourceMapGenerator$1.prototype.toJSON =
11096 function SourceMapGenerator_toJSON() {
11097 var map = {
11098 version: this._version,
11099 sources: this._sources.toArray(),
11100 names: this._names.toArray(),
11101 mappings: this._serializeMappings()
11102 };
11103 if (this._file != null) {
11104 map.file = this._file;
11105 }
11106 if (this._sourceRoot != null) {
11107 map.sourceRoot = this._sourceRoot;
11108 }
11109 if (this._sourcesContents) {
11110 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
11111 }
11112
11113 return map;
11114 };
11115
11116/**
11117 * Render the source map being generated to a string.
11118 */
11119SourceMapGenerator$1.prototype.toString =
11120 function SourceMapGenerator_toString() {
11121 return JSON.stringify(this.toJSON());
11122 };
11123
11124sourceMapGenerator.SourceMapGenerator = SourceMapGenerator$1;
11125
11126var SourceMapGenerator = sourceMapGenerator.SourceMapGenerator;
11127var trackNodes = {
11128 Atrule: true,
11129 Selector: true,
11130 Declaration: true
11131};
11132
11133var sourceMap$1 = function generateSourceMap(handlers) {
11134 var map = new SourceMapGenerator();
11135 var line = 1;
11136 var column = 0;
11137 var generated = {
11138 line: 1,
11139 column: 0
11140 };
11141 var original = {
11142 line: 0, // should be zero to add first mapping
11143 column: 0
11144 };
11145 var sourceMappingActive = false;
11146 var activatedGenerated = {
11147 line: 1,
11148 column: 0
11149 };
11150 var activatedMapping = {
11151 generated: activatedGenerated
11152 };
11153
11154 var handlersNode = handlers.node;
11155 handlers.node = function(node) {
11156 if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
11157 var nodeLine = node.loc.start.line;
11158 var nodeColumn = node.loc.start.column - 1;
11159
11160 if (original.line !== nodeLine ||
11161 original.column !== nodeColumn) {
11162 original.line = nodeLine;
11163 original.column = nodeColumn;
11164
11165 generated.line = line;
11166 generated.column = column;
11167
11168 if (sourceMappingActive) {
11169 sourceMappingActive = false;
11170 if (generated.line !== activatedGenerated.line ||
11171 generated.column !== activatedGenerated.column) {
11172 map.addMapping(activatedMapping);
11173 }
11174 }
11175
11176 sourceMappingActive = true;
11177 map.addMapping({
11178 source: node.loc.source,
11179 original: original,
11180 generated: generated
11181 });
11182 }
11183 }
11184
11185 handlersNode.call(this, node);
11186
11187 if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
11188 activatedGenerated.line = line;
11189 activatedGenerated.column = column;
11190 }
11191 };
11192
11193 var handlersChunk = handlers.chunk;
11194 handlers.chunk = function(chunk) {
11195 for (var i = 0; i < chunk.length; i++) {
11196 if (chunk.charCodeAt(i) === 10) { // \n
11197 line++;
11198 column = 0;
11199 } else {
11200 column++;
11201 }
11202 }
11203
11204 handlersChunk(chunk);
11205 };
11206
11207 var handlersResult = handlers.result;
11208 handlers.result = function() {
11209 if (sourceMappingActive) {
11210 map.addMapping(activatedMapping);
11211 }
11212
11213 return {
11214 css: handlersResult(),
11215 map: map
11216 };
11217 };
11218
11219 return handlers;
11220};
11221
11222var sourceMap = sourceMap$1;
11223var hasOwnProperty$4 = Object.prototype.hasOwnProperty;
11224
11225function processChildren(node, delimeter) {
11226 var list = node.children;
11227 var prev = null;
11228
11229 if (typeof delimeter !== 'function') {
11230 list.forEach(this.node, this);
11231 } else {
11232 list.forEach(function(node) {
11233 if (prev !== null) {
11234 delimeter.call(this, prev);
11235 }
11236
11237 this.node(node);
11238 prev = node;
11239 }, this);
11240 }
11241}
11242
11243var create$2 = function createGenerator(config) {
11244 function processNode(node) {
11245 if (hasOwnProperty$4.call(types, node.type)) {
11246 types[node.type].call(this, node);
11247 } else {
11248 throw new Error('Unknown node type: ' + node.type);
11249 }
11250 }
11251
11252 var types = {};
11253
11254 if (config.node) {
11255 for (var name in config.node) {
11256 types[name] = config.node[name].generate;
11257 }
11258 }
11259
11260 return function(node, options) {
11261 var buffer = '';
11262 var handlers = {
11263 children: processChildren,
11264 node: processNode,
11265 chunk: function(chunk) {
11266 buffer += chunk;
11267 },
11268 result: function() {
11269 return buffer;
11270 }
11271 };
11272
11273 if (options) {
11274 if (typeof options.decorator === 'function') {
11275 handlers = options.decorator(handlers);
11276 }
11277
11278 if (options.sourceMap) {
11279 handlers = sourceMap(handlers);
11280 }
11281 }
11282
11283 handlers.node(node);
11284
11285 return handlers.result();
11286 };
11287};
11288
11289var List$2 = List_1;
11290
11291var create$1 = function createConvertors(walk) {
11292 return {
11293 fromPlainObject: function(ast) {
11294 walk(ast, {
11295 enter: function(node) {
11296 if (node.children && node.children instanceof List$2 === false) {
11297 node.children = new List$2().fromArray(node.children);
11298 }
11299 }
11300 });
11301
11302 return ast;
11303 },
11304 toPlainObject: function(ast) {
11305 walk(ast, {
11306 leave: function(node) {
11307 if (node.children && node.children instanceof List$2) {
11308 node.children = node.children.toArray();
11309 }
11310 }
11311 });
11312
11313 return ast;
11314 }
11315 };
11316};
11317
11318var hasOwnProperty$3 = Object.prototype.hasOwnProperty;
11319var noop = function() {};
11320
11321function ensureFunction(value) {
11322 return typeof value === 'function' ? value : noop;
11323}
11324
11325function invokeForType(fn, type) {
11326 return function(node, item, list) {
11327 if (node.type === type) {
11328 fn.call(this, node, item, list);
11329 }
11330 };
11331}
11332
11333function getWalkersFromStructure(name, nodeType) {
11334 var structure = nodeType.structure;
11335 var walkers = [];
11336
11337 for (var key in structure) {
11338 if (hasOwnProperty$3.call(structure, key) === false) {
11339 continue;
11340 }
11341
11342 var fieldTypes = structure[key];
11343 var walker = {
11344 name: key,
11345 type: false,
11346 nullable: false
11347 };
11348
11349 if (!Array.isArray(structure[key])) {
11350 fieldTypes = [structure[key]];
11351 }
11352
11353 for (var i = 0; i < fieldTypes.length; i++) {
11354 var fieldType = fieldTypes[i];
11355 if (fieldType === null) {
11356 walker.nullable = true;
11357 } else if (typeof fieldType === 'string') {
11358 walker.type = 'node';
11359 } else if (Array.isArray(fieldType)) {
11360 walker.type = 'list';
11361 }
11362 }
11363
11364 if (walker.type) {
11365 walkers.push(walker);
11366 }
11367 }
11368
11369 if (walkers.length) {
11370 return {
11371 context: nodeType.walkContext,
11372 fields: walkers
11373 };
11374 }
11375
11376 return null;
11377}
11378
11379function getTypesFromConfig(config) {
11380 var types = {};
11381
11382 for (var name in config.node) {
11383 if (hasOwnProperty$3.call(config.node, name)) {
11384 var nodeType = config.node[name];
11385
11386 if (!nodeType.structure) {
11387 throw new Error('Missed `structure` field in `' + name + '` node type definition');
11388 }
11389
11390 types[name] = getWalkersFromStructure(name, nodeType);
11391 }
11392 }
11393
11394 return types;
11395}
11396
11397function createTypeIterator(config, reverse) {
11398 var fields = config.fields.slice();
11399 var contextName = config.context;
11400 var useContext = typeof contextName === 'string';
11401
11402 if (reverse) {
11403 fields.reverse();
11404 }
11405
11406 return function(node, context, walk, walkReducer) {
11407 var prevContextValue;
11408
11409 if (useContext) {
11410 prevContextValue = context[contextName];
11411 context[contextName] = node;
11412 }
11413
11414 for (var i = 0; i < fields.length; i++) {
11415 var field = fields[i];
11416 var ref = node[field.name];
11417
11418 if (!field.nullable || ref) {
11419 if (field.type === 'list') {
11420 var breakWalk = reverse
11421 ? ref.reduceRight(walkReducer, false)
11422 : ref.reduce(walkReducer, false);
11423
11424 if (breakWalk) {
11425 return true;
11426 }
11427 } else if (walk(ref)) {
11428 return true;
11429 }
11430 }
11431 }
11432
11433 if (useContext) {
11434 context[contextName] = prevContextValue;
11435 }
11436 };
11437}
11438
11439function createFastTraveralMap(iterators) {
11440 return {
11441 Atrule: {
11442 StyleSheet: iterators.StyleSheet,
11443 Atrule: iterators.Atrule,
11444 Rule: iterators.Rule,
11445 Block: iterators.Block
11446 },
11447 Rule: {
11448 StyleSheet: iterators.StyleSheet,
11449 Atrule: iterators.Atrule,
11450 Rule: iterators.Rule,
11451 Block: iterators.Block
11452 },
11453 Declaration: {
11454 StyleSheet: iterators.StyleSheet,
11455 Atrule: iterators.Atrule,
11456 Rule: iterators.Rule,
11457 Block: iterators.Block,
11458 DeclarationList: iterators.DeclarationList
11459 }
11460 };
11461}
11462
11463var create = function createWalker(config) {
11464 var types = getTypesFromConfig(config);
11465 var iteratorsNatural = {};
11466 var iteratorsReverse = {};
11467 var breakWalk = Symbol('break-walk');
11468 var skipNode = Symbol('skip-node');
11469
11470 for (var name in types) {
11471 if (hasOwnProperty$3.call(types, name) && types[name] !== null) {
11472 iteratorsNatural[name] = createTypeIterator(types[name], false);
11473 iteratorsReverse[name] = createTypeIterator(types[name], true);
11474 }
11475 }
11476
11477 var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
11478 var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
11479
11480 var walk = function(root, options) {
11481 function walkNode(node, item, list) {
11482 var enterRet = enter.call(context, node, item, list);
11483
11484 if (enterRet === breakWalk) {
11485 debugger;
11486 return true;
11487 }
11488
11489 if (enterRet === skipNode) {
11490 return false;
11491 }
11492
11493 if (iterators.hasOwnProperty(node.type)) {
11494 if (iterators[node.type](node, context, walkNode, walkReducer)) {
11495 return true;
11496 }
11497 }
11498
11499 if (leave.call(context, node, item, list) === breakWalk) {
11500 return true;
11501 }
11502
11503 return false;
11504 }
11505
11506 var walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);
11507 var enter = noop;
11508 var leave = noop;
11509 var iterators = iteratorsNatural;
11510 var context = {
11511 break: breakWalk,
11512 skip: skipNode,
11513
11514 root: root,
11515 stylesheet: null,
11516 atrule: null,
11517 atrulePrelude: null,
11518 rule: null,
11519 selector: null,
11520 block: null,
11521 declaration: null,
11522 function: null
11523 };
11524
11525 if (typeof options === 'function') {
11526 enter = options;
11527 } else if (options) {
11528 enter = ensureFunction(options.enter);
11529 leave = ensureFunction(options.leave);
11530
11531 if (options.reverse) {
11532 iterators = iteratorsReverse;
11533 }
11534
11535 if (options.visit) {
11536 if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
11537 iterators = options.reverse
11538 ? fastTraversalIteratorsReverse[options.visit]
11539 : fastTraversalIteratorsNatural[options.visit];
11540 } else if (!types.hasOwnProperty(options.visit)) {
11541 throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
11542 }
11543
11544 enter = invokeForType(enter, options.visit);
11545 leave = invokeForType(leave, options.visit);
11546 }
11547 }
11548
11549 if (enter === noop && leave === noop) {
11550 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
11551 }
11552
11553 walkNode(root);
11554 };
11555
11556 walk.break = breakWalk;
11557 walk.skip = skipNode;
11558
11559 walk.find = function(ast, fn) {
11560 var found = null;
11561
11562 walk(ast, function(node, item, list) {
11563 if (fn.call(this, node, item, list)) {
11564 found = node;
11565 return breakWalk;
11566 }
11567 });
11568
11569 return found;
11570 };
11571
11572 walk.findLast = function(ast, fn) {
11573 var found = null;
11574
11575 walk(ast, {
11576 reverse: true,
11577 enter: function(node, item, list) {
11578 if (fn.call(this, node, item, list)) {
11579 found = node;
11580 return breakWalk;
11581 }
11582 }
11583 });
11584
11585 return found;
11586 };
11587
11588 walk.findAll = function(ast, fn) {
11589 var found = [];
11590
11591 walk(ast, function(node, item, list) {
11592 if (fn.call(this, node, item, list)) {
11593 found.push(node);
11594 }
11595 });
11596
11597 return found;
11598 };
11599
11600 return walk;
11601};
11602
11603var List$1 = List_1;
11604
11605var clone$1 = function clone(node) {
11606 var result = {};
11607
11608 for (var key in node) {
11609 var value = node[key];
11610
11611 if (value) {
11612 if (Array.isArray(value) || value instanceof List$1) {
11613 value = value.map(clone);
11614 } else if (value.constructor === Object) {
11615 value = clone(value);
11616 }
11617 }
11618
11619 result[key] = value;
11620 }
11621
11622 return result;
11623};
11624
11625const hasOwnProperty$2 = Object.prototype.hasOwnProperty;
11626const shape$1 = {
11627 generic: true,
11628 types: appendOrAssign,
11629 atrules: {
11630 prelude: appendOrAssignOrNull,
11631 descriptors: appendOrAssignOrNull
11632 },
11633 properties: appendOrAssign,
11634 parseContext: assign,
11635 scope: deepAssign,
11636 atrule: ['parse'],
11637 pseudo: ['parse'],
11638 node: ['name', 'structure', 'parse', 'generate', 'walkContext']
11639};
11640
11641function isObject$2(value) {
11642 return value && value.constructor === Object;
11643}
11644
11645function copy(value) {
11646 return isObject$2(value)
11647 ? Object.assign({}, value)
11648 : value;
11649}
11650
11651function assign(dest, src) {
11652 return Object.assign(dest, src);
11653}
11654
11655function deepAssign(dest, src) {
11656 for (const key in src) {
11657 if (hasOwnProperty$2.call(src, key)) {
11658 if (isObject$2(dest[key])) {
11659 deepAssign(dest[key], copy(src[key]));
11660 } else {
11661 dest[key] = copy(src[key]);
11662 }
11663 }
11664 }
11665
11666 return dest;
11667}
11668
11669function append(a, b) {
11670 if (typeof b === 'string' && /^\s*\|/.test(b)) {
11671 return typeof a === 'string'
11672 ? a + b
11673 : b.replace(/^\s*\|\s*/, '');
11674 }
11675
11676 return b || null;
11677}
11678
11679function appendOrAssign(a, b) {
11680 if (typeof b === 'string') {
11681 return append(a, b);
11682 }
11683
11684 const result = Object.assign({}, a);
11685 for (let key in b) {
11686 if (hasOwnProperty$2.call(b, key)) {
11687 result[key] = append(hasOwnProperty$2.call(a, key) ? a[key] : undefined, b[key]);
11688 }
11689 }
11690
11691 return result;
11692}
11693
11694function appendOrAssignOrNull(a, b) {
11695 const result = appendOrAssign(a, b);
11696
11697 return !isObject$2(result) || Object.keys(result).length
11698 ? result
11699 : null;
11700}
11701
11702function mix$1(dest, src, shape) {
11703 for (const key in shape) {
11704 if (hasOwnProperty$2.call(shape, key) === false) {
11705 continue;
11706 }
11707
11708 if (shape[key] === true) {
11709 if (key in src) {
11710 if (hasOwnProperty$2.call(src, key)) {
11711 dest[key] = copy(src[key]);
11712 }
11713 }
11714 } else if (shape[key]) {
11715 if (typeof shape[key] === 'function') {
11716 const fn = shape[key];
11717 dest[key] = fn({}, dest[key]);
11718 dest[key] = fn(dest[key] || {}, src[key]);
11719 } else if (isObject$2(shape[key])) {
11720 const result = {};
11721
11722 for (let name in dest[key]) {
11723 result[name] = mix$1({}, dest[key][name], shape[key]);
11724 }
11725
11726 for (let name in src[key]) {
11727 result[name] = mix$1(result[name] || {}, src[key][name], shape[key]);
11728 }
11729
11730 dest[key] = result;
11731 } else if (Array.isArray(shape[key])) {
11732 const res = {};
11733 const innerShape = shape[key].reduce(function(s, k) {
11734 s[k] = true;
11735 return s;
11736 }, {});
11737
11738 for (const [name, value] of Object.entries(dest[key] || {})) {
11739 res[name] = {};
11740 if (value) {
11741 mix$1(res[name], value, innerShape);
11742 }
11743 }
11744
11745 for (const name in src[key]) {
11746 if (hasOwnProperty$2.call(src[key], name)) {
11747 if (!res[name]) {
11748 res[name] = {};
11749 }
11750
11751 if (src[key] && src[key][name]) {
11752 mix$1(res[name], src[key][name], innerShape);
11753 }
11754 }
11755 }
11756
11757 dest[key] = res;
11758 }
11759 }
11760 }
11761 return dest;
11762}
11763
11764var mix_1 = (dest, src) => mix$1(dest, src, shape$1);
11765
11766var List = List_1;
11767var SyntaxError$1 = _SyntaxError$1;
11768var TokenStream = TokenStream_1;
11769var Lexer = Lexer_1;
11770var definitionSyntax = definitionSyntax$1;
11771var tokenize = tokenizer$3;
11772var createParser = create$3;
11773var createGenerator = create$2;
11774var createConvertor = create$1;
11775var createWalker = create;
11776var clone = clone$1;
11777var names = names$2;
11778var mix = mix_1;
11779
11780function createSyntax(config) {
11781 var parse = createParser(config);
11782 var walk = createWalker(config);
11783 var generate = createGenerator(config);
11784 var convert = createConvertor(walk);
11785
11786 var syntax = {
11787 List: List,
11788 SyntaxError: SyntaxError$1,
11789 TokenStream: TokenStream,
11790 Lexer: Lexer,
11791
11792 vendorPrefix: names.vendorPrefix,
11793 keyword: names.keyword,
11794 property: names.property,
11795 isCustomProperty: names.isCustomProperty,
11796
11797 definitionSyntax: definitionSyntax,
11798 lexer: null,
11799 createLexer: function(config) {
11800 return new Lexer(config, syntax, syntax.lexer.structure);
11801 },
11802
11803 tokenize: tokenize,
11804 parse: parse,
11805 walk: walk,
11806 generate: generate,
11807
11808 find: walk.find,
11809 findLast: walk.findLast,
11810 findAll: walk.findAll,
11811
11812 clone: clone,
11813 fromPlainObject: convert.fromPlainObject,
11814 toPlainObject: convert.toPlainObject,
11815
11816 createSyntax: function(config) {
11817 return createSyntax(mix({}, config));
11818 },
11819 fork: function(extension) {
11820 var base = mix({}, config); // copy of config
11821 return createSyntax(
11822 typeof extension === 'function'
11823 ? extension(base, Object.assign)
11824 : mix(base, extension)
11825 );
11826 }
11827 };
11828
11829 syntax.lexer = new Lexer({
11830 generic: true,
11831 types: config.types,
11832 atrules: config.atrules,
11833 properties: config.properties,
11834 node: config.node
11835 }, syntax);
11836
11837 return syntax;
11838}
11839create$4.create = function(config) {
11840 return createSyntax(mix({}, config));
11841};
11842
11843var require$$0 = {
11844 "@charset": {
11845 syntax: "@charset \"<charset>\";",
11846 groups: [
11847 "CSS Charsets"
11848 ],
11849 status: "standard",
11850 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@charset"
11851},
11852 "@counter-style": {
11853 syntax: "@counter-style <counter-style-name> {\n [ system: <counter-system>; ] ||\n [ symbols: <counter-symbols>; ] ||\n [ additive-symbols: <additive-symbols>; ] ||\n [ negative: <negative-symbol>; ] ||\n [ prefix: <prefix>; ] ||\n [ suffix: <suffix>; ] ||\n [ range: <range>; ] ||\n [ pad: <padding>; ] ||\n [ speak-as: <speak-as>; ] ||\n [ fallback: <counter-style-name>; ]\n}",
11854 interfaces: [
11855 "CSSCounterStyleRule"
11856 ],
11857 groups: [
11858 "CSS Counter Styles"
11859 ],
11860 descriptors: {
11861 "additive-symbols": {
11862 syntax: "[ <integer> && <symbol> ]#",
11863 media: "all",
11864 initial: "n/a (required)",
11865 percentages: "no",
11866 computed: "asSpecified",
11867 order: "orderOfAppearance",
11868 status: "standard"
11869 },
11870 fallback: {
11871 syntax: "<counter-style-name>",
11872 media: "all",
11873 initial: "decimal",
11874 percentages: "no",
11875 computed: "asSpecified",
11876 order: "uniqueOrder",
11877 status: "standard"
11878 },
11879 negative: {
11880 syntax: "<symbol> <symbol>?",
11881 media: "all",
11882 initial: "\"-\" hyphen-minus",
11883 percentages: "no",
11884 computed: "asSpecified",
11885 order: "orderOfAppearance",
11886 status: "standard"
11887 },
11888 pad: {
11889 syntax: "<integer> && <symbol>",
11890 media: "all",
11891 initial: "0 \"\"",
11892 percentages: "no",
11893 computed: "asSpecified",
11894 order: "uniqueOrder",
11895 status: "standard"
11896 },
11897 prefix: {
11898 syntax: "<symbol>",
11899 media: "all",
11900 initial: "\"\"",
11901 percentages: "no",
11902 computed: "asSpecified",
11903 order: "uniqueOrder",
11904 status: "standard"
11905 },
11906 range: {
11907 syntax: "[ [ <integer> | infinite ]{2} ]# | auto",
11908 media: "all",
11909 initial: "auto",
11910 percentages: "no",
11911 computed: "asSpecified",
11912 order: "orderOfAppearance",
11913 status: "standard"
11914 },
11915 "speak-as": {
11916 syntax: "auto | bullets | numbers | words | spell-out | <counter-style-name>",
11917 media: "all",
11918 initial: "auto",
11919 percentages: "no",
11920 computed: "asSpecified",
11921 order: "uniqueOrder",
11922 status: "standard"
11923 },
11924 suffix: {
11925 syntax: "<symbol>",
11926 media: "all",
11927 initial: "\". \"",
11928 percentages: "no",
11929 computed: "asSpecified",
11930 order: "uniqueOrder",
11931 status: "standard"
11932 },
11933 symbols: {
11934 syntax: "<symbol>+",
11935 media: "all",
11936 initial: "n/a (required)",
11937 percentages: "no",
11938 computed: "asSpecified",
11939 order: "orderOfAppearance",
11940 status: "standard"
11941 },
11942 system: {
11943 syntax: "cyclic | numeric | alphabetic | symbolic | additive | [ fixed <integer>? ] | [ extends <counter-style-name> ]",
11944 media: "all",
11945 initial: "symbolic",
11946 percentages: "no",
11947 computed: "asSpecified",
11948 order: "uniqueOrder",
11949 status: "standard"
11950 }
11951 },
11952 status: "standard",
11953 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@counter-style"
11954},
11955 "@document": {
11956 syntax: "@document [ <url> | url-prefix(<string>) | domain(<string>) | media-document(<string>) | regexp(<string>) ]# {\n <group-rule-body>\n}",
11957 interfaces: [
11958 "CSSGroupingRule",
11959 "CSSConditionRule"
11960 ],
11961 groups: [
11962 "CSS Conditional Rules"
11963 ],
11964 status: "nonstandard",
11965 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@document"
11966},
11967 "@font-face": {
11968 syntax: "@font-face {\n [ font-family: <family-name>; ] ||\n [ src: <src>; ] ||\n [ unicode-range: <unicode-range>; ] ||\n [ font-variant: <font-variant>; ] ||\n [ font-feature-settings: <font-feature-settings>; ] ||\n [ font-variation-settings: <font-variation-settings>; ] ||\n [ font-stretch: <font-stretch>; ] ||\n [ font-weight: <font-weight>; ] ||\n [ font-style: <font-style>; ]\n}",
11969 interfaces: [
11970 "CSSFontFaceRule"
11971 ],
11972 groups: [
11973 "CSS Fonts"
11974 ],
11975 descriptors: {
11976 "font-display": {
11977 syntax: "[ auto | block | swap | fallback | optional ]",
11978 media: "visual",
11979 percentages: "no",
11980 initial: "auto",
11981 computed: "asSpecified",
11982 order: "uniqueOrder",
11983 status: "experimental"
11984 },
11985 "font-family": {
11986 syntax: "<family-name>",
11987 media: "all",
11988 initial: "n/a (required)",
11989 percentages: "no",
11990 computed: "asSpecified",
11991 order: "uniqueOrder",
11992 status: "standard"
11993 },
11994 "font-feature-settings": {
11995 syntax: "normal | <feature-tag-value>#",
11996 media: "all",
11997 initial: "normal",
11998 percentages: "no",
11999 computed: "asSpecified",
12000 order: "orderOfAppearance",
12001 status: "standard"
12002 },
12003 "font-variation-settings": {
12004 syntax: "normal | [ <string> <number> ]#",
12005 media: "all",
12006 initial: "normal",
12007 percentages: "no",
12008 computed: "asSpecified",
12009 order: "orderOfAppearance",
12010 status: "standard"
12011 },
12012 "font-stretch": {
12013 syntax: "<font-stretch-absolute>{1,2}",
12014 media: "all",
12015 initial: "normal",
12016 percentages: "no",
12017 computed: "asSpecified",
12018 order: "uniqueOrder",
12019 status: "standard"
12020 },
12021 "font-style": {
12022 syntax: "normal | italic | oblique <angle>{0,2}",
12023 media: "all",
12024 initial: "normal",
12025 percentages: "no",
12026 computed: "asSpecified",
12027 order: "uniqueOrder",
12028 status: "standard"
12029 },
12030 "font-weight": {
12031 syntax: "<font-weight-absolute>{1,2}",
12032 media: "all",
12033 initial: "normal",
12034 percentages: "no",
12035 computed: "asSpecified",
12036 order: "uniqueOrder",
12037 status: "standard"
12038 },
12039 "font-variant": {
12040 syntax: "normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> || stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero || <east-asian-variant-values> || <east-asian-width-values> || ruby ]",
12041 media: "all",
12042 initial: "normal",
12043 percentages: "no",
12044 computed: "asSpecified",
12045 order: "orderOfAppearance",
12046 status: "standard"
12047 },
12048 src: {
12049 syntax: "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#",
12050 media: "all",
12051 initial: "n/a (required)",
12052 percentages: "no",
12053 computed: "asSpecified",
12054 order: "orderOfAppearance",
12055 status: "standard"
12056 },
12057 "unicode-range": {
12058 syntax: "<unicode-range>#",
12059 media: "all",
12060 initial: "U+0-10FFFF",
12061 percentages: "no",
12062 computed: "asSpecified",
12063 order: "orderOfAppearance",
12064 status: "standard"
12065 }
12066 },
12067 status: "standard",
12068 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@font-face"
12069},
12070 "@font-feature-values": {
12071 syntax: "@font-feature-values <family-name># {\n <feature-value-block-list>\n}",
12072 interfaces: [
12073 "CSSFontFeatureValuesRule"
12074 ],
12075 groups: [
12076 "CSS Fonts"
12077 ],
12078 status: "standard",
12079 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@font-feature-values"
12080},
12081 "@import": {
12082 syntax: "@import [ <string> | <url> ] [ <media-query-list> ]?;",
12083 groups: [
12084 "Media Queries"
12085 ],
12086 status: "standard",
12087 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@import"
12088},
12089 "@keyframes": {
12090 syntax: "@keyframes <keyframes-name> {\n <keyframe-block-list>\n}",
12091 interfaces: [
12092 "CSSKeyframeRule",
12093 "CSSKeyframesRule"
12094 ],
12095 groups: [
12096 "CSS Animations"
12097 ],
12098 status: "standard",
12099 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@keyframes"
12100},
12101 "@media": {
12102 syntax: "@media <media-query-list> {\n <group-rule-body>\n}",
12103 interfaces: [
12104 "CSSGroupingRule",
12105 "CSSConditionRule",
12106 "CSSMediaRule",
12107 "CSSCustomMediaRule"
12108 ],
12109 groups: [
12110 "CSS Conditional Rules",
12111 "Media Queries"
12112 ],
12113 status: "standard",
12114 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@media"
12115},
12116 "@namespace": {
12117 syntax: "@namespace <namespace-prefix>? [ <string> | <url> ];",
12118 groups: [
12119 "CSS Namespaces"
12120 ],
12121 status: "standard",
12122 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@namespace"
12123},
12124 "@page": {
12125 syntax: "@page <page-selector-list> {\n <page-body>\n}",
12126 interfaces: [
12127 "CSSPageRule"
12128 ],
12129 groups: [
12130 "CSS Pages"
12131 ],
12132 descriptors: {
12133 bleed: {
12134 syntax: "auto | <length>",
12135 media: [
12136 "visual",
12137 "paged"
12138 ],
12139 initial: "auto",
12140 percentages: "no",
12141 computed: "asSpecified",
12142 order: "uniqueOrder",
12143 status: "standard"
12144 },
12145 marks: {
12146 syntax: "none | [ crop || cross ]",
12147 media: [
12148 "visual",
12149 "paged"
12150 ],
12151 initial: "none",
12152 percentages: "no",
12153 computed: "asSpecified",
12154 order: "orderOfAppearance",
12155 status: "standard"
12156 },
12157 size: {
12158 syntax: "<length>{1,2} | auto | [ <page-size> || [ portrait | landscape ] ]",
12159 media: [
12160 "visual",
12161 "paged"
12162 ],
12163 initial: "auto",
12164 percentages: "no",
12165 computed: "asSpecifiedRelativeToAbsoluteLengths",
12166 order: "orderOfAppearance",
12167 status: "standard"
12168 }
12169 },
12170 status: "standard",
12171 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@page"
12172},
12173 "@property": {
12174 syntax: "@property <custom-property-name> {\n <declaration-list>\n}",
12175 interfaces: [
12176 "CSS",
12177 "CSSPropertyRule"
12178 ],
12179 groups: [
12180 "CSS Houdini"
12181 ],
12182 descriptors: {
12183 syntax: {
12184 syntax: "<string>",
12185 media: "all",
12186 percentages: "no",
12187 initial: "n/a (required)",
12188 computed: "asSpecified",
12189 order: "uniqueOrder",
12190 status: "experimental"
12191 },
12192 inherits: {
12193 syntax: "true | false",
12194 media: "all",
12195 percentages: "no",
12196 initial: "auto",
12197 computed: "asSpecified",
12198 order: "uniqueOrder",
12199 status: "experimental"
12200 },
12201 "initial-value": {
12202 syntax: "<string>",
12203 media: "all",
12204 initial: "n/a (required)",
12205 percentages: "no",
12206 computed: "asSpecified",
12207 order: "uniqueOrder",
12208 status: "experimental"
12209 }
12210 },
12211 status: "experimental",
12212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@property"
12213},
12214 "@supports": {
12215 syntax: "@supports <supports-condition> {\n <group-rule-body>\n}",
12216 interfaces: [
12217 "CSSGroupingRule",
12218 "CSSConditionRule",
12219 "CSSSupportsRule"
12220 ],
12221 groups: [
12222 "CSS Conditional Rules"
12223 ],
12224 status: "standard",
12225 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@supports"
12226},
12227 "@viewport": {
12228 syntax: "@viewport {\n <group-rule-body>\n}",
12229 interfaces: [
12230 "CSSViewportRule"
12231 ],
12232 groups: [
12233 "CSS Device Adaptation"
12234 ],
12235 descriptors: {
12236 height: {
12237 syntax: "<viewport-length>{1,2}",
12238 media: [
12239 "visual",
12240 "continuous"
12241 ],
12242 initial: [
12243 "min-height",
12244 "max-height"
12245 ],
12246 percentages: [
12247 "min-height",
12248 "max-height"
12249 ],
12250 computed: [
12251 "min-height",
12252 "max-height"
12253 ],
12254 order: "orderOfAppearance",
12255 status: "standard"
12256 },
12257 "max-height": {
12258 syntax: "<viewport-length>",
12259 media: [
12260 "visual",
12261 "continuous"
12262 ],
12263 initial: "auto",
12264 percentages: "referToHeightOfInitialViewport",
12265 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12266 order: "uniqueOrder",
12267 status: "standard"
12268 },
12269 "max-width": {
12270 syntax: "<viewport-length>",
12271 media: [
12272 "visual",
12273 "continuous"
12274 ],
12275 initial: "auto",
12276 percentages: "referToWidthOfInitialViewport",
12277 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12278 order: "uniqueOrder",
12279 status: "standard"
12280 },
12281 "max-zoom": {
12282 syntax: "auto | <number> | <percentage>",
12283 media: [
12284 "visual",
12285 "continuous"
12286 ],
12287 initial: "auto",
12288 percentages: "the zoom factor itself",
12289 computed: "autoNonNegativeOrPercentage",
12290 order: "uniqueOrder",
12291 status: "standard"
12292 },
12293 "min-height": {
12294 syntax: "<viewport-length>",
12295 media: [
12296 "visual",
12297 "continuous"
12298 ],
12299 initial: "auto",
12300 percentages: "referToHeightOfInitialViewport",
12301 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12302 order: "uniqueOrder",
12303 status: "standard"
12304 },
12305 "min-width": {
12306 syntax: "<viewport-length>",
12307 media: [
12308 "visual",
12309 "continuous"
12310 ],
12311 initial: "auto",
12312 percentages: "referToWidthOfInitialViewport",
12313 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12314 order: "uniqueOrder",
12315 status: "standard"
12316 },
12317 "min-zoom": {
12318 syntax: "auto | <number> | <percentage>",
12319 media: [
12320 "visual",
12321 "continuous"
12322 ],
12323 initial: "auto",
12324 percentages: "the zoom factor itself",
12325 computed: "autoNonNegativeOrPercentage",
12326 order: "uniqueOrder",
12327 status: "standard"
12328 },
12329 orientation: {
12330 syntax: "auto | portrait | landscape",
12331 media: [
12332 "visual",
12333 "continuous"
12334 ],
12335 initial: "auto",
12336 percentages: "referToSizeOfBoundingBox",
12337 computed: "asSpecified",
12338 order: "uniqueOrder",
12339 status: "standard"
12340 },
12341 "user-zoom": {
12342 syntax: "zoom | fixed",
12343 media: [
12344 "visual",
12345 "continuous"
12346 ],
12347 initial: "zoom",
12348 percentages: "referToSizeOfBoundingBox",
12349 computed: "asSpecified",
12350 order: "uniqueOrder",
12351 status: "standard"
12352 },
12353 "viewport-fit": {
12354 syntax: "auto | contain | cover",
12355 media: [
12356 "visual",
12357 "continuous"
12358 ],
12359 initial: "auto",
12360 percentages: "no",
12361 computed: "asSpecified",
12362 order: "uniqueOrder",
12363 status: "standard"
12364 },
12365 width: {
12366 syntax: "<viewport-length>{1,2}",
12367 media: [
12368 "visual",
12369 "continuous"
12370 ],
12371 initial: [
12372 "min-width",
12373 "max-width"
12374 ],
12375 percentages: [
12376 "min-width",
12377 "max-width"
12378 ],
12379 computed: [
12380 "min-width",
12381 "max-width"
12382 ],
12383 order: "orderOfAppearance",
12384 status: "standard"
12385 },
12386 zoom: {
12387 syntax: "auto | <number> | <percentage>",
12388 media: [
12389 "visual",
12390 "continuous"
12391 ],
12392 initial: "auto",
12393 percentages: "the zoom factor itself",
12394 computed: "autoNonNegativeOrPercentage",
12395 order: "uniqueOrder",
12396 status: "standard"
12397 }
12398 },
12399 status: "standard",
12400 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/@viewport"
12401}
12402};
12403
12404var all = {
12405 syntax: "initial | inherit | unset | revert",
12406 media: "noPracticalMedia",
12407 inherited: false,
12408 animationType: "eachOfShorthandPropertiesExceptUnicodeBiDiAndDirection",
12409 percentages: "no",
12410 groups: [
12411 "CSS Miscellaneous"
12412 ],
12413 initial: "noPracticalInitialValue",
12414 appliesto: "allElements",
12415 computed: "asSpecifiedAppliesToEachProperty",
12416 order: "uniqueOrder",
12417 status: "standard",
12418 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/all"
12419};
12420var animation = {
12421 syntax: "<single-animation>#",
12422 media: "visual",
12423 inherited: false,
12424 animationType: "discrete",
12425 percentages: "no",
12426 groups: [
12427 "CSS Animations"
12428 ],
12429 initial: [
12430 "animation-name",
12431 "animation-duration",
12432 "animation-timing-function",
12433 "animation-delay",
12434 "animation-iteration-count",
12435 "animation-direction",
12436 "animation-fill-mode",
12437 "animation-play-state"
12438 ],
12439 appliesto: "allElementsAndPseudos",
12440 computed: [
12441 "animation-name",
12442 "animation-duration",
12443 "animation-timing-function",
12444 "animation-delay",
12445 "animation-direction",
12446 "animation-iteration-count",
12447 "animation-fill-mode",
12448 "animation-play-state"
12449 ],
12450 order: "orderOfAppearance",
12451 status: "standard",
12452 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation"
12453};
12454var appearance = {
12455 syntax: "none | auto | textfield | menulist-button | <compat-auto>",
12456 media: "all",
12457 inherited: false,
12458 animationType: "discrete",
12459 percentages: "no",
12460 groups: [
12461 "CSS Basic User Interface"
12462 ],
12463 initial: "auto",
12464 appliesto: "allElements",
12465 computed: "asSpecified",
12466 order: "perGrammar",
12467 status: "experimental",
12468 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/appearance"
12469};
12470var azimuth = {
12471 syntax: "<angle> | [ [ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards",
12472 media: "aural",
12473 inherited: true,
12474 animationType: "discrete",
12475 percentages: "no",
12476 groups: [
12477 "CSS Speech"
12478 ],
12479 initial: "center",
12480 appliesto: "allElements",
12481 computed: "normalizedAngle",
12482 order: "orderOfAppearance",
12483 status: "obsolete",
12484 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/azimuth"
12485};
12486var background = {
12487 syntax: "[ <bg-layer> , ]* <final-bg-layer>",
12488 media: "visual",
12489 inherited: false,
12490 animationType: [
12491 "background-color",
12492 "background-image",
12493 "background-clip",
12494 "background-position",
12495 "background-size",
12496 "background-repeat",
12497 "background-attachment"
12498 ],
12499 percentages: [
12500 "background-position",
12501 "background-size"
12502 ],
12503 groups: [
12504 "CSS Backgrounds and Borders"
12505 ],
12506 initial: [
12507 "background-image",
12508 "background-position",
12509 "background-size",
12510 "background-repeat",
12511 "background-origin",
12512 "background-clip",
12513 "background-attachment",
12514 "background-color"
12515 ],
12516 appliesto: "allElements",
12517 computed: [
12518 "background-image",
12519 "background-position",
12520 "background-size",
12521 "background-repeat",
12522 "background-origin",
12523 "background-clip",
12524 "background-attachment",
12525 "background-color"
12526 ],
12527 order: "orderOfAppearance",
12528 alsoAppliesTo: [
12529 "::first-letter",
12530 "::first-line",
12531 "::placeholder"
12532 ],
12533 status: "standard",
12534 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background"
12535};
12536var border = {
12537 syntax: "<line-width> || <line-style> || <color>",
12538 media: "visual",
12539 inherited: false,
12540 animationType: [
12541 "border-color",
12542 "border-style",
12543 "border-width"
12544 ],
12545 percentages: "no",
12546 groups: [
12547 "CSS Backgrounds and Borders"
12548 ],
12549 initial: [
12550 "border-width",
12551 "border-style",
12552 "border-color"
12553 ],
12554 appliesto: "allElements",
12555 computed: [
12556 "border-width",
12557 "border-style",
12558 "border-color"
12559 ],
12560 order: "orderOfAppearance",
12561 alsoAppliesTo: [
12562 "::first-letter"
12563 ],
12564 status: "standard",
12565 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border"
12566};
12567var bottom = {
12568 syntax: "<length> | <percentage> | auto",
12569 media: "visual",
12570 inherited: false,
12571 animationType: "lpc",
12572 percentages: "referToContainingBlockHeight",
12573 groups: [
12574 "CSS Positioning"
12575 ],
12576 initial: "auto",
12577 appliesto: "positionedElements",
12578 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12579 order: "uniqueOrder",
12580 status: "standard",
12581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/bottom"
12582};
12583var clear = {
12584 syntax: "none | left | right | both | inline-start | inline-end",
12585 media: "visual",
12586 inherited: false,
12587 animationType: "discrete",
12588 percentages: "no",
12589 groups: [
12590 "CSS Positioning"
12591 ],
12592 initial: "none",
12593 appliesto: "blockLevelElements",
12594 computed: "asSpecified",
12595 order: "uniqueOrder",
12596 status: "standard",
12597 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clear"
12598};
12599var clip = {
12600 syntax: "<shape> | auto",
12601 media: "visual",
12602 inherited: false,
12603 animationType: "rectangle",
12604 percentages: "no",
12605 groups: [
12606 "CSS Masking"
12607 ],
12608 initial: "auto",
12609 appliesto: "absolutelyPositionedElements",
12610 computed: "autoOrRectangle",
12611 order: "uniqueOrder",
12612 status: "standard",
12613 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clip"
12614};
12615var color$1 = {
12616 syntax: "<color>",
12617 media: "visual",
12618 inherited: true,
12619 animationType: "color",
12620 percentages: "no",
12621 groups: [
12622 "CSS Color"
12623 ],
12624 initial: "variesFromBrowserToBrowser",
12625 appliesto: "allElements",
12626 computed: "translucentValuesRGBAOtherwiseRGB",
12627 order: "uniqueOrder",
12628 alsoAppliesTo: [
12629 "::first-letter",
12630 "::first-line",
12631 "::placeholder"
12632 ],
12633 status: "standard",
12634 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/color"
12635};
12636var columns = {
12637 syntax: "<'column-width'> || <'column-count'>",
12638 media: "visual",
12639 inherited: false,
12640 animationType: [
12641 "column-width",
12642 "column-count"
12643 ],
12644 percentages: "no",
12645 groups: [
12646 "CSS Columns"
12647 ],
12648 initial: [
12649 "column-width",
12650 "column-count"
12651 ],
12652 appliesto: "blockContainersExceptTableWrappers",
12653 computed: [
12654 "column-width",
12655 "column-count"
12656 ],
12657 order: "perGrammar",
12658 status: "standard",
12659 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/columns"
12660};
12661var contain = {
12662 syntax: "none | strict | content | [ size || layout || style || paint ]",
12663 media: "all",
12664 inherited: false,
12665 animationType: "discrete",
12666 percentages: "no",
12667 groups: [
12668 "CSS Containment"
12669 ],
12670 initial: "none",
12671 appliesto: "allElements",
12672 computed: "asSpecified",
12673 order: "perGrammar",
12674 status: "standard",
12675 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/contain"
12676};
12677var content = {
12678 syntax: "normal | none | [ <content-replacement> | <content-list> ] [/ <string> ]?",
12679 media: "all",
12680 inherited: false,
12681 animationType: "discrete",
12682 percentages: "no",
12683 groups: [
12684 "CSS Generated Content"
12685 ],
12686 initial: "normal",
12687 appliesto: "beforeAndAfterPseudos",
12688 computed: "normalOnElementsForPseudosNoneAbsoluteURIStringOrAsSpecified",
12689 order: "uniqueOrder",
12690 status: "standard",
12691 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/content"
12692};
12693var cursor = {
12694 syntax: "[ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing ] ]",
12695 media: [
12696 "visual",
12697 "interactive"
12698 ],
12699 inherited: true,
12700 animationType: "discrete",
12701 percentages: "no",
12702 groups: [
12703 "CSS Basic User Interface"
12704 ],
12705 initial: "auto",
12706 appliesto: "allElements",
12707 computed: "asSpecifiedURLsAbsolute",
12708 order: "uniqueOrder",
12709 status: "standard",
12710 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/cursor"
12711};
12712var direction = {
12713 syntax: "ltr | rtl",
12714 media: "visual",
12715 inherited: true,
12716 animationType: "discrete",
12717 percentages: "no",
12718 groups: [
12719 "CSS Writing Modes"
12720 ],
12721 initial: "ltr",
12722 appliesto: "allElements",
12723 computed: "asSpecified",
12724 order: "uniqueOrder",
12725 status: "standard",
12726 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/direction"
12727};
12728var display = {
12729 syntax: "[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>",
12730 media: "all",
12731 inherited: false,
12732 animationType: "discrete",
12733 percentages: "no",
12734 groups: [
12735 "CSS Display"
12736 ],
12737 initial: "inline",
12738 appliesto: "allElements",
12739 computed: "asSpecifiedExceptPositionedFloatingAndRootElementsKeywordMaybeDifferent",
12740 order: "uniqueOrder",
12741 status: "standard",
12742 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/display"
12743};
12744var filter = {
12745 syntax: "none | <filter-function-list>",
12746 media: "visual",
12747 inherited: false,
12748 animationType: "filterList",
12749 percentages: "no",
12750 groups: [
12751 "Filter Effects"
12752 ],
12753 initial: "none",
12754 appliesto: "allElementsSVGContainerElements",
12755 computed: "asSpecified",
12756 order: "uniqueOrder",
12757 status: "standard",
12758 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/filter"
12759};
12760var flex = {
12761 syntax: "none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]",
12762 media: "visual",
12763 inherited: false,
12764 animationType: [
12765 "flex-grow",
12766 "flex-shrink",
12767 "flex-basis"
12768 ],
12769 percentages: "no",
12770 groups: [
12771 "CSS Flexible Box Layout"
12772 ],
12773 initial: [
12774 "flex-grow",
12775 "flex-shrink",
12776 "flex-basis"
12777 ],
12778 appliesto: "flexItemsAndInFlowPseudos",
12779 computed: [
12780 "flex-grow",
12781 "flex-shrink",
12782 "flex-basis"
12783 ],
12784 order: "orderOfAppearance",
12785 status: "standard",
12786 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex"
12787};
12788var float = {
12789 syntax: "left | right | none | inline-start | inline-end",
12790 media: "visual",
12791 inherited: false,
12792 animationType: "discrete",
12793 percentages: "no",
12794 groups: [
12795 "CSS Positioning"
12796 ],
12797 initial: "none",
12798 appliesto: "allElementsNoEffectIfDisplayNone",
12799 computed: "asSpecified",
12800 order: "uniqueOrder",
12801 status: "standard",
12802 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/float"
12803};
12804var font = {
12805 syntax: "[ [ <'font-style'> || <font-variant-css21> || <'font-weight'> || <'font-stretch'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar",
12806 media: "visual",
12807 inherited: true,
12808 animationType: [
12809 "font-style",
12810 "font-variant",
12811 "font-weight",
12812 "font-stretch",
12813 "font-size",
12814 "line-height",
12815 "font-family"
12816 ],
12817 percentages: [
12818 "font-size",
12819 "line-height"
12820 ],
12821 groups: [
12822 "CSS Fonts"
12823 ],
12824 initial: [
12825 "font-style",
12826 "font-variant",
12827 "font-weight",
12828 "font-stretch",
12829 "font-size",
12830 "line-height",
12831 "font-family"
12832 ],
12833 appliesto: "allElements",
12834 computed: [
12835 "font-style",
12836 "font-variant",
12837 "font-weight",
12838 "font-stretch",
12839 "font-size",
12840 "line-height",
12841 "font-family"
12842 ],
12843 order: "orderOfAppearance",
12844 alsoAppliesTo: [
12845 "::first-letter",
12846 "::first-line",
12847 "::placeholder"
12848 ],
12849 status: "standard",
12850 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font"
12851};
12852var gap = {
12853 syntax: "<'row-gap'> <'column-gap'>?",
12854 media: "visual",
12855 inherited: false,
12856 animationType: [
12857 "row-gap",
12858 "column-gap"
12859 ],
12860 percentages: "no",
12861 groups: [
12862 "CSS Box Alignment"
12863 ],
12864 initial: [
12865 "row-gap",
12866 "column-gap"
12867 ],
12868 appliesto: "multiColumnElementsFlexContainersGridContainers",
12869 computed: [
12870 "row-gap",
12871 "column-gap"
12872 ],
12873 order: "uniqueOrder",
12874 status: "standard",
12875 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/gap"
12876};
12877var grid = {
12878 syntax: "<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>",
12879 media: "visual",
12880 inherited: false,
12881 animationType: "discrete",
12882 percentages: [
12883 "grid-template-rows",
12884 "grid-template-columns",
12885 "grid-auto-rows",
12886 "grid-auto-columns"
12887 ],
12888 groups: [
12889 "CSS Grid Layout"
12890 ],
12891 initial: [
12892 "grid-template-rows",
12893 "grid-template-columns",
12894 "grid-template-areas",
12895 "grid-auto-rows",
12896 "grid-auto-columns",
12897 "grid-auto-flow",
12898 "grid-column-gap",
12899 "grid-row-gap",
12900 "column-gap",
12901 "row-gap"
12902 ],
12903 appliesto: "gridContainers",
12904 computed: [
12905 "grid-template-rows",
12906 "grid-template-columns",
12907 "grid-template-areas",
12908 "grid-auto-rows",
12909 "grid-auto-columns",
12910 "grid-auto-flow",
12911 "grid-column-gap",
12912 "grid-row-gap",
12913 "column-gap",
12914 "row-gap"
12915 ],
12916 order: "uniqueOrder",
12917 status: "standard",
12918 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid"
12919};
12920var height = {
12921 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
12922 media: "visual",
12923 inherited: false,
12924 animationType: "lpc",
12925 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentagesRelativeToContainingBlock",
12926 groups: [
12927 "CSS Box Model"
12928 ],
12929 initial: "auto",
12930 appliesto: "allElementsButNonReplacedAndTableColumns",
12931 computed: "percentageAutoOrAbsoluteLength",
12932 order: "uniqueOrder",
12933 status: "standard",
12934 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/height"
12935};
12936var hyphens = {
12937 syntax: "none | manual | auto",
12938 media: "visual",
12939 inherited: true,
12940 animationType: "discrete",
12941 percentages: "no",
12942 groups: [
12943 "CSS Text"
12944 ],
12945 initial: "manual",
12946 appliesto: "allElements",
12947 computed: "asSpecified",
12948 order: "uniqueOrder",
12949 status: "standard",
12950 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/hyphens"
12951};
12952var inset = {
12953 syntax: "<'top'>{1,4}",
12954 media: "visual",
12955 inherited: false,
12956 animationType: "lpc",
12957 percentages: "logicalHeightOfContainingBlock",
12958 groups: [
12959 "CSS Logical Properties"
12960 ],
12961 initial: "auto",
12962 appliesto: "positionedElements",
12963 computed: "sameAsBoxOffsets",
12964 order: "uniqueOrder",
12965 status: "standard",
12966 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset"
12967};
12968var isolation = {
12969 syntax: "auto | isolate",
12970 media: "visual",
12971 inherited: false,
12972 animationType: "discrete",
12973 percentages: "no",
12974 groups: [
12975 "Compositing and Blending"
12976 ],
12977 initial: "auto",
12978 appliesto: "allElementsSVGContainerGraphicsAndGraphicsReferencingElements",
12979 computed: "asSpecified",
12980 order: "uniqueOrder",
12981 status: "standard",
12982 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/isolation"
12983};
12984var left = {
12985 syntax: "<length> | <percentage> | auto",
12986 media: "visual",
12987 inherited: false,
12988 animationType: "lpc",
12989 percentages: "referToWidthOfContainingBlock",
12990 groups: [
12991 "CSS Positioning"
12992 ],
12993 initial: "auto",
12994 appliesto: "positionedElements",
12995 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
12996 order: "uniqueOrder",
12997 status: "standard",
12998 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/left"
12999};
13000var margin = {
13001 syntax: "[ <length> | <percentage> | auto ]{1,4}",
13002 media: "visual",
13003 inherited: false,
13004 animationType: "length",
13005 percentages: "referToWidthOfContainingBlock",
13006 groups: [
13007 "CSS Box Model"
13008 ],
13009 initial: [
13010 "margin-bottom",
13011 "margin-left",
13012 "margin-right",
13013 "margin-top"
13014 ],
13015 appliesto: "allElementsExceptTableDisplayTypes",
13016 computed: [
13017 "margin-bottom",
13018 "margin-left",
13019 "margin-right",
13020 "margin-top"
13021 ],
13022 order: "uniqueOrder",
13023 alsoAppliesTo: [
13024 "::first-letter",
13025 "::first-line"
13026 ],
13027 status: "standard",
13028 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin"
13029};
13030var mask = {
13031 syntax: "<mask-layer>#",
13032 media: "visual",
13033 inherited: false,
13034 animationType: [
13035 "mask-image",
13036 "mask-mode",
13037 "mask-repeat",
13038 "mask-position",
13039 "mask-clip",
13040 "mask-origin",
13041 "mask-size",
13042 "mask-composite"
13043 ],
13044 percentages: [
13045 "mask-position"
13046 ],
13047 groups: [
13048 "CSS Masking"
13049 ],
13050 initial: [
13051 "mask-image",
13052 "mask-mode",
13053 "mask-repeat",
13054 "mask-position",
13055 "mask-clip",
13056 "mask-origin",
13057 "mask-size",
13058 "mask-composite"
13059 ],
13060 appliesto: "allElementsSVGContainerElements",
13061 computed: [
13062 "mask-image",
13063 "mask-mode",
13064 "mask-repeat",
13065 "mask-position",
13066 "mask-clip",
13067 "mask-origin",
13068 "mask-size",
13069 "mask-composite"
13070 ],
13071 order: "perGrammar",
13072 stacking: true,
13073 status: "standard",
13074 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask"
13075};
13076var offset = {
13077 syntax: "[ <'offset-position'>? [ <'offset-path'> [ <'offset-distance'> || <'offset-rotate'> ]? ]? ]! [ / <'offset-anchor'> ]?",
13078 media: "visual",
13079 inherited: false,
13080 animationType: [
13081 "offset-position",
13082 "offset-path",
13083 "offset-distance",
13084 "offset-anchor",
13085 "offset-rotate"
13086 ],
13087 percentages: [
13088 "offset-position",
13089 "offset-distance",
13090 "offset-anchor"
13091 ],
13092 groups: [
13093 "CSS Motion Path"
13094 ],
13095 initial: [
13096 "offset-position",
13097 "offset-path",
13098 "offset-distance",
13099 "offset-anchor",
13100 "offset-rotate"
13101 ],
13102 appliesto: "transformableElements",
13103 computed: [
13104 "offset-position",
13105 "offset-path",
13106 "offset-distance",
13107 "offset-anchor",
13108 "offset-rotate"
13109 ],
13110 order: "perGrammar",
13111 stacking: true,
13112 status: "standard",
13113 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset"
13114};
13115var opacity = {
13116 syntax: "<alpha-value>",
13117 media: "visual",
13118 inherited: false,
13119 animationType: "number",
13120 percentages: "no",
13121 groups: [
13122 "CSS Color"
13123 ],
13124 initial: "1.0",
13125 appliesto: "allElements",
13126 computed: "specifiedValueClipped0To1",
13127 order: "uniqueOrder",
13128 alsoAppliesTo: [
13129 "::placeholder"
13130 ],
13131 status: "standard",
13132 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/opacity"
13133};
13134var order = {
13135 syntax: "<integer>",
13136 media: "visual",
13137 inherited: false,
13138 animationType: "integer",
13139 percentages: "no",
13140 groups: [
13141 "CSS Flexible Box Layout"
13142 ],
13143 initial: "0",
13144 appliesto: "flexItemsGridItemsAbsolutelyPositionedContainerChildren",
13145 computed: "asSpecified",
13146 order: "uniqueOrder",
13147 status: "standard",
13148 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/order"
13149};
13150var orphans = {
13151 syntax: "<integer>",
13152 media: "visual",
13153 inherited: true,
13154 animationType: "discrete",
13155 percentages: "no",
13156 groups: [
13157 "CSS Fragmentation"
13158 ],
13159 initial: "2",
13160 appliesto: "blockContainerElements",
13161 computed: "asSpecified",
13162 order: "perGrammar",
13163 status: "standard",
13164 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/orphans"
13165};
13166var outline = {
13167 syntax: "[ <'outline-color'> || <'outline-style'> || <'outline-width'> ]",
13168 media: [
13169 "visual",
13170 "interactive"
13171 ],
13172 inherited: false,
13173 animationType: [
13174 "outline-color",
13175 "outline-width",
13176 "outline-style"
13177 ],
13178 percentages: "no",
13179 groups: [
13180 "CSS Basic User Interface"
13181 ],
13182 initial: [
13183 "outline-color",
13184 "outline-style",
13185 "outline-width"
13186 ],
13187 appliesto: "allElements",
13188 computed: [
13189 "outline-color",
13190 "outline-width",
13191 "outline-style"
13192 ],
13193 order: "orderOfAppearance",
13194 status: "standard",
13195 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline"
13196};
13197var overflow = {
13198 syntax: "[ visible | hidden | clip | scroll | auto ]{1,2}",
13199 media: "visual",
13200 inherited: false,
13201 animationType: "discrete",
13202 percentages: "no",
13203 groups: [
13204 "CSS Overflow"
13205 ],
13206 initial: "visible",
13207 appliesto: "blockContainersFlexContainersGridContainers",
13208 computed: [
13209 "overflow-x",
13210 "overflow-y"
13211 ],
13212 order: "uniqueOrder",
13213 status: "standard",
13214 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow"
13215};
13216var padding = {
13217 syntax: "[ <length> | <percentage> ]{1,4}",
13218 media: "visual",
13219 inherited: false,
13220 animationType: "length",
13221 percentages: "referToWidthOfContainingBlock",
13222 groups: [
13223 "CSS Box Model"
13224 ],
13225 initial: [
13226 "padding-bottom",
13227 "padding-left",
13228 "padding-right",
13229 "padding-top"
13230 ],
13231 appliesto: "allElementsExceptInternalTableDisplayTypes",
13232 computed: [
13233 "padding-bottom",
13234 "padding-left",
13235 "padding-right",
13236 "padding-top"
13237 ],
13238 order: "uniqueOrder",
13239 alsoAppliesTo: [
13240 "::first-letter",
13241 "::first-line"
13242 ],
13243 status: "standard",
13244 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding"
13245};
13246var perspective = {
13247 syntax: "none | <length>",
13248 media: "visual",
13249 inherited: false,
13250 animationType: "length",
13251 percentages: "no",
13252 groups: [
13253 "CSS Transforms"
13254 ],
13255 initial: "none",
13256 appliesto: "transformableElements",
13257 computed: "absoluteLengthOrNone",
13258 order: "uniqueOrder",
13259 stacking: true,
13260 status: "standard",
13261 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/perspective"
13262};
13263var position$1 = {
13264 syntax: "static | relative | absolute | sticky | fixed",
13265 media: "visual",
13266 inherited: false,
13267 animationType: "discrete",
13268 percentages: "no",
13269 groups: [
13270 "CSS Positioning"
13271 ],
13272 initial: "static",
13273 appliesto: "allElements",
13274 computed: "asSpecified",
13275 order: "uniqueOrder",
13276 stacking: true,
13277 status: "standard",
13278 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/position"
13279};
13280var quotes = {
13281 syntax: "none | auto | [ <string> <string> ]+",
13282 media: "visual",
13283 inherited: true,
13284 animationType: "discrete",
13285 percentages: "no",
13286 groups: [
13287 "CSS Generated Content"
13288 ],
13289 initial: "dependsOnUserAgent",
13290 appliesto: "allElements",
13291 computed: "asSpecified",
13292 order: "uniqueOrder",
13293 status: "standard",
13294 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/quotes"
13295};
13296var resize = {
13297 syntax: "none | both | horizontal | vertical | block | inline",
13298 media: "visual",
13299 inherited: false,
13300 animationType: "discrete",
13301 percentages: "no",
13302 groups: [
13303 "CSS Basic User Interface"
13304 ],
13305 initial: "none",
13306 appliesto: "elementsWithOverflowNotVisibleAndReplacedElements",
13307 computed: "asSpecified",
13308 order: "uniqueOrder",
13309 status: "standard",
13310 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/resize"
13311};
13312var right = {
13313 syntax: "<length> | <percentage> | auto",
13314 media: "visual",
13315 inherited: false,
13316 animationType: "lpc",
13317 percentages: "referToWidthOfContainingBlock",
13318 groups: [
13319 "CSS Positioning"
13320 ],
13321 initial: "auto",
13322 appliesto: "positionedElements",
13323 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
13324 order: "uniqueOrder",
13325 status: "standard",
13326 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/right"
13327};
13328var rotate = {
13329 syntax: "none | <angle> | [ x | y | z | <number>{3} ] && <angle>",
13330 media: "visual",
13331 inherited: false,
13332 animationType: "transform",
13333 percentages: "no",
13334 groups: [
13335 "CSS Transforms"
13336 ],
13337 initial: "none",
13338 appliesto: "transformableElements",
13339 computed: "asSpecified",
13340 order: "perGrammar",
13341 stacking: true,
13342 status: "standard",
13343 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/rotate"
13344};
13345var scale = {
13346 syntax: "none | <number>{1,3}",
13347 media: "visual",
13348 inherited: false,
13349 animationType: "transform",
13350 percentages: "no",
13351 groups: [
13352 "CSS Transforms"
13353 ],
13354 initial: "none",
13355 appliesto: "transformableElements",
13356 computed: "asSpecified",
13357 order: "perGrammar",
13358 stacking: true,
13359 status: "standard",
13360 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scale"
13361};
13362var top = {
13363 syntax: "<length> | <percentage> | auto",
13364 media: "visual",
13365 inherited: false,
13366 animationType: "lpc",
13367 percentages: "referToContainingBlockHeight",
13368 groups: [
13369 "CSS Positioning"
13370 ],
13371 initial: "auto",
13372 appliesto: "positionedElements",
13373 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
13374 order: "uniqueOrder",
13375 status: "standard",
13376 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/top"
13377};
13378var transform = {
13379 syntax: "none | <transform-list>",
13380 media: "visual",
13381 inherited: false,
13382 animationType: "transform",
13383 percentages: "referToSizeOfBoundingBox",
13384 groups: [
13385 "CSS Transforms"
13386 ],
13387 initial: "none",
13388 appliesto: "transformableElements",
13389 computed: "asSpecifiedRelativeToAbsoluteLengths",
13390 order: "uniqueOrder",
13391 stacking: true,
13392 status: "standard",
13393 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform"
13394};
13395var transition = {
13396 syntax: "<single-transition>#",
13397 media: "interactive",
13398 inherited: false,
13399 animationType: "discrete",
13400 percentages: "no",
13401 groups: [
13402 "CSS Transitions"
13403 ],
13404 initial: [
13405 "transition-delay",
13406 "transition-duration",
13407 "transition-property",
13408 "transition-timing-function"
13409 ],
13410 appliesto: "allElementsAndPseudos",
13411 computed: [
13412 "transition-delay",
13413 "transition-duration",
13414 "transition-property",
13415 "transition-timing-function"
13416 ],
13417 order: "orderOfAppearance",
13418 status: "standard",
13419 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition"
13420};
13421var translate = {
13422 syntax: "none | <length-percentage> [ <length-percentage> <length>? ]?",
13423 media: "visual",
13424 inherited: false,
13425 animationType: "transform",
13426 percentages: "referToSizeOfBoundingBox",
13427 groups: [
13428 "CSS Transforms"
13429 ],
13430 initial: "none",
13431 appliesto: "transformableElements",
13432 computed: "asSpecifiedRelativeToAbsoluteLengths",
13433 order: "perGrammar",
13434 stacking: true,
13435 status: "standard",
13436 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/translate"
13437};
13438var visibility = {
13439 syntax: "visible | hidden | collapse",
13440 media: "visual",
13441 inherited: true,
13442 animationType: "visibility",
13443 percentages: "no",
13444 groups: [
13445 "CSS Box Model"
13446 ],
13447 initial: "visible",
13448 appliesto: "allElements",
13449 computed: "asSpecified",
13450 order: "uniqueOrder",
13451 status: "standard",
13452 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/visibility"
13453};
13454var widows = {
13455 syntax: "<integer>",
13456 media: "visual",
13457 inherited: true,
13458 animationType: "discrete",
13459 percentages: "no",
13460 groups: [
13461 "CSS Fragmentation"
13462 ],
13463 initial: "2",
13464 appliesto: "blockContainerElements",
13465 computed: "asSpecified",
13466 order: "perGrammar",
13467 status: "standard",
13468 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/widows"
13469};
13470var width = {
13471 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
13472 media: "visual",
13473 inherited: false,
13474 animationType: "lpc",
13475 percentages: "referToWidthOfContainingBlock",
13476 groups: [
13477 "CSS Box Model"
13478 ],
13479 initial: "auto",
13480 appliesto: "allElementsButNonReplacedAndTableRows",
13481 computed: "percentageAutoOrAbsoluteLength",
13482 order: "lengthOrPercentageBeforeKeywordIfBothPresent",
13483 status: "standard",
13484 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/width"
13485};
13486var zoom = {
13487 syntax: "normal | reset | <number> | <percentage>",
13488 media: "visual",
13489 inherited: false,
13490 animationType: "integer",
13491 percentages: "no",
13492 groups: [
13493 "Microsoft Extensions"
13494 ],
13495 initial: "normal",
13496 appliesto: "allElements",
13497 computed: "asSpecified",
13498 order: "uniqueOrder",
13499 status: "nonstandard",
13500 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/zoom"
13501};
13502var require$$1 = {
13503 "--*": {
13504 syntax: "<declaration-value>",
13505 media: "all",
13506 inherited: true,
13507 animationType: "discrete",
13508 percentages: "no",
13509 groups: [
13510 "CSS Variables"
13511 ],
13512 initial: "seeProse",
13513 appliesto: "allElements",
13514 computed: "asSpecifiedWithVarsSubstituted",
13515 order: "perGrammar",
13516 status: "experimental",
13517 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/--*"
13518},
13519 "-ms-accelerator": {
13520 syntax: "false | true",
13521 media: "visual",
13522 inherited: false,
13523 animationType: "discrete",
13524 percentages: "no",
13525 groups: [
13526 "Microsoft Extensions"
13527 ],
13528 initial: "false",
13529 appliesto: "allElements",
13530 computed: "asSpecified",
13531 order: "uniqueOrder",
13532 status: "nonstandard",
13533 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-accelerator"
13534},
13535 "-ms-block-progression": {
13536 syntax: "tb | rl | bt | lr",
13537 media: "visual",
13538 inherited: false,
13539 animationType: "discrete",
13540 percentages: "no",
13541 groups: [
13542 "Microsoft Extensions"
13543 ],
13544 initial: "tb",
13545 appliesto: "allElements",
13546 computed: "asSpecified",
13547 order: "uniqueOrder",
13548 status: "nonstandard",
13549 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-block-progression"
13550},
13551 "-ms-content-zoom-chaining": {
13552 syntax: "none | chained",
13553 media: "interactive",
13554 inherited: false,
13555 animationType: "discrete",
13556 percentages: "no",
13557 groups: [
13558 "Microsoft Extensions"
13559 ],
13560 initial: "none",
13561 appliesto: "nonReplacedBlockAndInlineBlockElements",
13562 computed: "asSpecified",
13563 order: "uniqueOrder",
13564 status: "nonstandard",
13565 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-chaining"
13566},
13567 "-ms-content-zooming": {
13568 syntax: "none | zoom",
13569 media: "interactive",
13570 inherited: false,
13571 animationType: "discrete",
13572 percentages: "no",
13573 groups: [
13574 "Microsoft Extensions"
13575 ],
13576 initial: "zoomForTheTopLevelNoneForTheRest",
13577 appliesto: "nonReplacedBlockAndInlineBlockElements",
13578 computed: "asSpecified",
13579 order: "uniqueOrder",
13580 status: "nonstandard",
13581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zooming"
13582},
13583 "-ms-content-zoom-limit": {
13584 syntax: "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>",
13585 media: "interactive",
13586 inherited: false,
13587 animationType: "discrete",
13588 percentages: [
13589 "-ms-content-zoom-limit-max",
13590 "-ms-content-zoom-limit-min"
13591 ],
13592 groups: [
13593 "Microsoft Extensions"
13594 ],
13595 initial: [
13596 "-ms-content-zoom-limit-max",
13597 "-ms-content-zoom-limit-min"
13598 ],
13599 appliesto: "nonReplacedBlockAndInlineBlockElements",
13600 computed: [
13601 "-ms-content-zoom-limit-max",
13602 "-ms-content-zoom-limit-min"
13603 ],
13604 order: "uniqueOrder",
13605 status: "nonstandard",
13606 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit"
13607},
13608 "-ms-content-zoom-limit-max": {
13609 syntax: "<percentage>",
13610 media: "interactive",
13611 inherited: false,
13612 animationType: "discrete",
13613 percentages: "maxZoomFactor",
13614 groups: [
13615 "Microsoft Extensions"
13616 ],
13617 initial: "400%",
13618 appliesto: "nonReplacedBlockAndInlineBlockElements",
13619 computed: "asSpecified",
13620 order: "uniqueOrder",
13621 status: "nonstandard",
13622 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit-max"
13623},
13624 "-ms-content-zoom-limit-min": {
13625 syntax: "<percentage>",
13626 media: "interactive",
13627 inherited: false,
13628 animationType: "discrete",
13629 percentages: "minZoomFactor",
13630 groups: [
13631 "Microsoft Extensions"
13632 ],
13633 initial: "100%",
13634 appliesto: "nonReplacedBlockAndInlineBlockElements",
13635 computed: "asSpecified",
13636 order: "uniqueOrder",
13637 status: "nonstandard",
13638 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-limit-min"
13639},
13640 "-ms-content-zoom-snap": {
13641 syntax: "<'-ms-content-zoom-snap-type'> || <'-ms-content-zoom-snap-points'>",
13642 media: "interactive",
13643 inherited: false,
13644 animationType: "discrete",
13645 percentages: "no",
13646 groups: [
13647 "Microsoft Extensions"
13648 ],
13649 initial: [
13650 "-ms-content-zoom-snap-type",
13651 "-ms-content-zoom-snap-points"
13652 ],
13653 appliesto: "nonReplacedBlockAndInlineBlockElements",
13654 computed: [
13655 "-ms-content-zoom-snap-type",
13656 "-ms-content-zoom-snap-points"
13657 ],
13658 order: "uniqueOrder",
13659 status: "nonstandard",
13660 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap"
13661},
13662 "-ms-content-zoom-snap-points": {
13663 syntax: "snapInterval( <percentage>, <percentage> ) | snapList( <percentage># )",
13664 media: "interactive",
13665 inherited: false,
13666 animationType: "discrete",
13667 percentages: "no",
13668 groups: [
13669 "Microsoft Extensions"
13670 ],
13671 initial: "snapInterval(0%, 100%)",
13672 appliesto: "nonReplacedBlockAndInlineBlockElements",
13673 computed: "asSpecified",
13674 order: "uniqueOrder",
13675 status: "nonstandard",
13676 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap-points"
13677},
13678 "-ms-content-zoom-snap-type": {
13679 syntax: "none | proximity | mandatory",
13680 media: "interactive",
13681 inherited: false,
13682 animationType: "discrete",
13683 percentages: "no",
13684 groups: [
13685 "Microsoft Extensions"
13686 ],
13687 initial: "none",
13688 appliesto: "nonReplacedBlockAndInlineBlockElements",
13689 computed: "asSpecified",
13690 order: "uniqueOrder",
13691 status: "nonstandard",
13692 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-content-zoom-snap-type"
13693},
13694 "-ms-filter": {
13695 syntax: "<string>",
13696 media: "visual",
13697 inherited: false,
13698 animationType: "discrete",
13699 percentages: "no",
13700 groups: [
13701 "Microsoft Extensions"
13702 ],
13703 initial: "\"\"",
13704 appliesto: "allElements",
13705 computed: "asSpecified",
13706 order: "uniqueOrder",
13707 status: "nonstandard",
13708 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-filter"
13709},
13710 "-ms-flow-from": {
13711 syntax: "[ none | <custom-ident> ]#",
13712 media: "visual",
13713 inherited: false,
13714 animationType: "discrete",
13715 percentages: "no",
13716 groups: [
13717 "Microsoft Extensions"
13718 ],
13719 initial: "none",
13720 appliesto: "nonReplacedElements",
13721 computed: "asSpecified",
13722 order: "uniqueOrder",
13723 status: "nonstandard",
13724 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-flow-from"
13725},
13726 "-ms-flow-into": {
13727 syntax: "[ none | <custom-ident> ]#",
13728 media: "visual",
13729 inherited: false,
13730 animationType: "discrete",
13731 percentages: "no",
13732 groups: [
13733 "Microsoft Extensions"
13734 ],
13735 initial: "none",
13736 appliesto: "iframeElements",
13737 computed: "asSpecified",
13738 order: "uniqueOrder",
13739 status: "nonstandard",
13740 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-flow-into"
13741},
13742 "-ms-grid-columns": {
13743 syntax: "none | <track-list> | <auto-track-list>",
13744 media: "visual",
13745 inherited: false,
13746 animationType: "simpleListOfLpcDifferenceLpc",
13747 percentages: "referToDimensionOfContentArea",
13748 groups: [
13749 "CSS Grid Layout"
13750 ],
13751 initial: "none",
13752 appliesto: "gridContainers",
13753 computed: "asSpecifiedRelativeToAbsoluteLengths",
13754 order: "uniqueOrder",
13755 status: "nonstandard",
13756 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-grid-columns"
13757},
13758 "-ms-grid-rows": {
13759 syntax: "none | <track-list> | <auto-track-list>",
13760 media: "visual",
13761 inherited: false,
13762 animationType: "simpleListOfLpcDifferenceLpc",
13763 percentages: "referToDimensionOfContentArea",
13764 groups: [
13765 "CSS Grid Layout"
13766 ],
13767 initial: "none",
13768 appliesto: "gridContainers",
13769 computed: "asSpecifiedRelativeToAbsoluteLengths",
13770 order: "uniqueOrder",
13771 status: "nonstandard",
13772 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-grid-rows"
13773},
13774 "-ms-high-contrast-adjust": {
13775 syntax: "auto | none",
13776 media: "visual",
13777 inherited: true,
13778 animationType: "discrete",
13779 percentages: "no",
13780 groups: [
13781 "Microsoft Extensions"
13782 ],
13783 initial: "auto",
13784 appliesto: "allElements",
13785 computed: "asSpecified",
13786 order: "uniqueOrder",
13787 status: "nonstandard",
13788 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-high-contrast-adjust"
13789},
13790 "-ms-hyphenate-limit-chars": {
13791 syntax: "auto | <integer>{1,3}",
13792 media: "visual",
13793 inherited: true,
13794 animationType: "discrete",
13795 percentages: "no",
13796 groups: [
13797 "Microsoft Extensions"
13798 ],
13799 initial: "auto",
13800 appliesto: "allElements",
13801 computed: "asSpecified",
13802 order: "uniqueOrder",
13803 status: "nonstandard",
13804 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-chars"
13805},
13806 "-ms-hyphenate-limit-lines": {
13807 syntax: "no-limit | <integer>",
13808 media: "visual",
13809 inherited: true,
13810 animationType: "discrete",
13811 percentages: "no",
13812 groups: [
13813 "Microsoft Extensions"
13814 ],
13815 initial: "no-limit",
13816 appliesto: "blockContainerElements",
13817 computed: "asSpecified",
13818 order: "uniqueOrder",
13819 status: "nonstandard",
13820 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-lines"
13821},
13822 "-ms-hyphenate-limit-zone": {
13823 syntax: "<percentage> | <length>",
13824 media: "visual",
13825 inherited: true,
13826 animationType: "discrete",
13827 percentages: "referToLineBoxWidth",
13828 groups: [
13829 "Microsoft Extensions"
13830 ],
13831 initial: "0",
13832 appliesto: "blockContainerElements",
13833 computed: "asSpecified",
13834 order: "uniqueOrder",
13835 status: "nonstandard",
13836 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-hyphenate-limit-zone"
13837},
13838 "-ms-ime-align": {
13839 syntax: "auto | after",
13840 media: "visual",
13841 inherited: false,
13842 animationType: "discrete",
13843 percentages: "no",
13844 groups: [
13845 "Microsoft Extensions"
13846 ],
13847 initial: "auto",
13848 appliesto: "allElements",
13849 computed: "asSpecified",
13850 order: "uniqueOrder",
13851 status: "nonstandard",
13852 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-ime-align"
13853},
13854 "-ms-overflow-style": {
13855 syntax: "auto | none | scrollbar | -ms-autohiding-scrollbar",
13856 media: "interactive",
13857 inherited: true,
13858 animationType: "discrete",
13859 percentages: "no",
13860 groups: [
13861 "Microsoft Extensions"
13862 ],
13863 initial: "auto",
13864 appliesto: "nonReplacedBlockAndInlineBlockElements",
13865 computed: "asSpecified",
13866 order: "uniqueOrder",
13867 status: "nonstandard",
13868 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-overflow-style"
13869},
13870 "-ms-scrollbar-3dlight-color": {
13871 syntax: "<color>",
13872 media: "visual",
13873 inherited: true,
13874 animationType: "discrete",
13875 percentages: "no",
13876 groups: [
13877 "Microsoft Extensions"
13878 ],
13879 initial: "dependsOnUserAgent",
13880 appliesto: "allElements",
13881 computed: "asSpecified",
13882 order: "uniqueOrder",
13883 status: "nonstandard",
13884 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-3dlight-color"
13885},
13886 "-ms-scrollbar-arrow-color": {
13887 syntax: "<color>",
13888 media: "visual",
13889 inherited: true,
13890 animationType: "discrete",
13891 percentages: "no",
13892 groups: [
13893 "Microsoft Extensions"
13894 ],
13895 initial: "ButtonText",
13896 appliesto: "allElements",
13897 computed: "asSpecified",
13898 order: "uniqueOrder",
13899 status: "nonstandard",
13900 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-arrow-color"
13901},
13902 "-ms-scrollbar-base-color": {
13903 syntax: "<color>",
13904 media: "visual",
13905 inherited: true,
13906 animationType: "discrete",
13907 percentages: "no",
13908 groups: [
13909 "Microsoft Extensions"
13910 ],
13911 initial: "dependsOnUserAgent",
13912 appliesto: "allElements",
13913 computed: "asSpecified",
13914 order: "uniqueOrder",
13915 status: "nonstandard",
13916 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-base-color"
13917},
13918 "-ms-scrollbar-darkshadow-color": {
13919 syntax: "<color>",
13920 media: "visual",
13921 inherited: true,
13922 animationType: "discrete",
13923 percentages: "no",
13924 groups: [
13925 "Microsoft Extensions"
13926 ],
13927 initial: "ThreeDDarkShadow",
13928 appliesto: "allElements",
13929 computed: "asSpecified",
13930 order: "uniqueOrder",
13931 status: "nonstandard",
13932 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-darkshadow-color"
13933},
13934 "-ms-scrollbar-face-color": {
13935 syntax: "<color>",
13936 media: "visual",
13937 inherited: true,
13938 animationType: "discrete",
13939 percentages: "no",
13940 groups: [
13941 "Microsoft Extensions"
13942 ],
13943 initial: "ThreeDFace",
13944 appliesto: "allElements",
13945 computed: "asSpecified",
13946 order: "uniqueOrder",
13947 status: "nonstandard",
13948 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-face-color"
13949},
13950 "-ms-scrollbar-highlight-color": {
13951 syntax: "<color>",
13952 media: "visual",
13953 inherited: true,
13954 animationType: "discrete",
13955 percentages: "no",
13956 groups: [
13957 "Microsoft Extensions"
13958 ],
13959 initial: "ThreeDHighlight",
13960 appliesto: "allElements",
13961 computed: "asSpecified",
13962 order: "uniqueOrder",
13963 status: "nonstandard",
13964 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-highlight-color"
13965},
13966 "-ms-scrollbar-shadow-color": {
13967 syntax: "<color>",
13968 media: "visual",
13969 inherited: true,
13970 animationType: "discrete",
13971 percentages: "no",
13972 groups: [
13973 "Microsoft Extensions"
13974 ],
13975 initial: "ThreeDDarkShadow",
13976 appliesto: "allElements",
13977 computed: "asSpecified",
13978 order: "uniqueOrder",
13979 status: "nonstandard",
13980 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-shadow-color"
13981},
13982 "-ms-scrollbar-track-color": {
13983 syntax: "<color>",
13984 media: "visual",
13985 inherited: true,
13986 animationType: "discrete",
13987 percentages: "no",
13988 groups: [
13989 "Microsoft Extensions"
13990 ],
13991 initial: "Scrollbar",
13992 appliesto: "allElements",
13993 computed: "asSpecified",
13994 order: "uniqueOrder",
13995 status: "nonstandard",
13996 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scrollbar-track-color"
13997},
13998 "-ms-scroll-chaining": {
13999 syntax: "chained | none",
14000 media: "interactive",
14001 inherited: false,
14002 animationType: "discrete",
14003 percentages: "no",
14004 groups: [
14005 "Microsoft Extensions"
14006 ],
14007 initial: "chained",
14008 appliesto: "nonReplacedBlockAndInlineBlockElements",
14009 computed: "asSpecified",
14010 order: "uniqueOrder",
14011 status: "nonstandard",
14012 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-chaining"
14013},
14014 "-ms-scroll-limit": {
14015 syntax: "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>",
14016 media: "interactive",
14017 inherited: false,
14018 animationType: "discrete",
14019 percentages: "no",
14020 groups: [
14021 "Microsoft Extensions"
14022 ],
14023 initial: [
14024 "-ms-scroll-limit-x-min",
14025 "-ms-scroll-limit-y-min",
14026 "-ms-scroll-limit-x-max",
14027 "-ms-scroll-limit-y-max"
14028 ],
14029 appliesto: "nonReplacedBlockAndInlineBlockElements",
14030 computed: [
14031 "-ms-scroll-limit-x-min",
14032 "-ms-scroll-limit-y-min",
14033 "-ms-scroll-limit-x-max",
14034 "-ms-scroll-limit-y-max"
14035 ],
14036 order: "uniqueOrder",
14037 status: "nonstandard",
14038 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit"
14039},
14040 "-ms-scroll-limit-x-max": {
14041 syntax: "auto | <length>",
14042 media: "interactive",
14043 inherited: false,
14044 animationType: "discrete",
14045 percentages: "no",
14046 groups: [
14047 "Microsoft Extensions"
14048 ],
14049 initial: "auto",
14050 appliesto: "nonReplacedBlockAndInlineBlockElements",
14051 computed: "asSpecified",
14052 order: "uniqueOrder",
14053 status: "nonstandard",
14054 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-x-max"
14055},
14056 "-ms-scroll-limit-x-min": {
14057 syntax: "<length>",
14058 media: "interactive",
14059 inherited: false,
14060 animationType: "discrete",
14061 percentages: "no",
14062 groups: [
14063 "Microsoft Extensions"
14064 ],
14065 initial: "0",
14066 appliesto: "nonReplacedBlockAndInlineBlockElements",
14067 computed: "asSpecified",
14068 order: "uniqueOrder",
14069 status: "nonstandard",
14070 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-x-min"
14071},
14072 "-ms-scroll-limit-y-max": {
14073 syntax: "auto | <length>",
14074 media: "interactive",
14075 inherited: false,
14076 animationType: "discrete",
14077 percentages: "no",
14078 groups: [
14079 "Microsoft Extensions"
14080 ],
14081 initial: "auto",
14082 appliesto: "nonReplacedBlockAndInlineBlockElements",
14083 computed: "asSpecified",
14084 order: "uniqueOrder",
14085 status: "nonstandard",
14086 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-y-max"
14087},
14088 "-ms-scroll-limit-y-min": {
14089 syntax: "<length>",
14090 media: "interactive",
14091 inherited: false,
14092 animationType: "discrete",
14093 percentages: "no",
14094 groups: [
14095 "Microsoft Extensions"
14096 ],
14097 initial: "0",
14098 appliesto: "nonReplacedBlockAndInlineBlockElements",
14099 computed: "asSpecified",
14100 order: "uniqueOrder",
14101 status: "nonstandard",
14102 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-limit-y-min"
14103},
14104 "-ms-scroll-rails": {
14105 syntax: "none | railed",
14106 media: "interactive",
14107 inherited: false,
14108 animationType: "discrete",
14109 percentages: "no",
14110 groups: [
14111 "Microsoft Extensions"
14112 ],
14113 initial: "railed",
14114 appliesto: "nonReplacedBlockAndInlineBlockElements",
14115 computed: "asSpecified",
14116 order: "uniqueOrder",
14117 status: "nonstandard",
14118 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-rails"
14119},
14120 "-ms-scroll-snap-points-x": {
14121 syntax: "snapInterval( <length-percentage>, <length-percentage> ) | snapList( <length-percentage># )",
14122 media: "interactive",
14123 inherited: false,
14124 animationType: "discrete",
14125 percentages: "no",
14126 groups: [
14127 "Microsoft Extensions"
14128 ],
14129 initial: "snapInterval(0px, 100%)",
14130 appliesto: "nonReplacedBlockAndInlineBlockElements",
14131 computed: "asSpecified",
14132 order: "uniqueOrder",
14133 status: "nonstandard",
14134 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-points-x"
14135},
14136 "-ms-scroll-snap-points-y": {
14137 syntax: "snapInterval( <length-percentage>, <length-percentage> ) | snapList( <length-percentage># )",
14138 media: "interactive",
14139 inherited: false,
14140 animationType: "discrete",
14141 percentages: "no",
14142 groups: [
14143 "Microsoft Extensions"
14144 ],
14145 initial: "snapInterval(0px, 100%)",
14146 appliesto: "nonReplacedBlockAndInlineBlockElements",
14147 computed: "asSpecified",
14148 order: "uniqueOrder",
14149 status: "nonstandard",
14150 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-points-y"
14151},
14152 "-ms-scroll-snap-type": {
14153 syntax: "none | proximity | mandatory",
14154 media: "interactive",
14155 inherited: false,
14156 animationType: "discrete",
14157 percentages: "no",
14158 groups: [
14159 "Microsoft Extensions"
14160 ],
14161 initial: "none",
14162 appliesto: "nonReplacedBlockAndInlineBlockElements",
14163 computed: "asSpecified",
14164 order: "uniqueOrder",
14165 status: "nonstandard",
14166 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-type"
14167},
14168 "-ms-scroll-snap-x": {
14169 syntax: "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>",
14170 media: "interactive",
14171 inherited: false,
14172 animationType: "discrete",
14173 percentages: "no",
14174 groups: [
14175 "Microsoft Extensions"
14176 ],
14177 initial: [
14178 "-ms-scroll-snap-type",
14179 "-ms-scroll-snap-points-x"
14180 ],
14181 appliesto: "nonReplacedBlockAndInlineBlockElements",
14182 computed: [
14183 "-ms-scroll-snap-type",
14184 "-ms-scroll-snap-points-x"
14185 ],
14186 order: "uniqueOrder",
14187 status: "nonstandard",
14188 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-x"
14189},
14190 "-ms-scroll-snap-y": {
14191 syntax: "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>",
14192 media: "interactive",
14193 inherited: false,
14194 animationType: "discrete",
14195 percentages: "no",
14196 groups: [
14197 "Microsoft Extensions"
14198 ],
14199 initial: [
14200 "-ms-scroll-snap-type",
14201 "-ms-scroll-snap-points-y"
14202 ],
14203 appliesto: "nonReplacedBlockAndInlineBlockElements",
14204 computed: [
14205 "-ms-scroll-snap-type",
14206 "-ms-scroll-snap-points-y"
14207 ],
14208 order: "uniqueOrder",
14209 status: "nonstandard",
14210 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-snap-y"
14211},
14212 "-ms-scroll-translation": {
14213 syntax: "none | vertical-to-horizontal",
14214 media: "interactive",
14215 inherited: true,
14216 animationType: "discrete",
14217 percentages: "no",
14218 groups: [
14219 "Microsoft Extensions"
14220 ],
14221 initial: "none",
14222 appliesto: "allElements",
14223 computed: "asSpecified",
14224 order: "uniqueOrder",
14225 status: "nonstandard",
14226 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-scroll-translation"
14227},
14228 "-ms-text-autospace": {
14229 syntax: "none | ideograph-alpha | ideograph-numeric | ideograph-parenthesis | ideograph-space",
14230 media: "visual",
14231 inherited: false,
14232 animationType: "discrete",
14233 percentages: "no",
14234 groups: [
14235 "Microsoft Extensions"
14236 ],
14237 initial: "none",
14238 appliesto: "allElements",
14239 computed: "asSpecified",
14240 order: "uniqueOrder",
14241 status: "nonstandard",
14242 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-text-autospace"
14243},
14244 "-ms-touch-select": {
14245 syntax: "grippers | none",
14246 media: "interactive",
14247 inherited: true,
14248 animationType: "discrete",
14249 percentages: "no",
14250 groups: [
14251 "Microsoft Extensions"
14252 ],
14253 initial: "grippers",
14254 appliesto: "allElements",
14255 computed: "asSpecified",
14256 order: "uniqueOrder",
14257 status: "nonstandard",
14258 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-touch-select"
14259},
14260 "-ms-user-select": {
14261 syntax: "none | element | text",
14262 media: "interactive",
14263 inherited: false,
14264 animationType: "discrete",
14265 percentages: "no",
14266 groups: [
14267 "Microsoft Extensions"
14268 ],
14269 initial: "text",
14270 appliesto: "nonReplacedElements",
14271 computed: "asSpecified",
14272 order: "uniqueOrder",
14273 status: "nonstandard",
14274 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-user-select"
14275},
14276 "-ms-wrap-flow": {
14277 syntax: "auto | both | start | end | maximum | clear",
14278 media: "visual",
14279 inherited: false,
14280 animationType: "discrete",
14281 percentages: "no",
14282 groups: [
14283 "Microsoft Extensions"
14284 ],
14285 initial: "auto",
14286 appliesto: "blockLevelElements",
14287 computed: "asSpecified",
14288 order: "uniqueOrder",
14289 status: "nonstandard",
14290 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-flow"
14291},
14292 "-ms-wrap-margin": {
14293 syntax: "<length>",
14294 media: "visual",
14295 inherited: false,
14296 animationType: "discrete",
14297 percentages: "no",
14298 groups: [
14299 "Microsoft Extensions"
14300 ],
14301 initial: "0",
14302 appliesto: "exclusionElements",
14303 computed: "asSpecified",
14304 order: "uniqueOrder",
14305 status: "nonstandard",
14306 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-margin"
14307},
14308 "-ms-wrap-through": {
14309 syntax: "wrap | none",
14310 media: "visual",
14311 inherited: false,
14312 animationType: "discrete",
14313 percentages: "no",
14314 groups: [
14315 "Microsoft Extensions"
14316 ],
14317 initial: "wrap",
14318 appliesto: "blockLevelElements",
14319 computed: "asSpecified",
14320 order: "uniqueOrder",
14321 status: "nonstandard",
14322 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-ms-wrap-through"
14323},
14324 "-moz-appearance": {
14325 syntax: "none | button | button-arrow-down | button-arrow-next | button-arrow-previous | button-arrow-up | button-bevel | button-focus | caret | checkbox | checkbox-container | checkbox-label | checkmenuitem | dualbutton | groupbox | listbox | listitem | menuarrow | menubar | menucheckbox | menuimage | menuitem | menuitemtext | menulist | menulist-button | menulist-text | menulist-textfield | menupopup | menuradio | menuseparator | meterbar | meterchunk | progressbar | progressbar-vertical | progresschunk | progresschunk-vertical | radio | radio-container | radio-label | radiomenuitem | range | range-thumb | resizer | resizerpanel | scale-horizontal | scalethumbend | scalethumb-horizontal | scalethumbstart | scalethumbtick | scalethumb-vertical | scale-vertical | scrollbarbutton-down | scrollbarbutton-left | scrollbarbutton-right | scrollbarbutton-up | scrollbarthumb-horizontal | scrollbarthumb-vertical | scrollbartrack-horizontal | scrollbartrack-vertical | searchfield | separator | sheet | spinner | spinner-downbutton | spinner-textfield | spinner-upbutton | splitter | statusbar | statusbarpanel | tab | tabpanel | tabpanels | tab-scroll-arrow-back | tab-scroll-arrow-forward | textfield | textfield-multiline | toolbar | toolbarbutton | toolbarbutton-dropdown | toolbargripper | toolbox | tooltip | treeheader | treeheadercell | treeheadersortarrow | treeitem | treeline | treetwisty | treetwistyopen | treeview | -moz-mac-unified-toolbar | -moz-win-borderless-glass | -moz-win-browsertabbar-toolbox | -moz-win-communicationstext | -moz-win-communications-toolbox | -moz-win-exclude-glass | -moz-win-glass | -moz-win-mediatext | -moz-win-media-toolbox | -moz-window-button-box | -moz-window-button-box-maximized | -moz-window-button-close | -moz-window-button-maximize | -moz-window-button-minimize | -moz-window-button-restore | -moz-window-frame-bottom | -moz-window-frame-left | -moz-window-frame-right | -moz-window-titlebar | -moz-window-titlebar-maximized",
14326 media: "visual",
14327 inherited: false,
14328 animationType: "discrete",
14329 percentages: "no",
14330 groups: [
14331 "Mozilla Extensions",
14332 "WebKit Extensions"
14333 ],
14334 initial: "noneButOverriddenInUserAgentCSS",
14335 appliesto: "allElements",
14336 computed: "asSpecified",
14337 order: "uniqueOrder",
14338 status: "nonstandard",
14339 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/appearance"
14340},
14341 "-moz-binding": {
14342 syntax: "<url> | none",
14343 media: "visual",
14344 inherited: false,
14345 animationType: "discrete",
14346 percentages: "no",
14347 groups: [
14348 "Mozilla Extensions"
14349 ],
14350 initial: "none",
14351 appliesto: "allElementsExceptGeneratedContentOrPseudoElements",
14352 computed: "asSpecified",
14353 order: "uniqueOrder",
14354 status: "nonstandard",
14355 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-binding"
14356},
14357 "-moz-border-bottom-colors": {
14358 syntax: "<color>+ | none",
14359 media: "visual",
14360 inherited: false,
14361 animationType: "discrete",
14362 percentages: "no",
14363 groups: [
14364 "Mozilla Extensions"
14365 ],
14366 initial: "none",
14367 appliesto: "allElements",
14368 computed: "asSpecified",
14369 order: "uniqueOrder",
14370 status: "nonstandard",
14371 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-bottom-colors"
14372},
14373 "-moz-border-left-colors": {
14374 syntax: "<color>+ | none",
14375 media: "visual",
14376 inherited: false,
14377 animationType: "discrete",
14378 percentages: "no",
14379 groups: [
14380 "Mozilla Extensions"
14381 ],
14382 initial: "none",
14383 appliesto: "allElements",
14384 computed: "asSpecified",
14385 order: "uniqueOrder",
14386 status: "nonstandard",
14387 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-left-colors"
14388},
14389 "-moz-border-right-colors": {
14390 syntax: "<color>+ | none",
14391 media: "visual",
14392 inherited: false,
14393 animationType: "discrete",
14394 percentages: "no",
14395 groups: [
14396 "Mozilla Extensions"
14397 ],
14398 initial: "none",
14399 appliesto: "allElements",
14400 computed: "asSpecified",
14401 order: "uniqueOrder",
14402 status: "nonstandard",
14403 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-right-colors"
14404},
14405 "-moz-border-top-colors": {
14406 syntax: "<color>+ | none",
14407 media: "visual",
14408 inherited: false,
14409 animationType: "discrete",
14410 percentages: "no",
14411 groups: [
14412 "Mozilla Extensions"
14413 ],
14414 initial: "none",
14415 appliesto: "allElements",
14416 computed: "asSpecified",
14417 order: "uniqueOrder",
14418 status: "nonstandard",
14419 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-border-top-colors"
14420},
14421 "-moz-context-properties": {
14422 syntax: "none | [ fill | fill-opacity | stroke | stroke-opacity ]#",
14423 media: "visual",
14424 inherited: true,
14425 animationType: "discrete",
14426 percentages: "no",
14427 groups: [
14428 "Mozilla Extensions"
14429 ],
14430 initial: "none",
14431 appliesto: "allElementsThatCanReferenceImages",
14432 computed: "asSpecified",
14433 order: "uniqueOrder",
14434 status: "nonstandard",
14435 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-context-properties"
14436},
14437 "-moz-float-edge": {
14438 syntax: "border-box | content-box | margin-box | padding-box",
14439 media: "visual",
14440 inherited: false,
14441 animationType: "discrete",
14442 percentages: "no",
14443 groups: [
14444 "Mozilla Extensions"
14445 ],
14446 initial: "content-box",
14447 appliesto: "allElements",
14448 computed: "asSpecified",
14449 order: "uniqueOrder",
14450 status: "nonstandard",
14451 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-float-edge"
14452},
14453 "-moz-force-broken-image-icon": {
14454 syntax: "<integer [0,1]>",
14455 media: "visual",
14456 inherited: false,
14457 animationType: "discrete",
14458 percentages: "no",
14459 groups: [
14460 "Mozilla Extensions"
14461 ],
14462 initial: "0",
14463 appliesto: "images",
14464 computed: "asSpecified",
14465 order: "uniqueOrder",
14466 status: "nonstandard",
14467 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-force-broken-image-icon"
14468},
14469 "-moz-image-region": {
14470 syntax: "<shape> | auto",
14471 media: "visual",
14472 inherited: true,
14473 animationType: "discrete",
14474 percentages: "no",
14475 groups: [
14476 "Mozilla Extensions"
14477 ],
14478 initial: "auto",
14479 appliesto: "xulImageElements",
14480 computed: "asSpecified",
14481 order: "uniqueOrder",
14482 status: "nonstandard",
14483 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-image-region"
14484},
14485 "-moz-orient": {
14486 syntax: "inline | block | horizontal | vertical",
14487 media: "visual",
14488 inherited: false,
14489 animationType: "discrete",
14490 percentages: "no",
14491 groups: [
14492 "Mozilla Extensions"
14493 ],
14494 initial: "inline",
14495 appliesto: "anyElementEffectOnProgressAndMeter",
14496 computed: "asSpecified",
14497 order: "uniqueOrder",
14498 status: "nonstandard",
14499 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-orient"
14500},
14501 "-moz-outline-radius": {
14502 syntax: "<outline-radius>{1,4} [ / <outline-radius>{1,4} ]?",
14503 media: "visual",
14504 inherited: false,
14505 animationType: [
14506 "-moz-outline-radius-topleft",
14507 "-moz-outline-radius-topright",
14508 "-moz-outline-radius-bottomright",
14509 "-moz-outline-radius-bottomleft"
14510 ],
14511 percentages: [
14512 "-moz-outline-radius-topleft",
14513 "-moz-outline-radius-topright",
14514 "-moz-outline-radius-bottomright",
14515 "-moz-outline-radius-bottomleft"
14516 ],
14517 groups: [
14518 "Mozilla Extensions"
14519 ],
14520 initial: [
14521 "-moz-outline-radius-topleft",
14522 "-moz-outline-radius-topright",
14523 "-moz-outline-radius-bottomright",
14524 "-moz-outline-radius-bottomleft"
14525 ],
14526 appliesto: "allElements",
14527 computed: [
14528 "-moz-outline-radius-topleft",
14529 "-moz-outline-radius-topright",
14530 "-moz-outline-radius-bottomright",
14531 "-moz-outline-radius-bottomleft"
14532 ],
14533 order: "uniqueOrder",
14534 status: "nonstandard",
14535 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius"
14536},
14537 "-moz-outline-radius-bottomleft": {
14538 syntax: "<outline-radius>",
14539 media: "visual",
14540 inherited: false,
14541 animationType: "lpc",
14542 percentages: "referToDimensionOfBorderBox",
14543 groups: [
14544 "Mozilla Extensions"
14545 ],
14546 initial: "0",
14547 appliesto: "allElements",
14548 computed: "asSpecified",
14549 order: "uniqueOrder",
14550 status: "nonstandard",
14551 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-bottomleft"
14552},
14553 "-moz-outline-radius-bottomright": {
14554 syntax: "<outline-radius>",
14555 media: "visual",
14556 inherited: false,
14557 animationType: "lpc",
14558 percentages: "referToDimensionOfBorderBox",
14559 groups: [
14560 "Mozilla Extensions"
14561 ],
14562 initial: "0",
14563 appliesto: "allElements",
14564 computed: "asSpecified",
14565 order: "uniqueOrder",
14566 status: "nonstandard",
14567 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-bottomright"
14568},
14569 "-moz-outline-radius-topleft": {
14570 syntax: "<outline-radius>",
14571 media: "visual",
14572 inherited: false,
14573 animationType: "lpc",
14574 percentages: "referToDimensionOfBorderBox",
14575 groups: [
14576 "Mozilla Extensions"
14577 ],
14578 initial: "0",
14579 appliesto: "allElements",
14580 computed: "asSpecified",
14581 order: "uniqueOrder",
14582 status: "nonstandard",
14583 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-topleft"
14584},
14585 "-moz-outline-radius-topright": {
14586 syntax: "<outline-radius>",
14587 media: "visual",
14588 inherited: false,
14589 animationType: "lpc",
14590 percentages: "referToDimensionOfBorderBox",
14591 groups: [
14592 "Mozilla Extensions"
14593 ],
14594 initial: "0",
14595 appliesto: "allElements",
14596 computed: "asSpecified",
14597 order: "uniqueOrder",
14598 status: "nonstandard",
14599 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-outline-radius-topright"
14600},
14601 "-moz-stack-sizing": {
14602 syntax: "ignore | stretch-to-fit",
14603 media: "visual",
14604 inherited: true,
14605 animationType: "discrete",
14606 percentages: "no",
14607 groups: [
14608 "Mozilla Extensions"
14609 ],
14610 initial: "stretch-to-fit",
14611 appliesto: "allElements",
14612 computed: "asSpecified",
14613 order: "uniqueOrder",
14614 status: "nonstandard",
14615 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-stack-sizing"
14616},
14617 "-moz-text-blink": {
14618 syntax: "none | blink",
14619 media: "visual",
14620 inherited: false,
14621 animationType: "discrete",
14622 percentages: "no",
14623 groups: [
14624 "Mozilla Extensions"
14625 ],
14626 initial: "none",
14627 appliesto: "allElements",
14628 computed: "asSpecified",
14629 order: "uniqueOrder",
14630 status: "nonstandard",
14631 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-text-blink"
14632},
14633 "-moz-user-focus": {
14634 syntax: "ignore | normal | select-after | select-before | select-menu | select-same | select-all | none",
14635 media: "interactive",
14636 inherited: false,
14637 animationType: "discrete",
14638 percentages: "no",
14639 groups: [
14640 "Mozilla Extensions"
14641 ],
14642 initial: "none",
14643 appliesto: "allElements",
14644 computed: "asSpecified",
14645 order: "uniqueOrder",
14646 status: "nonstandard",
14647 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-focus"
14648},
14649 "-moz-user-input": {
14650 syntax: "auto | none | enabled | disabled",
14651 media: "visual",
14652 inherited: true,
14653 animationType: "discrete",
14654 percentages: "no",
14655 groups: [
14656 "Mozilla Extensions"
14657 ],
14658 initial: "auto",
14659 appliesto: "allElements",
14660 computed: "asSpecified",
14661 order: "uniqueOrder",
14662 status: "nonstandard",
14663 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-input"
14664},
14665 "-moz-user-modify": {
14666 syntax: "read-only | read-write | write-only",
14667 media: "interactive",
14668 inherited: true,
14669 animationType: "discrete",
14670 percentages: "no",
14671 groups: [
14672 "Mozilla Extensions"
14673 ],
14674 initial: "read-only",
14675 appliesto: "allElements",
14676 computed: "asSpecified",
14677 order: "uniqueOrder",
14678 status: "nonstandard",
14679 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-user-modify"
14680},
14681 "-moz-window-dragging": {
14682 syntax: "drag | no-drag",
14683 media: "visual",
14684 inherited: false,
14685 animationType: "discrete",
14686 percentages: "no",
14687 groups: [
14688 "Mozilla Extensions"
14689 ],
14690 initial: "drag",
14691 appliesto: "allElementsCreatingNativeWindows",
14692 computed: "asSpecified",
14693 order: "uniqueOrder",
14694 status: "nonstandard",
14695 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-window-dragging"
14696},
14697 "-moz-window-shadow": {
14698 syntax: "default | menu | tooltip | sheet | none",
14699 media: "visual",
14700 inherited: false,
14701 animationType: "discrete",
14702 percentages: "no",
14703 groups: [
14704 "Mozilla Extensions"
14705 ],
14706 initial: "default",
14707 appliesto: "allElementsCreatingNativeWindows",
14708 computed: "asSpecified",
14709 order: "uniqueOrder",
14710 status: "nonstandard",
14711 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-moz-window-shadow"
14712},
14713 "-webkit-appearance": {
14714 syntax: "none | button | button-bevel | caret | checkbox | default-button | inner-spin-button | listbox | listitem | media-controls-background | media-controls-fullscreen-background | media-current-time-display | media-enter-fullscreen-button | media-exit-fullscreen-button | media-fullscreen-button | media-mute-button | media-overlay-play-button | media-play-button | media-seek-back-button | media-seek-forward-button | media-slider | media-sliderthumb | media-time-remaining-display | media-toggle-closed-captions-button | media-volume-slider | media-volume-slider-container | media-volume-sliderthumb | menulist | menulist-button | menulist-text | menulist-textfield | meter | progress-bar | progress-bar-value | push-button | radio | searchfield | searchfield-cancel-button | searchfield-decoration | searchfield-results-button | searchfield-results-decoration | slider-horizontal | slider-vertical | sliderthumb-horizontal | sliderthumb-vertical | square-button | textarea | textfield | -apple-pay-button",
14715 media: "visual",
14716 inherited: false,
14717 animationType: "discrete",
14718 percentages: "no",
14719 groups: [
14720 "WebKit Extensions"
14721 ],
14722 initial: "noneButOverriddenInUserAgentCSS",
14723 appliesto: "allElements",
14724 computed: "asSpecified",
14725 order: "uniqueOrder",
14726 status: "nonstandard",
14727 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/appearance"
14728},
14729 "-webkit-border-before": {
14730 syntax: "<'border-width'> || <'border-style'> || <'color'>",
14731 media: "visual",
14732 inherited: true,
14733 animationType: "discrete",
14734 percentages: [
14735 "-webkit-border-before-width"
14736 ],
14737 groups: [
14738 "WebKit Extensions"
14739 ],
14740 initial: [
14741 "border-width",
14742 "border-style",
14743 "color"
14744 ],
14745 appliesto: "allElements",
14746 computed: [
14747 "border-width",
14748 "border-style",
14749 "color"
14750 ],
14751 order: "uniqueOrder",
14752 status: "nonstandard",
14753 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-border-before"
14754},
14755 "-webkit-border-before-color": {
14756 syntax: "<'color'>",
14757 media: "visual",
14758 inherited: true,
14759 animationType: "discrete",
14760 percentages: "no",
14761 groups: [
14762 "WebKit Extensions"
14763 ],
14764 initial: "currentcolor",
14765 appliesto: "allElements",
14766 computed: "computedColor",
14767 order: "uniqueOrder",
14768 status: "nonstandard"
14769},
14770 "-webkit-border-before-style": {
14771 syntax: "<'border-style'>",
14772 media: "visual",
14773 inherited: true,
14774 animationType: "discrete",
14775 percentages: "no",
14776 groups: [
14777 "WebKit Extensions"
14778 ],
14779 initial: "none",
14780 appliesto: "allElements",
14781 computed: "asSpecified",
14782 order: "uniqueOrder",
14783 status: "nonstandard"
14784},
14785 "-webkit-border-before-width": {
14786 syntax: "<'border-width'>",
14787 media: "visual",
14788 inherited: true,
14789 animationType: "discrete",
14790 percentages: "logicalWidthOfContainingBlock",
14791 groups: [
14792 "WebKit Extensions"
14793 ],
14794 initial: "medium",
14795 appliesto: "allElements",
14796 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
14797 order: "uniqueOrder",
14798 status: "nonstandard"
14799},
14800 "-webkit-box-reflect": {
14801 syntax: "[ above | below | right | left ]? <length>? <image>?",
14802 media: "visual",
14803 inherited: false,
14804 animationType: "discrete",
14805 percentages: "no",
14806 groups: [
14807 "WebKit Extensions"
14808 ],
14809 initial: "none",
14810 appliesto: "allElements",
14811 computed: "asSpecified",
14812 order: "uniqueOrder",
14813 status: "nonstandard",
14814 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-box-reflect"
14815},
14816 "-webkit-line-clamp": {
14817 syntax: "none | <integer>",
14818 media: "visual",
14819 inherited: false,
14820 animationType: "byComputedValueType",
14821 percentages: "no",
14822 groups: [
14823 "WebKit Extensions",
14824 "CSS Overflow"
14825 ],
14826 initial: "none",
14827 appliesto: "allElements",
14828 computed: "asSpecified",
14829 order: "uniqueOrder",
14830 status: "standard",
14831 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-line-clamp"
14832},
14833 "-webkit-mask": {
14834 syntax: "[ <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || [ <box> | border | padding | content | text ] || [ <box> | border | padding | content ] ]#",
14835 media: "visual",
14836 inherited: false,
14837 animationType: "discrete",
14838 percentages: "no",
14839 groups: [
14840 "WebKit Extensions"
14841 ],
14842 initial: [
14843 "-webkit-mask-image",
14844 "-webkit-mask-repeat",
14845 "-webkit-mask-attachment",
14846 "-webkit-mask-position",
14847 "-webkit-mask-origin",
14848 "-webkit-mask-clip"
14849 ],
14850 appliesto: "allElements",
14851 computed: [
14852 "-webkit-mask-image",
14853 "-webkit-mask-repeat",
14854 "-webkit-mask-attachment",
14855 "-webkit-mask-position",
14856 "-webkit-mask-origin",
14857 "-webkit-mask-clip"
14858 ],
14859 order: "uniqueOrder",
14860 status: "nonstandard",
14861 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask"
14862},
14863 "-webkit-mask-attachment": {
14864 syntax: "<attachment>#",
14865 media: "visual",
14866 inherited: false,
14867 animationType: "discrete",
14868 percentages: "no",
14869 groups: [
14870 "WebKit Extensions"
14871 ],
14872 initial: "scroll",
14873 appliesto: "allElements",
14874 computed: "asSpecified",
14875 order: "orderOfAppearance",
14876 status: "nonstandard",
14877 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-attachment"
14878},
14879 "-webkit-mask-clip": {
14880 syntax: "[ <box> | border | padding | content | text ]#",
14881 media: "visual",
14882 inherited: false,
14883 animationType: "discrete",
14884 percentages: "no",
14885 groups: [
14886 "WebKit Extensions"
14887 ],
14888 initial: "border",
14889 appliesto: "allElements",
14890 computed: "asSpecified",
14891 order: "orderOfAppearance",
14892 status: "nonstandard",
14893 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-clip"
14894},
14895 "-webkit-mask-composite": {
14896 syntax: "<composite-style>#",
14897 media: "visual",
14898 inherited: false,
14899 animationType: "discrete",
14900 percentages: "no",
14901 groups: [
14902 "WebKit Extensions"
14903 ],
14904 initial: "source-over",
14905 appliesto: "allElements",
14906 computed: "asSpecified",
14907 order: "orderOfAppearance",
14908 status: "nonstandard",
14909 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-composite"
14910},
14911 "-webkit-mask-image": {
14912 syntax: "<mask-reference>#",
14913 media: "visual",
14914 inherited: false,
14915 animationType: "discrete",
14916 percentages: "no",
14917 groups: [
14918 "WebKit Extensions"
14919 ],
14920 initial: "none",
14921 appliesto: "allElements",
14922 computed: "absoluteURIOrNone",
14923 order: "orderOfAppearance",
14924 status: "nonstandard",
14925 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-image"
14926},
14927 "-webkit-mask-origin": {
14928 syntax: "[ <box> | border | padding | content ]#",
14929 media: "visual",
14930 inherited: false,
14931 animationType: "discrete",
14932 percentages: "no",
14933 groups: [
14934 "WebKit Extensions"
14935 ],
14936 initial: "padding",
14937 appliesto: "allElements",
14938 computed: "asSpecified",
14939 order: "orderOfAppearance",
14940 status: "nonstandard",
14941 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-origin"
14942},
14943 "-webkit-mask-position": {
14944 syntax: "<position>#",
14945 media: "visual",
14946 inherited: false,
14947 animationType: "discrete",
14948 percentages: "referToSizeOfElement",
14949 groups: [
14950 "WebKit Extensions"
14951 ],
14952 initial: "0% 0%",
14953 appliesto: "allElements",
14954 computed: "absoluteLengthOrPercentage",
14955 order: "orderOfAppearance",
14956 status: "nonstandard",
14957 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-position"
14958},
14959 "-webkit-mask-position-x": {
14960 syntax: "[ <length-percentage> | left | center | right ]#",
14961 media: "visual",
14962 inherited: false,
14963 animationType: "discrete",
14964 percentages: "referToSizeOfElement",
14965 groups: [
14966 "WebKit Extensions"
14967 ],
14968 initial: "0%",
14969 appliesto: "allElements",
14970 computed: "absoluteLengthOrPercentage",
14971 order: "orderOfAppearance",
14972 status: "nonstandard",
14973 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-position-x"
14974},
14975 "-webkit-mask-position-y": {
14976 syntax: "[ <length-percentage> | top | center | bottom ]#",
14977 media: "visual",
14978 inherited: false,
14979 animationType: "discrete",
14980 percentages: "referToSizeOfElement",
14981 groups: [
14982 "WebKit Extensions"
14983 ],
14984 initial: "0%",
14985 appliesto: "allElements",
14986 computed: "absoluteLengthOrPercentage",
14987 order: "orderOfAppearance",
14988 status: "nonstandard",
14989 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-position-y"
14990},
14991 "-webkit-mask-repeat": {
14992 syntax: "<repeat-style>#",
14993 media: "visual",
14994 inherited: false,
14995 animationType: "discrete",
14996 percentages: "no",
14997 groups: [
14998 "WebKit Extensions"
14999 ],
15000 initial: "repeat",
15001 appliesto: "allElements",
15002 computed: "asSpecified",
15003 order: "orderOfAppearance",
15004 status: "nonstandard",
15005 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-repeat"
15006},
15007 "-webkit-mask-repeat-x": {
15008 syntax: "repeat | no-repeat | space | round",
15009 media: "visual",
15010 inherited: false,
15011 animationType: "discrete",
15012 percentages: "no",
15013 groups: [
15014 "WebKit Extensions"
15015 ],
15016 initial: "repeat",
15017 appliesto: "allElements",
15018 computed: "asSpecified",
15019 order: "orderOfAppearance",
15020 status: "nonstandard",
15021 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-repeat-x"
15022},
15023 "-webkit-mask-repeat-y": {
15024 syntax: "repeat | no-repeat | space | round",
15025 media: "visual",
15026 inherited: false,
15027 animationType: "discrete",
15028 percentages: "no",
15029 groups: [
15030 "WebKit Extensions"
15031 ],
15032 initial: "repeat",
15033 appliesto: "allElements",
15034 computed: "absoluteLengthOrPercentage",
15035 order: "orderOfAppearance",
15036 status: "nonstandard",
15037 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-repeat-y"
15038},
15039 "-webkit-mask-size": {
15040 syntax: "<bg-size>#",
15041 media: "visual",
15042 inherited: false,
15043 animationType: "discrete",
15044 percentages: "relativeToBackgroundPositioningArea",
15045 groups: [
15046 "WebKit Extensions"
15047 ],
15048 initial: "auto auto",
15049 appliesto: "allElements",
15050 computed: "asSpecified",
15051 order: "orderOfAppearance",
15052 status: "nonstandard",
15053 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-size"
15054},
15055 "-webkit-overflow-scrolling": {
15056 syntax: "auto | touch",
15057 media: "visual",
15058 inherited: true,
15059 animationType: "discrete",
15060 percentages: "no",
15061 groups: [
15062 "WebKit Extensions"
15063 ],
15064 initial: "auto",
15065 appliesto: "scrollingBoxes",
15066 computed: "asSpecified",
15067 order: "orderOfAppearance",
15068 status: "nonstandard",
15069 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-overflow-scrolling"
15070},
15071 "-webkit-tap-highlight-color": {
15072 syntax: "<color>",
15073 media: "visual",
15074 inherited: false,
15075 animationType: "discrete",
15076 percentages: "no",
15077 groups: [
15078 "WebKit Extensions"
15079 ],
15080 initial: "black",
15081 appliesto: "allElements",
15082 computed: "asSpecified",
15083 order: "uniqueOrder",
15084 status: "nonstandard",
15085 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-tap-highlight-color"
15086},
15087 "-webkit-text-fill-color": {
15088 syntax: "<color>",
15089 media: "visual",
15090 inherited: true,
15091 animationType: "color",
15092 percentages: "no",
15093 groups: [
15094 "WebKit Extensions"
15095 ],
15096 initial: "currentcolor",
15097 appliesto: "allElements",
15098 computed: "computedColor",
15099 order: "uniqueOrder",
15100 status: "nonstandard",
15101 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-fill-color"
15102},
15103 "-webkit-text-stroke": {
15104 syntax: "<length> || <color>",
15105 media: "visual",
15106 inherited: true,
15107 animationType: [
15108 "-webkit-text-stroke-width",
15109 "-webkit-text-stroke-color"
15110 ],
15111 percentages: "no",
15112 groups: [
15113 "WebKit Extensions"
15114 ],
15115 initial: [
15116 "-webkit-text-stroke-width",
15117 "-webkit-text-stroke-color"
15118 ],
15119 appliesto: "allElements",
15120 computed: [
15121 "-webkit-text-stroke-width",
15122 "-webkit-text-stroke-color"
15123 ],
15124 order: "canonicalOrder",
15125 status: "nonstandard",
15126 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke"
15127},
15128 "-webkit-text-stroke-color": {
15129 syntax: "<color>",
15130 media: "visual",
15131 inherited: true,
15132 animationType: "color",
15133 percentages: "no",
15134 groups: [
15135 "WebKit Extensions"
15136 ],
15137 initial: "currentcolor",
15138 appliesto: "allElements",
15139 computed: "computedColor",
15140 order: "uniqueOrder",
15141 status: "nonstandard",
15142 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-color"
15143},
15144 "-webkit-text-stroke-width": {
15145 syntax: "<length>",
15146 media: "visual",
15147 inherited: true,
15148 animationType: "discrete",
15149 percentages: "no",
15150 groups: [
15151 "WebKit Extensions"
15152 ],
15153 initial: "0",
15154 appliesto: "allElements",
15155 computed: "absoluteLength",
15156 order: "uniqueOrder",
15157 status: "nonstandard",
15158 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-width"
15159},
15160 "-webkit-touch-callout": {
15161 syntax: "default | none",
15162 media: "visual",
15163 inherited: true,
15164 animationType: "discrete",
15165 percentages: "no",
15166 groups: [
15167 "WebKit Extensions"
15168 ],
15169 initial: "default",
15170 appliesto: "allElements",
15171 computed: "asSpecified",
15172 order: "uniqueOrder",
15173 status: "nonstandard",
15174 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/-webkit-touch-callout"
15175},
15176 "-webkit-user-modify": {
15177 syntax: "read-only | read-write | read-write-plaintext-only",
15178 media: "interactive",
15179 inherited: true,
15180 animationType: "discrete",
15181 percentages: "no",
15182 groups: [
15183 "WebKit Extensions"
15184 ],
15185 initial: "read-only",
15186 appliesto: "allElements",
15187 computed: "asSpecified",
15188 order: "uniqueOrder",
15189 status: "nonstandard"
15190},
15191 "align-content": {
15192 syntax: "normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>",
15193 media: "visual",
15194 inherited: false,
15195 animationType: "discrete",
15196 percentages: "no",
15197 groups: [
15198 "CSS Box Alignment"
15199 ],
15200 initial: "normal",
15201 appliesto: "multilineFlexContainers",
15202 computed: "asSpecified",
15203 order: "uniqueOrder",
15204 status: "standard",
15205 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-content"
15206},
15207 "align-items": {
15208 syntax: "normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]",
15209 media: "visual",
15210 inherited: false,
15211 animationType: "discrete",
15212 percentages: "no",
15213 groups: [
15214 "CSS Box Alignment"
15215 ],
15216 initial: "normal",
15217 appliesto: "allElements",
15218 computed: "asSpecified",
15219 order: "uniqueOrder",
15220 status: "standard",
15221 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-items"
15222},
15223 "align-self": {
15224 syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>",
15225 media: "visual",
15226 inherited: false,
15227 animationType: "discrete",
15228 percentages: "no",
15229 groups: [
15230 "CSS Box Alignment"
15231 ],
15232 initial: "auto",
15233 appliesto: "flexItemsGridItemsAndAbsolutelyPositionedBoxes",
15234 computed: "autoOnAbsolutelyPositionedElementsValueOfAlignItemsOnParent",
15235 order: "uniqueOrder",
15236 status: "standard",
15237 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-self"
15238},
15239 "align-tracks": {
15240 syntax: "[ normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position> ]#",
15241 media: "visual",
15242 inherited: false,
15243 animationType: "discrete",
15244 percentages: "no",
15245 groups: [
15246 "CSS Grid Layout"
15247 ],
15248 initial: "normal",
15249 appliesto: "gridContainersWithMasonryLayoutInTheirBlockAxis",
15250 computed: "asSpecified",
15251 order: "uniqueOrder",
15252 status: "experimental",
15253 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/align-tracks"
15254},
15255 all: all,
15256 animation: animation,
15257 "animation-delay": {
15258 syntax: "<time>#",
15259 media: "visual",
15260 inherited: false,
15261 animationType: "discrete",
15262 percentages: "no",
15263 groups: [
15264 "CSS Animations"
15265 ],
15266 initial: "0s",
15267 appliesto: "allElementsAndPseudos",
15268 computed: "asSpecified",
15269 order: "uniqueOrder",
15270 status: "standard",
15271 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-delay"
15272},
15273 "animation-direction": {
15274 syntax: "<single-animation-direction>#",
15275 media: "visual",
15276 inherited: false,
15277 animationType: "discrete",
15278 percentages: "no",
15279 groups: [
15280 "CSS Animations"
15281 ],
15282 initial: "normal",
15283 appliesto: "allElementsAndPseudos",
15284 computed: "asSpecified",
15285 order: "uniqueOrder",
15286 status: "standard",
15287 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-direction"
15288},
15289 "animation-duration": {
15290 syntax: "<time>#",
15291 media: "visual",
15292 inherited: false,
15293 animationType: "discrete",
15294 percentages: "no",
15295 groups: [
15296 "CSS Animations"
15297 ],
15298 initial: "0s",
15299 appliesto: "allElementsAndPseudos",
15300 computed: "asSpecified",
15301 order: "uniqueOrder",
15302 status: "standard",
15303 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-duration"
15304},
15305 "animation-fill-mode": {
15306 syntax: "<single-animation-fill-mode>#",
15307 media: "visual",
15308 inherited: false,
15309 animationType: "discrete",
15310 percentages: "no",
15311 groups: [
15312 "CSS Animations"
15313 ],
15314 initial: "none",
15315 appliesto: "allElementsAndPseudos",
15316 computed: "asSpecified",
15317 order: "uniqueOrder",
15318 status: "standard",
15319 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-fill-mode"
15320},
15321 "animation-iteration-count": {
15322 syntax: "<single-animation-iteration-count>#",
15323 media: "visual",
15324 inherited: false,
15325 animationType: "discrete",
15326 percentages: "no",
15327 groups: [
15328 "CSS Animations"
15329 ],
15330 initial: "1",
15331 appliesto: "allElementsAndPseudos",
15332 computed: "asSpecified",
15333 order: "uniqueOrder",
15334 status: "standard",
15335 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-iteration-count"
15336},
15337 "animation-name": {
15338 syntax: "[ none | <keyframes-name> ]#",
15339 media: "visual",
15340 inherited: false,
15341 animationType: "discrete",
15342 percentages: "no",
15343 groups: [
15344 "CSS Animations"
15345 ],
15346 initial: "none",
15347 appliesto: "allElementsAndPseudos",
15348 computed: "asSpecified",
15349 order: "uniqueOrder",
15350 status: "standard",
15351 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-name"
15352},
15353 "animation-play-state": {
15354 syntax: "<single-animation-play-state>#",
15355 media: "visual",
15356 inherited: false,
15357 animationType: "discrete",
15358 percentages: "no",
15359 groups: [
15360 "CSS Animations"
15361 ],
15362 initial: "running",
15363 appliesto: "allElementsAndPseudos",
15364 computed: "asSpecified",
15365 order: "uniqueOrder",
15366 status: "standard",
15367 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-play-state"
15368},
15369 "animation-timing-function": {
15370 syntax: "<timing-function>#",
15371 media: "visual",
15372 inherited: false,
15373 animationType: "discrete",
15374 percentages: "no",
15375 groups: [
15376 "CSS Animations"
15377 ],
15378 initial: "ease",
15379 appliesto: "allElementsAndPseudos",
15380 computed: "asSpecified",
15381 order: "uniqueOrder",
15382 status: "standard",
15383 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/animation-timing-function"
15384},
15385 appearance: appearance,
15386 "aspect-ratio": {
15387 syntax: "auto | <ratio>",
15388 media: "all",
15389 inherited: false,
15390 animationType: "discrete",
15391 percentages: "no",
15392 groups: [
15393 "CSS Basic User Interface"
15394 ],
15395 initial: "auto",
15396 appliesto: "allElementsExceptInlineBoxesAndInternalRubyOrTableBoxes",
15397 computed: "asSpecified",
15398 order: "perGrammar",
15399 status: "experimental",
15400 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/aspect-ratio"
15401},
15402 azimuth: azimuth,
15403 "backdrop-filter": {
15404 syntax: "none | <filter-function-list>",
15405 media: "visual",
15406 inherited: false,
15407 animationType: "filterList",
15408 percentages: "no",
15409 groups: [
15410 "Filter Effects"
15411 ],
15412 initial: "none",
15413 appliesto: "allElementsSVGContainerElements",
15414 computed: "asSpecified",
15415 order: "uniqueOrder",
15416 status: "standard",
15417 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/backdrop-filter"
15418},
15419 "backface-visibility": {
15420 syntax: "visible | hidden",
15421 media: "visual",
15422 inherited: false,
15423 animationType: "discrete",
15424 percentages: "no",
15425 groups: [
15426 "CSS Transforms"
15427 ],
15428 initial: "visible",
15429 appliesto: "transformableElements",
15430 computed: "asSpecified",
15431 order: "uniqueOrder",
15432 status: "standard",
15433 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/backface-visibility"
15434},
15435 background: background,
15436 "background-attachment": {
15437 syntax: "<attachment>#",
15438 media: "visual",
15439 inherited: false,
15440 animationType: "discrete",
15441 percentages: "no",
15442 groups: [
15443 "CSS Backgrounds and Borders"
15444 ],
15445 initial: "scroll",
15446 appliesto: "allElements",
15447 computed: "asSpecified",
15448 order: "uniqueOrder",
15449 alsoAppliesTo: [
15450 "::first-letter",
15451 "::first-line",
15452 "::placeholder"
15453 ],
15454 status: "standard",
15455 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-attachment"
15456},
15457 "background-blend-mode": {
15458 syntax: "<blend-mode>#",
15459 media: "none",
15460 inherited: false,
15461 animationType: "discrete",
15462 percentages: "no",
15463 groups: [
15464 "Compositing and Blending"
15465 ],
15466 initial: "normal",
15467 appliesto: "allElementsSVGContainerGraphicsAndGraphicsReferencingElements",
15468 computed: "asSpecified",
15469 order: "uniqueOrder",
15470 alsoAppliesTo: [
15471 "::first-letter",
15472 "::first-line",
15473 "::placeholder"
15474 ],
15475 status: "standard",
15476 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-blend-mode"
15477},
15478 "background-clip": {
15479 syntax: "<box>#",
15480 media: "visual",
15481 inherited: false,
15482 animationType: "discrete",
15483 percentages: "no",
15484 groups: [
15485 "CSS Backgrounds and Borders"
15486 ],
15487 initial: "border-box",
15488 appliesto: "allElements",
15489 computed: "asSpecified",
15490 order: "uniqueOrder",
15491 alsoAppliesTo: [
15492 "::first-letter",
15493 "::first-line",
15494 "::placeholder"
15495 ],
15496 status: "standard",
15497 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-clip"
15498},
15499 "background-color": {
15500 syntax: "<color>",
15501 media: "visual",
15502 inherited: false,
15503 animationType: "color",
15504 percentages: "no",
15505 groups: [
15506 "CSS Backgrounds and Borders"
15507 ],
15508 initial: "transparent",
15509 appliesto: "allElements",
15510 computed: "computedColor",
15511 order: "uniqueOrder",
15512 alsoAppliesTo: [
15513 "::first-letter",
15514 "::first-line",
15515 "::placeholder"
15516 ],
15517 status: "standard",
15518 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-color"
15519},
15520 "background-image": {
15521 syntax: "<bg-image>#",
15522 media: "visual",
15523 inherited: false,
15524 animationType: "discrete",
15525 percentages: "no",
15526 groups: [
15527 "CSS Backgrounds and Borders"
15528 ],
15529 initial: "none",
15530 appliesto: "allElements",
15531 computed: "asSpecifiedURLsAbsolute",
15532 order: "uniqueOrder",
15533 alsoAppliesTo: [
15534 "::first-letter",
15535 "::first-line",
15536 "::placeholder"
15537 ],
15538 status: "standard",
15539 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-image"
15540},
15541 "background-origin": {
15542 syntax: "<box>#",
15543 media: "visual",
15544 inherited: false,
15545 animationType: "discrete",
15546 percentages: "no",
15547 groups: [
15548 "CSS Backgrounds and Borders"
15549 ],
15550 initial: "padding-box",
15551 appliesto: "allElements",
15552 computed: "asSpecified",
15553 order: "uniqueOrder",
15554 alsoAppliesTo: [
15555 "::first-letter",
15556 "::first-line",
15557 "::placeholder"
15558 ],
15559 status: "standard",
15560 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-origin"
15561},
15562 "background-position": {
15563 syntax: "<bg-position>#",
15564 media: "visual",
15565 inherited: false,
15566 animationType: "repeatableListOfSimpleListOfLpc",
15567 percentages: "referToSizeOfBackgroundPositioningAreaMinusBackgroundImageSize",
15568 groups: [
15569 "CSS Backgrounds and Borders"
15570 ],
15571 initial: "0% 0%",
15572 appliesto: "allElements",
15573 computed: "listEachItemTwoKeywordsOriginOffsets",
15574 order: "uniqueOrder",
15575 alsoAppliesTo: [
15576 "::first-letter",
15577 "::first-line",
15578 "::placeholder"
15579 ],
15580 status: "standard",
15581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position"
15582},
15583 "background-position-x": {
15584 syntax: "[ center | [ [ left | right | x-start | x-end ]? <length-percentage>? ]! ]#",
15585 media: "visual",
15586 inherited: false,
15587 animationType: "discrete",
15588 percentages: "referToWidthOfBackgroundPositioningAreaMinusBackgroundImageHeight",
15589 groups: [
15590 "CSS Backgrounds and Borders"
15591 ],
15592 initial: "left",
15593 appliesto: "allElements",
15594 computed: "listEachItemConsistingOfAbsoluteLengthPercentageAndOrigin",
15595 order: "uniqueOrder",
15596 status: "experimental",
15597 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position-x"
15598},
15599 "background-position-y": {
15600 syntax: "[ center | [ [ top | bottom | y-start | y-end ]? <length-percentage>? ]! ]#",
15601 media: "visual",
15602 inherited: false,
15603 animationType: "discrete",
15604 percentages: "referToHeightOfBackgroundPositioningAreaMinusBackgroundImageHeight",
15605 groups: [
15606 "CSS Backgrounds and Borders"
15607 ],
15608 initial: "top",
15609 appliesto: "allElements",
15610 computed: "listEachItemConsistingOfAbsoluteLengthPercentageAndOrigin",
15611 order: "uniqueOrder",
15612 status: "experimental",
15613 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-position-y"
15614},
15615 "background-repeat": {
15616 syntax: "<repeat-style>#",
15617 media: "visual",
15618 inherited: false,
15619 animationType: "discrete",
15620 percentages: "no",
15621 groups: [
15622 "CSS Backgrounds and Borders"
15623 ],
15624 initial: "repeat",
15625 appliesto: "allElements",
15626 computed: "listEachItemHasTwoKeywordsOnePerDimension",
15627 order: "uniqueOrder",
15628 alsoAppliesTo: [
15629 "::first-letter",
15630 "::first-line",
15631 "::placeholder"
15632 ],
15633 status: "standard",
15634 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-repeat"
15635},
15636 "background-size": {
15637 syntax: "<bg-size>#",
15638 media: "visual",
15639 inherited: false,
15640 animationType: "repeatableListOfSimpleListOfLpc",
15641 percentages: "relativeToBackgroundPositioningArea",
15642 groups: [
15643 "CSS Backgrounds and Borders"
15644 ],
15645 initial: "auto auto",
15646 appliesto: "allElements",
15647 computed: "asSpecifiedRelativeToAbsoluteLengths",
15648 order: "uniqueOrder",
15649 alsoAppliesTo: [
15650 "::first-letter",
15651 "::first-line",
15652 "::placeholder"
15653 ],
15654 status: "standard",
15655 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/background-size"
15656},
15657 "block-overflow": {
15658 syntax: "clip | ellipsis | <string>",
15659 media: "visual",
15660 inherited: true,
15661 animationType: "discrete",
15662 percentages: "no",
15663 groups: [
15664 "CSS Overflow"
15665 ],
15666 initial: "clip",
15667 appliesto: "blockContainers",
15668 computed: "asSpecified",
15669 order: "perGrammar",
15670 status: "experimental"
15671},
15672 "block-size": {
15673 syntax: "<'width'>",
15674 media: "visual",
15675 inherited: false,
15676 animationType: "lpc",
15677 percentages: "blockSizeOfContainingBlock",
15678 groups: [
15679 "CSS Logical Properties"
15680 ],
15681 initial: "auto",
15682 appliesto: "sameAsWidthAndHeight",
15683 computed: "sameAsWidthAndHeight",
15684 order: "uniqueOrder",
15685 status: "standard",
15686 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/block-size"
15687},
15688 border: border,
15689 "border-block": {
15690 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15691 media: "visual",
15692 inherited: false,
15693 animationType: "discrete",
15694 percentages: "no",
15695 groups: [
15696 "CSS Logical Properties"
15697 ],
15698 initial: [
15699 "border-top-width",
15700 "border-top-style",
15701 "border-top-color"
15702 ],
15703 appliesto: "allElements",
15704 computed: [
15705 "border-top-width",
15706 "border-top-style",
15707 "border-top-color"
15708 ],
15709 order: "uniqueOrder",
15710 status: "standard",
15711 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block"
15712},
15713 "border-block-color": {
15714 syntax: "<'border-top-color'>{1,2}",
15715 media: "visual",
15716 inherited: false,
15717 animationType: "discrete",
15718 percentages: "no",
15719 groups: [
15720 "CSS Logical Properties"
15721 ],
15722 initial: "currentcolor",
15723 appliesto: "allElements",
15724 computed: "computedColor",
15725 order: "uniqueOrder",
15726 status: "standard",
15727 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-color"
15728},
15729 "border-block-style": {
15730 syntax: "<'border-top-style'>",
15731 media: "visual",
15732 inherited: false,
15733 animationType: "discrete",
15734 percentages: "no",
15735 groups: [
15736 "CSS Logical Properties"
15737 ],
15738 initial: "none",
15739 appliesto: "allElements",
15740 computed: "asSpecified",
15741 order: "uniqueOrder",
15742 status: "standard",
15743 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-style"
15744},
15745 "border-block-width": {
15746 syntax: "<'border-top-width'>",
15747 media: "visual",
15748 inherited: false,
15749 animationType: "discrete",
15750 percentages: "logicalWidthOfContainingBlock",
15751 groups: [
15752 "CSS Logical Properties"
15753 ],
15754 initial: "medium",
15755 appliesto: "allElements",
15756 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15757 order: "uniqueOrder",
15758 status: "standard",
15759 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-width"
15760},
15761 "border-block-end": {
15762 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15763 media: "visual",
15764 inherited: false,
15765 animationType: [
15766 "border-block-end-color",
15767 "border-block-end-style",
15768 "border-block-end-width"
15769 ],
15770 percentages: "no",
15771 groups: [
15772 "CSS Logical Properties"
15773 ],
15774 initial: [
15775 "border-top-width",
15776 "border-top-style",
15777 "border-top-color"
15778 ],
15779 appliesto: "allElements",
15780 computed: [
15781 "border-top-width",
15782 "border-top-style",
15783 "border-top-color"
15784 ],
15785 order: "uniqueOrder",
15786 status: "standard",
15787 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end"
15788},
15789 "border-block-end-color": {
15790 syntax: "<'border-top-color'>",
15791 media: "visual",
15792 inherited: false,
15793 animationType: "color",
15794 percentages: "no",
15795 groups: [
15796 "CSS Logical Properties"
15797 ],
15798 initial: "currentcolor",
15799 appliesto: "allElements",
15800 computed: "computedColor",
15801 order: "uniqueOrder",
15802 status: "standard",
15803 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-color"
15804},
15805 "border-block-end-style": {
15806 syntax: "<'border-top-style'>",
15807 media: "visual",
15808 inherited: false,
15809 animationType: "discrete",
15810 percentages: "no",
15811 groups: [
15812 "CSS Logical Properties"
15813 ],
15814 initial: "none",
15815 appliesto: "allElements",
15816 computed: "asSpecified",
15817 order: "uniqueOrder",
15818 status: "standard",
15819 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-style"
15820},
15821 "border-block-end-width": {
15822 syntax: "<'border-top-width'>",
15823 media: "visual",
15824 inherited: false,
15825 animationType: "length",
15826 percentages: "logicalWidthOfContainingBlock",
15827 groups: [
15828 "CSS Logical Properties"
15829 ],
15830 initial: "medium",
15831 appliesto: "allElements",
15832 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15833 order: "uniqueOrder",
15834 status: "standard",
15835 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-end-width"
15836},
15837 "border-block-start": {
15838 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
15839 media: "visual",
15840 inherited: false,
15841 animationType: [
15842 "border-block-start-color",
15843 "border-block-start-style",
15844 "border-block-start-width"
15845 ],
15846 percentages: "no",
15847 groups: [
15848 "CSS Logical Properties"
15849 ],
15850 initial: [
15851 "border-width",
15852 "border-style",
15853 "color"
15854 ],
15855 appliesto: "allElements",
15856 computed: [
15857 "border-width",
15858 "border-style",
15859 "border-block-start-color"
15860 ],
15861 order: "uniqueOrder",
15862 status: "standard",
15863 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start"
15864},
15865 "border-block-start-color": {
15866 syntax: "<'border-top-color'>",
15867 media: "visual",
15868 inherited: false,
15869 animationType: "color",
15870 percentages: "no",
15871 groups: [
15872 "CSS Logical Properties"
15873 ],
15874 initial: "currentcolor",
15875 appliesto: "allElements",
15876 computed: "computedColor",
15877 order: "uniqueOrder",
15878 status: "standard",
15879 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-color"
15880},
15881 "border-block-start-style": {
15882 syntax: "<'border-top-style'>",
15883 media: "visual",
15884 inherited: false,
15885 animationType: "discrete",
15886 percentages: "no",
15887 groups: [
15888 "CSS Logical Properties"
15889 ],
15890 initial: "none",
15891 appliesto: "allElements",
15892 computed: "asSpecified",
15893 order: "uniqueOrder",
15894 status: "standard",
15895 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-style"
15896},
15897 "border-block-start-width": {
15898 syntax: "<'border-top-width'>",
15899 media: "visual",
15900 inherited: false,
15901 animationType: "length",
15902 percentages: "logicalWidthOfContainingBlock",
15903 groups: [
15904 "CSS Logical Properties"
15905 ],
15906 initial: "medium",
15907 appliesto: "allElements",
15908 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
15909 order: "uniqueOrder",
15910 status: "standard",
15911 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-block-start-width"
15912},
15913 "border-bottom": {
15914 syntax: "<line-width> || <line-style> || <color>",
15915 media: "visual",
15916 inherited: false,
15917 animationType: [
15918 "border-bottom-color",
15919 "border-bottom-style",
15920 "border-bottom-width"
15921 ],
15922 percentages: "no",
15923 groups: [
15924 "CSS Backgrounds and Borders"
15925 ],
15926 initial: [
15927 "border-bottom-width",
15928 "border-bottom-style",
15929 "border-bottom-color"
15930 ],
15931 appliesto: "allElements",
15932 computed: [
15933 "border-bottom-width",
15934 "border-bottom-style",
15935 "border-bottom-color"
15936 ],
15937 order: "orderOfAppearance",
15938 alsoAppliesTo: [
15939 "::first-letter"
15940 ],
15941 status: "standard",
15942 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom"
15943},
15944 "border-bottom-color": {
15945 syntax: "<'border-top-color'>",
15946 media: "visual",
15947 inherited: false,
15948 animationType: "color",
15949 percentages: "no",
15950 groups: [
15951 "CSS Backgrounds and Borders"
15952 ],
15953 initial: "currentcolor",
15954 appliesto: "allElements",
15955 computed: "computedColor",
15956 order: "uniqueOrder",
15957 alsoAppliesTo: [
15958 "::first-letter"
15959 ],
15960 status: "standard",
15961 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-color"
15962},
15963 "border-bottom-left-radius": {
15964 syntax: "<length-percentage>{1,2}",
15965 media: "visual",
15966 inherited: false,
15967 animationType: "lpc",
15968 percentages: "referToDimensionOfBorderBox",
15969 groups: [
15970 "CSS Backgrounds and Borders"
15971 ],
15972 initial: "0",
15973 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15974 computed: "twoAbsoluteLengthOrPercentages",
15975 order: "uniqueOrder",
15976 alsoAppliesTo: [
15977 "::first-letter"
15978 ],
15979 status: "standard",
15980 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-left-radius"
15981},
15982 "border-bottom-right-radius": {
15983 syntax: "<length-percentage>{1,2}",
15984 media: "visual",
15985 inherited: false,
15986 animationType: "lpc",
15987 percentages: "referToDimensionOfBorderBox",
15988 groups: [
15989 "CSS Backgrounds and Borders"
15990 ],
15991 initial: "0",
15992 appliesto: "allElementsUAsNotRequiredWhenCollapse",
15993 computed: "twoAbsoluteLengthOrPercentages",
15994 order: "uniqueOrder",
15995 alsoAppliesTo: [
15996 "::first-letter"
15997 ],
15998 status: "standard",
15999 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-right-radius"
16000},
16001 "border-bottom-style": {
16002 syntax: "<line-style>",
16003 media: "visual",
16004 inherited: false,
16005 animationType: "discrete",
16006 percentages: "no",
16007 groups: [
16008 "CSS Backgrounds and Borders"
16009 ],
16010 initial: "none",
16011 appliesto: "allElements",
16012 computed: "asSpecified",
16013 order: "uniqueOrder",
16014 alsoAppliesTo: [
16015 "::first-letter"
16016 ],
16017 status: "standard",
16018 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-style"
16019},
16020 "border-bottom-width": {
16021 syntax: "<line-width>",
16022 media: "visual",
16023 inherited: false,
16024 animationType: "length",
16025 percentages: "no",
16026 groups: [
16027 "CSS Backgrounds and Borders"
16028 ],
16029 initial: "medium",
16030 appliesto: "allElements",
16031 computed: "absoluteLengthOr0IfBorderBottomStyleNoneOrHidden",
16032 order: "uniqueOrder",
16033 alsoAppliesTo: [
16034 "::first-letter"
16035 ],
16036 status: "standard",
16037 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-bottom-width"
16038},
16039 "border-collapse": {
16040 syntax: "collapse | separate",
16041 media: "visual",
16042 inherited: true,
16043 animationType: "discrete",
16044 percentages: "no",
16045 groups: [
16046 "CSS Table"
16047 ],
16048 initial: "separate",
16049 appliesto: "tableElements",
16050 computed: "asSpecified",
16051 order: "uniqueOrder",
16052 status: "standard",
16053 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-collapse"
16054},
16055 "border-color": {
16056 syntax: "<color>{1,4}",
16057 media: "visual",
16058 inherited: false,
16059 animationType: [
16060 "border-bottom-color",
16061 "border-left-color",
16062 "border-right-color",
16063 "border-top-color"
16064 ],
16065 percentages: "no",
16066 groups: [
16067 "CSS Backgrounds and Borders"
16068 ],
16069 initial: [
16070 "border-top-color",
16071 "border-right-color",
16072 "border-bottom-color",
16073 "border-left-color"
16074 ],
16075 appliesto: "allElements",
16076 computed: [
16077 "border-bottom-color",
16078 "border-left-color",
16079 "border-right-color",
16080 "border-top-color"
16081 ],
16082 order: "uniqueOrder",
16083 alsoAppliesTo: [
16084 "::first-letter"
16085 ],
16086 status: "standard",
16087 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-color"
16088},
16089 "border-end-end-radius": {
16090 syntax: "<length-percentage>{1,2}",
16091 media: "visual",
16092 inherited: false,
16093 animationType: "lpc",
16094 percentages: "referToDimensionOfBorderBox",
16095 groups: [
16096 "CSS Logical Properties"
16097 ],
16098 initial: "0",
16099 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16100 computed: "twoAbsoluteLengthOrPercentages",
16101 order: "uniqueOrder",
16102 alsoAppliesTo: [
16103 "::first-letter"
16104 ],
16105 status: "standard",
16106 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-end-end-radius"
16107},
16108 "border-end-start-radius": {
16109 syntax: "<length-percentage>{1,2}",
16110 media: "visual",
16111 inherited: false,
16112 animationType: "lpc",
16113 percentages: "referToDimensionOfBorderBox",
16114 groups: [
16115 "CSS Logical Properties"
16116 ],
16117 initial: "0",
16118 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16119 computed: "twoAbsoluteLengthOrPercentages",
16120 order: "uniqueOrder",
16121 alsoAppliesTo: [
16122 "::first-letter"
16123 ],
16124 status: "standard",
16125 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-end-start-radius"
16126},
16127 "border-image": {
16128 syntax: "<'border-image-source'> || <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]? || <'border-image-repeat'>",
16129 media: "visual",
16130 inherited: false,
16131 animationType: "discrete",
16132 percentages: [
16133 "border-image-slice",
16134 "border-image-width"
16135 ],
16136 groups: [
16137 "CSS Backgrounds and Borders"
16138 ],
16139 initial: [
16140 "border-image-source",
16141 "border-image-slice",
16142 "border-image-width",
16143 "border-image-outset",
16144 "border-image-repeat"
16145 ],
16146 appliesto: "allElementsExceptTableElementsWhenCollapse",
16147 computed: [
16148 "border-image-outset",
16149 "border-image-repeat",
16150 "border-image-slice",
16151 "border-image-source",
16152 "border-image-width"
16153 ],
16154 order: "uniqueOrder",
16155 alsoAppliesTo: [
16156 "::first-letter"
16157 ],
16158 status: "standard",
16159 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image"
16160},
16161 "border-image-outset": {
16162 syntax: "[ <length> | <number> ]{1,4}",
16163 media: "visual",
16164 inherited: false,
16165 animationType: "byComputedValueType",
16166 percentages: "no",
16167 groups: [
16168 "CSS Backgrounds and Borders"
16169 ],
16170 initial: "0",
16171 appliesto: "allElementsExceptTableElementsWhenCollapse",
16172 computed: "asSpecifiedRelativeToAbsoluteLengths",
16173 order: "uniqueOrder",
16174 alsoAppliesTo: [
16175 "::first-letter"
16176 ],
16177 status: "standard",
16178 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-outset"
16179},
16180 "border-image-repeat": {
16181 syntax: "[ stretch | repeat | round | space ]{1,2}",
16182 media: "visual",
16183 inherited: false,
16184 animationType: "discrete",
16185 percentages: "no",
16186 groups: [
16187 "CSS Backgrounds and Borders"
16188 ],
16189 initial: "stretch",
16190 appliesto: "allElementsExceptTableElementsWhenCollapse",
16191 computed: "asSpecified",
16192 order: "uniqueOrder",
16193 alsoAppliesTo: [
16194 "::first-letter"
16195 ],
16196 status: "standard",
16197 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-repeat"
16198},
16199 "border-image-slice": {
16200 syntax: "<number-percentage>{1,4} && fill?",
16201 media: "visual",
16202 inherited: false,
16203 animationType: "byComputedValueType",
16204 percentages: "referToSizeOfBorderImage",
16205 groups: [
16206 "CSS Backgrounds and Borders"
16207 ],
16208 initial: "100%",
16209 appliesto: "allElementsExceptTableElementsWhenCollapse",
16210 computed: "oneToFourPercentagesOrAbsoluteLengthsPlusFill",
16211 order: "percentagesOrLengthsFollowedByFill",
16212 alsoAppliesTo: [
16213 "::first-letter"
16214 ],
16215 status: "standard",
16216 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-slice"
16217},
16218 "border-image-source": {
16219 syntax: "none | <image>",
16220 media: "visual",
16221 inherited: false,
16222 animationType: "discrete",
16223 percentages: "no",
16224 groups: [
16225 "CSS Backgrounds and Borders"
16226 ],
16227 initial: "none",
16228 appliesto: "allElementsExceptTableElementsWhenCollapse",
16229 computed: "noneOrImageWithAbsoluteURI",
16230 order: "uniqueOrder",
16231 alsoAppliesTo: [
16232 "::first-letter"
16233 ],
16234 status: "standard",
16235 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-source"
16236},
16237 "border-image-width": {
16238 syntax: "[ <length-percentage> | <number> | auto ]{1,4}",
16239 media: "visual",
16240 inherited: false,
16241 animationType: "byComputedValueType",
16242 percentages: "referToWidthOrHeightOfBorderImageArea",
16243 groups: [
16244 "CSS Backgrounds and Borders"
16245 ],
16246 initial: "1",
16247 appliesto: "allElementsExceptTableElementsWhenCollapse",
16248 computed: "asSpecifiedRelativeToAbsoluteLengths",
16249 order: "uniqueOrder",
16250 alsoAppliesTo: [
16251 "::first-letter"
16252 ],
16253 status: "standard",
16254 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-image-width"
16255},
16256 "border-inline": {
16257 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
16258 media: "visual",
16259 inherited: false,
16260 animationType: "discrete",
16261 percentages: "no",
16262 groups: [
16263 "CSS Logical Properties"
16264 ],
16265 initial: [
16266 "border-top-width",
16267 "border-top-style",
16268 "border-top-color"
16269 ],
16270 appliesto: "allElements",
16271 computed: [
16272 "border-top-width",
16273 "border-top-style",
16274 "border-top-color"
16275 ],
16276 order: "uniqueOrder",
16277 status: "standard",
16278 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline"
16279},
16280 "border-inline-end": {
16281 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
16282 media: "visual",
16283 inherited: false,
16284 animationType: [
16285 "border-inline-end-color",
16286 "border-inline-end-style",
16287 "border-inline-end-width"
16288 ],
16289 percentages: "no",
16290 groups: [
16291 "CSS Logical Properties"
16292 ],
16293 initial: [
16294 "border-width",
16295 "border-style",
16296 "color"
16297 ],
16298 appliesto: "allElements",
16299 computed: [
16300 "border-width",
16301 "border-style",
16302 "border-inline-end-color"
16303 ],
16304 order: "uniqueOrder",
16305 status: "standard",
16306 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end"
16307},
16308 "border-inline-color": {
16309 syntax: "<'border-top-color'>{1,2}",
16310 media: "visual",
16311 inherited: false,
16312 animationType: "discrete",
16313 percentages: "no",
16314 groups: [
16315 "CSS Logical Properties"
16316 ],
16317 initial: "currentcolor",
16318 appliesto: "allElements",
16319 computed: "computedColor",
16320 order: "uniqueOrder",
16321 status: "standard",
16322 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-color"
16323},
16324 "border-inline-style": {
16325 syntax: "<'border-top-style'>",
16326 media: "visual",
16327 inherited: false,
16328 animationType: "discrete",
16329 percentages: "no",
16330 groups: [
16331 "CSS Logical Properties"
16332 ],
16333 initial: "none",
16334 appliesto: "allElements",
16335 computed: "asSpecified",
16336 order: "uniqueOrder",
16337 status: "standard",
16338 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-style"
16339},
16340 "border-inline-width": {
16341 syntax: "<'border-top-width'>",
16342 media: "visual",
16343 inherited: false,
16344 animationType: "discrete",
16345 percentages: "logicalWidthOfContainingBlock",
16346 groups: [
16347 "CSS Logical Properties"
16348 ],
16349 initial: "medium",
16350 appliesto: "allElements",
16351 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
16352 order: "uniqueOrder",
16353 status: "standard",
16354 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-width"
16355},
16356 "border-inline-end-color": {
16357 syntax: "<'border-top-color'>",
16358 media: "visual",
16359 inherited: false,
16360 animationType: "color",
16361 percentages: "no",
16362 groups: [
16363 "CSS Logical Properties"
16364 ],
16365 initial: "currentcolor",
16366 appliesto: "allElements",
16367 computed: "computedColor",
16368 order: "uniqueOrder",
16369 status: "standard",
16370 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-color"
16371},
16372 "border-inline-end-style": {
16373 syntax: "<'border-top-style'>",
16374 media: "visual",
16375 inherited: false,
16376 animationType: "discrete",
16377 percentages: "no",
16378 groups: [
16379 "CSS Logical Properties"
16380 ],
16381 initial: "none",
16382 appliesto: "allElements",
16383 computed: "asSpecified",
16384 order: "uniqueOrder",
16385 status: "standard",
16386 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-style"
16387},
16388 "border-inline-end-width": {
16389 syntax: "<'border-top-width'>",
16390 media: "visual",
16391 inherited: false,
16392 animationType: "length",
16393 percentages: "logicalWidthOfContainingBlock",
16394 groups: [
16395 "CSS Logical Properties"
16396 ],
16397 initial: "medium",
16398 appliesto: "allElements",
16399 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
16400 order: "uniqueOrder",
16401 status: "standard",
16402 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-end-width"
16403},
16404 "border-inline-start": {
16405 syntax: "<'border-top-width'> || <'border-top-style'> || <'color'>",
16406 media: "visual",
16407 inherited: false,
16408 animationType: [
16409 "border-inline-start-color",
16410 "border-inline-start-style",
16411 "border-inline-start-width"
16412 ],
16413 percentages: "no",
16414 groups: [
16415 "CSS Logical Properties"
16416 ],
16417 initial: [
16418 "border-width",
16419 "border-style",
16420 "color"
16421 ],
16422 appliesto: "allElements",
16423 computed: [
16424 "border-width",
16425 "border-style",
16426 "border-inline-start-color"
16427 ],
16428 order: "uniqueOrder",
16429 status: "standard",
16430 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start"
16431},
16432 "border-inline-start-color": {
16433 syntax: "<'border-top-color'>",
16434 media: "visual",
16435 inherited: false,
16436 animationType: "color",
16437 percentages: "no",
16438 groups: [
16439 "CSS Logical Properties"
16440 ],
16441 initial: "currentcolor",
16442 appliesto: "allElements",
16443 computed: "computedColor",
16444 order: "uniqueOrder",
16445 status: "standard",
16446 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-color"
16447},
16448 "border-inline-start-style": {
16449 syntax: "<'border-top-style'>",
16450 media: "visual",
16451 inherited: false,
16452 animationType: "discrete",
16453 percentages: "no",
16454 groups: [
16455 "CSS Logical Properties"
16456 ],
16457 initial: "none",
16458 appliesto: "allElements",
16459 computed: "asSpecified",
16460 order: "uniqueOrder",
16461 status: "standard",
16462 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-style"
16463},
16464 "border-inline-start-width": {
16465 syntax: "<'border-top-width'>",
16466 media: "visual",
16467 inherited: false,
16468 animationType: "length",
16469 percentages: "logicalWidthOfContainingBlock",
16470 groups: [
16471 "CSS Logical Properties"
16472 ],
16473 initial: "medium",
16474 appliesto: "allElements",
16475 computed: "absoluteLengthZeroIfBorderStyleNoneOrHidden",
16476 order: "uniqueOrder",
16477 status: "standard",
16478 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-inline-start-width"
16479},
16480 "border-left": {
16481 syntax: "<line-width> || <line-style> || <color>",
16482 media: "visual",
16483 inherited: false,
16484 animationType: [
16485 "border-left-color",
16486 "border-left-style",
16487 "border-left-width"
16488 ],
16489 percentages: "no",
16490 groups: [
16491 "CSS Backgrounds and Borders"
16492 ],
16493 initial: [
16494 "border-left-width",
16495 "border-left-style",
16496 "border-left-color"
16497 ],
16498 appliesto: "allElements",
16499 computed: [
16500 "border-left-width",
16501 "border-left-style",
16502 "border-left-color"
16503 ],
16504 order: "orderOfAppearance",
16505 alsoAppliesTo: [
16506 "::first-letter"
16507 ],
16508 status: "standard",
16509 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left"
16510},
16511 "border-left-color": {
16512 syntax: "<color>",
16513 media: "visual",
16514 inherited: false,
16515 animationType: "color",
16516 percentages: "no",
16517 groups: [
16518 "CSS Backgrounds and Borders"
16519 ],
16520 initial: "currentcolor",
16521 appliesto: "allElements",
16522 computed: "computedColor",
16523 order: "uniqueOrder",
16524 alsoAppliesTo: [
16525 "::first-letter"
16526 ],
16527 status: "standard",
16528 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-color"
16529},
16530 "border-left-style": {
16531 syntax: "<line-style>",
16532 media: "visual",
16533 inherited: false,
16534 animationType: "discrete",
16535 percentages: "no",
16536 groups: [
16537 "CSS Backgrounds and Borders"
16538 ],
16539 initial: "none",
16540 appliesto: "allElements",
16541 computed: "asSpecified",
16542 order: "uniqueOrder",
16543 alsoAppliesTo: [
16544 "::first-letter"
16545 ],
16546 status: "standard",
16547 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-style"
16548},
16549 "border-left-width": {
16550 syntax: "<line-width>",
16551 media: "visual",
16552 inherited: false,
16553 animationType: "length",
16554 percentages: "no",
16555 groups: [
16556 "CSS Backgrounds and Borders"
16557 ],
16558 initial: "medium",
16559 appliesto: "allElements",
16560 computed: "absoluteLengthOr0IfBorderLeftStyleNoneOrHidden",
16561 order: "uniqueOrder",
16562 alsoAppliesTo: [
16563 "::first-letter"
16564 ],
16565 status: "standard",
16566 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-left-width"
16567},
16568 "border-radius": {
16569 syntax: "<length-percentage>{1,4} [ / <length-percentage>{1,4} ]?",
16570 media: "visual",
16571 inherited: false,
16572 animationType: [
16573 "border-top-left-radius",
16574 "border-top-right-radius",
16575 "border-bottom-right-radius",
16576 "border-bottom-left-radius"
16577 ],
16578 percentages: "referToDimensionOfBorderBox",
16579 groups: [
16580 "CSS Backgrounds and Borders"
16581 ],
16582 initial: [
16583 "border-top-left-radius",
16584 "border-top-right-radius",
16585 "border-bottom-right-radius",
16586 "border-bottom-left-radius"
16587 ],
16588 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16589 computed: [
16590 "border-bottom-left-radius",
16591 "border-bottom-right-radius",
16592 "border-top-left-radius",
16593 "border-top-right-radius"
16594 ],
16595 order: "uniqueOrder",
16596 alsoAppliesTo: [
16597 "::first-letter"
16598 ],
16599 status: "standard",
16600 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-radius"
16601},
16602 "border-right": {
16603 syntax: "<line-width> || <line-style> || <color>",
16604 media: "visual",
16605 inherited: false,
16606 animationType: [
16607 "border-right-color",
16608 "border-right-style",
16609 "border-right-width"
16610 ],
16611 percentages: "no",
16612 groups: [
16613 "CSS Backgrounds and Borders"
16614 ],
16615 initial: [
16616 "border-right-width",
16617 "border-right-style",
16618 "border-right-color"
16619 ],
16620 appliesto: "allElements",
16621 computed: [
16622 "border-right-width",
16623 "border-right-style",
16624 "border-right-color"
16625 ],
16626 order: "orderOfAppearance",
16627 alsoAppliesTo: [
16628 "::first-letter"
16629 ],
16630 status: "standard",
16631 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right"
16632},
16633 "border-right-color": {
16634 syntax: "<color>",
16635 media: "visual",
16636 inherited: false,
16637 animationType: "color",
16638 percentages: "no",
16639 groups: [
16640 "CSS Backgrounds and Borders"
16641 ],
16642 initial: "currentcolor",
16643 appliesto: "allElements",
16644 computed: "computedColor",
16645 order: "uniqueOrder",
16646 alsoAppliesTo: [
16647 "::first-letter"
16648 ],
16649 status: "standard",
16650 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-color"
16651},
16652 "border-right-style": {
16653 syntax: "<line-style>",
16654 media: "visual",
16655 inherited: false,
16656 animationType: "discrete",
16657 percentages: "no",
16658 groups: [
16659 "CSS Backgrounds and Borders"
16660 ],
16661 initial: "none",
16662 appliesto: "allElements",
16663 computed: "asSpecified",
16664 order: "uniqueOrder",
16665 alsoAppliesTo: [
16666 "::first-letter"
16667 ],
16668 status: "standard",
16669 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-style"
16670},
16671 "border-right-width": {
16672 syntax: "<line-width>",
16673 media: "visual",
16674 inherited: false,
16675 animationType: "length",
16676 percentages: "no",
16677 groups: [
16678 "CSS Backgrounds and Borders"
16679 ],
16680 initial: "medium",
16681 appliesto: "allElements",
16682 computed: "absoluteLengthOr0IfBorderRightStyleNoneOrHidden",
16683 order: "uniqueOrder",
16684 alsoAppliesTo: [
16685 "::first-letter"
16686 ],
16687 status: "standard",
16688 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-right-width"
16689},
16690 "border-spacing": {
16691 syntax: "<length> <length>?",
16692 media: "visual",
16693 inherited: true,
16694 animationType: "discrete",
16695 percentages: "no",
16696 groups: [
16697 "CSS Table"
16698 ],
16699 initial: "0",
16700 appliesto: "tableElements",
16701 computed: "twoAbsoluteLengths",
16702 order: "uniqueOrder",
16703 status: "standard",
16704 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-spacing"
16705},
16706 "border-start-end-radius": {
16707 syntax: "<length-percentage>{1,2}",
16708 media: "visual",
16709 inherited: false,
16710 animationType: "lpc",
16711 percentages: "referToDimensionOfBorderBox",
16712 groups: [
16713 "CSS Logical Properties"
16714 ],
16715 initial: "0",
16716 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16717 computed: "twoAbsoluteLengthOrPercentages",
16718 order: "uniqueOrder",
16719 alsoAppliesTo: [
16720 "::first-letter"
16721 ],
16722 status: "standard",
16723 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-start-end-radius"
16724},
16725 "border-start-start-radius": {
16726 syntax: "<length-percentage>{1,2}",
16727 media: "visual",
16728 inherited: false,
16729 animationType: "lpc",
16730 percentages: "referToDimensionOfBorderBox",
16731 groups: [
16732 "CSS Logical Properties"
16733 ],
16734 initial: "0",
16735 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16736 computed: "twoAbsoluteLengthOrPercentages",
16737 order: "uniqueOrder",
16738 alsoAppliesTo: [
16739 "::first-letter"
16740 ],
16741 status: "standard",
16742 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-start-start-radius"
16743},
16744 "border-style": {
16745 syntax: "<line-style>{1,4}",
16746 media: "visual",
16747 inherited: false,
16748 animationType: "discrete",
16749 percentages: "no",
16750 groups: [
16751 "CSS Backgrounds and Borders"
16752 ],
16753 initial: [
16754 "border-top-style",
16755 "border-right-style",
16756 "border-bottom-style",
16757 "border-left-style"
16758 ],
16759 appliesto: "allElements",
16760 computed: [
16761 "border-bottom-style",
16762 "border-left-style",
16763 "border-right-style",
16764 "border-top-style"
16765 ],
16766 order: "uniqueOrder",
16767 alsoAppliesTo: [
16768 "::first-letter"
16769 ],
16770 status: "standard",
16771 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-style"
16772},
16773 "border-top": {
16774 syntax: "<line-width> || <line-style> || <color>",
16775 media: "visual",
16776 inherited: false,
16777 animationType: [
16778 "border-top-color",
16779 "border-top-style",
16780 "border-top-width"
16781 ],
16782 percentages: "no",
16783 groups: [
16784 "CSS Backgrounds and Borders"
16785 ],
16786 initial: [
16787 "border-top-width",
16788 "border-top-style",
16789 "border-top-color"
16790 ],
16791 appliesto: "allElements",
16792 computed: [
16793 "border-top-width",
16794 "border-top-style",
16795 "border-top-color"
16796 ],
16797 order: "orderOfAppearance",
16798 alsoAppliesTo: [
16799 "::first-letter"
16800 ],
16801 status: "standard",
16802 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top"
16803},
16804 "border-top-color": {
16805 syntax: "<color>",
16806 media: "visual",
16807 inherited: false,
16808 animationType: "color",
16809 percentages: "no",
16810 groups: [
16811 "CSS Backgrounds and Borders"
16812 ],
16813 initial: "currentcolor",
16814 appliesto: "allElements",
16815 computed: "computedColor",
16816 order: "uniqueOrder",
16817 alsoAppliesTo: [
16818 "::first-letter"
16819 ],
16820 status: "standard",
16821 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-color"
16822},
16823 "border-top-left-radius": {
16824 syntax: "<length-percentage>{1,2}",
16825 media: "visual",
16826 inherited: false,
16827 animationType: "lpc",
16828 percentages: "referToDimensionOfBorderBox",
16829 groups: [
16830 "CSS Backgrounds and Borders"
16831 ],
16832 initial: "0",
16833 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16834 computed: "twoAbsoluteLengthOrPercentages",
16835 order: "uniqueOrder",
16836 alsoAppliesTo: [
16837 "::first-letter"
16838 ],
16839 status: "standard",
16840 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-left-radius"
16841},
16842 "border-top-right-radius": {
16843 syntax: "<length-percentage>{1,2}",
16844 media: "visual",
16845 inherited: false,
16846 animationType: "lpc",
16847 percentages: "referToDimensionOfBorderBox",
16848 groups: [
16849 "CSS Backgrounds and Borders"
16850 ],
16851 initial: "0",
16852 appliesto: "allElementsUAsNotRequiredWhenCollapse",
16853 computed: "twoAbsoluteLengthOrPercentages",
16854 order: "uniqueOrder",
16855 alsoAppliesTo: [
16856 "::first-letter"
16857 ],
16858 status: "standard",
16859 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-right-radius"
16860},
16861 "border-top-style": {
16862 syntax: "<line-style>",
16863 media: "visual",
16864 inherited: false,
16865 animationType: "discrete",
16866 percentages: "no",
16867 groups: [
16868 "CSS Backgrounds and Borders"
16869 ],
16870 initial: "none",
16871 appliesto: "allElements",
16872 computed: "asSpecified",
16873 order: "uniqueOrder",
16874 alsoAppliesTo: [
16875 "::first-letter"
16876 ],
16877 status: "standard",
16878 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-style"
16879},
16880 "border-top-width": {
16881 syntax: "<line-width>",
16882 media: "visual",
16883 inherited: false,
16884 animationType: "length",
16885 percentages: "no",
16886 groups: [
16887 "CSS Backgrounds and Borders"
16888 ],
16889 initial: "medium",
16890 appliesto: "allElements",
16891 computed: "absoluteLengthOr0IfBorderTopStyleNoneOrHidden",
16892 order: "uniqueOrder",
16893 alsoAppliesTo: [
16894 "::first-letter"
16895 ],
16896 status: "standard",
16897 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-top-width"
16898},
16899 "border-width": {
16900 syntax: "<line-width>{1,4}",
16901 media: "visual",
16902 inherited: false,
16903 animationType: [
16904 "border-bottom-width",
16905 "border-left-width",
16906 "border-right-width",
16907 "border-top-width"
16908 ],
16909 percentages: "no",
16910 groups: [
16911 "CSS Backgrounds and Borders"
16912 ],
16913 initial: [
16914 "border-top-width",
16915 "border-right-width",
16916 "border-bottom-width",
16917 "border-left-width"
16918 ],
16919 appliesto: "allElements",
16920 computed: [
16921 "border-bottom-width",
16922 "border-left-width",
16923 "border-right-width",
16924 "border-top-width"
16925 ],
16926 order: "uniqueOrder",
16927 alsoAppliesTo: [
16928 "::first-letter"
16929 ],
16930 status: "standard",
16931 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/border-width"
16932},
16933 bottom: bottom,
16934 "box-align": {
16935 syntax: "start | center | end | baseline | stretch",
16936 media: "visual",
16937 inherited: false,
16938 animationType: "discrete",
16939 percentages: "no",
16940 groups: [
16941 "Mozilla Extensions",
16942 "WebKit Extensions"
16943 ],
16944 initial: "stretch",
16945 appliesto: "elementsWithDisplayBoxOrInlineBox",
16946 computed: "asSpecified",
16947 order: "uniqueOrder",
16948 status: "nonstandard",
16949 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-align"
16950},
16951 "box-decoration-break": {
16952 syntax: "slice | clone",
16953 media: "visual",
16954 inherited: false,
16955 animationType: "discrete",
16956 percentages: "no",
16957 groups: [
16958 "CSS Fragmentation"
16959 ],
16960 initial: "slice",
16961 appliesto: "allElements",
16962 computed: "asSpecified",
16963 order: "uniqueOrder",
16964 status: "standard",
16965 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-decoration-break"
16966},
16967 "box-direction": {
16968 syntax: "normal | reverse | inherit",
16969 media: "visual",
16970 inherited: false,
16971 animationType: "discrete",
16972 percentages: "no",
16973 groups: [
16974 "Mozilla Extensions",
16975 "WebKit Extensions"
16976 ],
16977 initial: "normal",
16978 appliesto: "elementsWithDisplayBoxOrInlineBox",
16979 computed: "asSpecified",
16980 order: "uniqueOrder",
16981 status: "nonstandard",
16982 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-direction"
16983},
16984 "box-flex": {
16985 syntax: "<number>",
16986 media: "visual",
16987 inherited: false,
16988 animationType: "discrete",
16989 percentages: "no",
16990 groups: [
16991 "Mozilla Extensions",
16992 "WebKit Extensions"
16993 ],
16994 initial: "0",
16995 appliesto: "directChildrenOfElementsWithDisplayMozBoxMozInlineBox",
16996 computed: "asSpecified",
16997 order: "uniqueOrder",
16998 status: "nonstandard",
16999 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-flex"
17000},
17001 "box-flex-group": {
17002 syntax: "<integer>",
17003 media: "visual",
17004 inherited: false,
17005 animationType: "discrete",
17006 percentages: "no",
17007 groups: [
17008 "Mozilla Extensions",
17009 "WebKit Extensions"
17010 ],
17011 initial: "1",
17012 appliesto: "inFlowChildrenOfBoxElements",
17013 computed: "asSpecified",
17014 order: "uniqueOrder",
17015 status: "nonstandard",
17016 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-flex-group"
17017},
17018 "box-lines": {
17019 syntax: "single | multiple",
17020 media: "visual",
17021 inherited: false,
17022 animationType: "discrete",
17023 percentages: "no",
17024 groups: [
17025 "Mozilla Extensions",
17026 "WebKit Extensions"
17027 ],
17028 initial: "single",
17029 appliesto: "boxElements",
17030 computed: "asSpecified",
17031 order: "uniqueOrder",
17032 status: "nonstandard",
17033 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-lines"
17034},
17035 "box-ordinal-group": {
17036 syntax: "<integer>",
17037 media: "visual",
17038 inherited: false,
17039 animationType: "discrete",
17040 percentages: "no",
17041 groups: [
17042 "Mozilla Extensions",
17043 "WebKit Extensions"
17044 ],
17045 initial: "1",
17046 appliesto: "childrenOfBoxElements",
17047 computed: "asSpecified",
17048 order: "uniqueOrder",
17049 status: "nonstandard",
17050 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-ordinal-group"
17051},
17052 "box-orient": {
17053 syntax: "horizontal | vertical | inline-axis | block-axis | inherit",
17054 media: "visual",
17055 inherited: false,
17056 animationType: "discrete",
17057 percentages: "no",
17058 groups: [
17059 "Mozilla Extensions",
17060 "WebKit Extensions"
17061 ],
17062 initial: "inlineAxisHorizontalInXUL",
17063 appliesto: "elementsWithDisplayBoxOrInlineBox",
17064 computed: "asSpecified",
17065 order: "uniqueOrder",
17066 status: "nonstandard",
17067 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-orient"
17068},
17069 "box-pack": {
17070 syntax: "start | center | end | justify",
17071 media: "visual",
17072 inherited: false,
17073 animationType: "discrete",
17074 percentages: "no",
17075 groups: [
17076 "Mozilla Extensions",
17077 "WebKit Extensions"
17078 ],
17079 initial: "start",
17080 appliesto: "elementsWithDisplayMozBoxMozInlineBox",
17081 computed: "asSpecified",
17082 order: "uniqueOrder",
17083 status: "nonstandard",
17084 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-pack"
17085},
17086 "box-shadow": {
17087 syntax: "none | <shadow>#",
17088 media: "visual",
17089 inherited: false,
17090 animationType: "shadowList",
17091 percentages: "no",
17092 groups: [
17093 "CSS Backgrounds and Borders"
17094 ],
17095 initial: "none",
17096 appliesto: "allElements",
17097 computed: "absoluteLengthsSpecifiedColorAsSpecified",
17098 order: "uniqueOrder",
17099 alsoAppliesTo: [
17100 "::first-letter"
17101 ],
17102 status: "standard",
17103 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-shadow"
17104},
17105 "box-sizing": {
17106 syntax: "content-box | border-box",
17107 media: "visual",
17108 inherited: false,
17109 animationType: "discrete",
17110 percentages: "no",
17111 groups: [
17112 "CSS Basic User Interface"
17113 ],
17114 initial: "content-box",
17115 appliesto: "allElementsAcceptingWidthOrHeight",
17116 computed: "asSpecified",
17117 order: "uniqueOrder",
17118 status: "standard",
17119 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/box-sizing"
17120},
17121 "break-after": {
17122 syntax: "auto | avoid | always | all | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region",
17123 media: "visual",
17124 inherited: false,
17125 animationType: "discrete",
17126 percentages: "no",
17127 groups: [
17128 "CSS Fragmentation"
17129 ],
17130 initial: "auto",
17131 appliesto: "blockLevelElements",
17132 computed: "asSpecified",
17133 order: "uniqueOrder",
17134 status: "standard",
17135 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-after"
17136},
17137 "break-before": {
17138 syntax: "auto | avoid | always | all | avoid-page | page | left | right | recto | verso | avoid-column | column | avoid-region | region",
17139 media: "visual",
17140 inherited: false,
17141 animationType: "discrete",
17142 percentages: "no",
17143 groups: [
17144 "CSS Fragmentation"
17145 ],
17146 initial: "auto",
17147 appliesto: "blockLevelElements",
17148 computed: "asSpecified",
17149 order: "uniqueOrder",
17150 status: "standard",
17151 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-before"
17152},
17153 "break-inside": {
17154 syntax: "auto | avoid | avoid-page | avoid-column | avoid-region",
17155 media: "visual",
17156 inherited: false,
17157 animationType: "discrete",
17158 percentages: "no",
17159 groups: [
17160 "CSS Fragmentation"
17161 ],
17162 initial: "auto",
17163 appliesto: "blockLevelElements",
17164 computed: "asSpecified",
17165 order: "uniqueOrder",
17166 status: "standard",
17167 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/break-inside"
17168},
17169 "caption-side": {
17170 syntax: "top | bottom | block-start | block-end | inline-start | inline-end",
17171 media: "visual",
17172 inherited: true,
17173 animationType: "discrete",
17174 percentages: "no",
17175 groups: [
17176 "CSS Table"
17177 ],
17178 initial: "top",
17179 appliesto: "tableCaptionElements",
17180 computed: "asSpecified",
17181 order: "uniqueOrder",
17182 status: "standard",
17183 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/caption-side"
17184},
17185 "caret-color": {
17186 syntax: "auto | <color>",
17187 media: "interactive",
17188 inherited: true,
17189 animationType: "color",
17190 percentages: "no",
17191 groups: [
17192 "CSS Basic User Interface"
17193 ],
17194 initial: "auto",
17195 appliesto: "allElements",
17196 computed: "asAutoOrColor",
17197 order: "perGrammar",
17198 status: "standard",
17199 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/caret-color"
17200},
17201 clear: clear,
17202 clip: clip,
17203 "clip-path": {
17204 syntax: "<clip-source> | [ <basic-shape> || <geometry-box> ] | none",
17205 media: "visual",
17206 inherited: false,
17207 animationType: "basicShapeOtherwiseNo",
17208 percentages: "referToReferenceBoxWhenSpecifiedOtherwiseBorderBox",
17209 groups: [
17210 "CSS Masking"
17211 ],
17212 initial: "none",
17213 appliesto: "allElementsSVGContainerElements",
17214 computed: "asSpecifiedURLsAbsolute",
17215 order: "uniqueOrder",
17216 status: "standard",
17217 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/clip-path"
17218},
17219 color: color$1,
17220 "color-adjust": {
17221 syntax: "economy | exact",
17222 media: "visual",
17223 inherited: true,
17224 animationType: "discrete",
17225 percentages: "no",
17226 groups: [
17227 "CSS Color"
17228 ],
17229 initial: "economy",
17230 appliesto: "allElements",
17231 computed: "asSpecified",
17232 order: "perGrammar",
17233 status: "standard",
17234 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/color-adjust"
17235},
17236 "column-count": {
17237 syntax: "<integer> | auto",
17238 media: "visual",
17239 inherited: false,
17240 animationType: "integer",
17241 percentages: "no",
17242 groups: [
17243 "CSS Columns"
17244 ],
17245 initial: "auto",
17246 appliesto: "blockContainersExceptTableWrappers",
17247 computed: "asSpecified",
17248 order: "perGrammar",
17249 status: "standard",
17250 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-count"
17251},
17252 "column-fill": {
17253 syntax: "auto | balance | balance-all",
17254 media: "visualInContinuousMediaNoEffectInOverflowColumns",
17255 inherited: false,
17256 animationType: "discrete",
17257 percentages: "no",
17258 groups: [
17259 "CSS Columns"
17260 ],
17261 initial: "balance",
17262 appliesto: "multicolElements",
17263 computed: "asSpecified",
17264 order: "perGrammar",
17265 status: "standard",
17266 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-fill"
17267},
17268 "column-gap": {
17269 syntax: "normal | <length-percentage>",
17270 media: "visual",
17271 inherited: false,
17272 animationType: "lpc",
17273 percentages: "referToDimensionOfContentArea",
17274 groups: [
17275 "CSS Box Alignment"
17276 ],
17277 initial: "normal",
17278 appliesto: "multiColumnElementsFlexContainersGridContainers",
17279 computed: "asSpecifiedWithLengthsAbsoluteAndNormalComputingToZeroExceptMultiColumn",
17280 order: "perGrammar",
17281 status: "standard",
17282 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-gap"
17283},
17284 "column-rule": {
17285 syntax: "<'column-rule-width'> || <'column-rule-style'> || <'column-rule-color'>",
17286 media: "visual",
17287 inherited: false,
17288 animationType: [
17289 "column-rule-color",
17290 "column-rule-style",
17291 "column-rule-width"
17292 ],
17293 percentages: "no",
17294 groups: [
17295 "CSS Columns"
17296 ],
17297 initial: [
17298 "column-rule-width",
17299 "column-rule-style",
17300 "column-rule-color"
17301 ],
17302 appliesto: "multicolElements",
17303 computed: [
17304 "column-rule-color",
17305 "column-rule-style",
17306 "column-rule-width"
17307 ],
17308 order: "perGrammar",
17309 status: "standard",
17310 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule"
17311},
17312 "column-rule-color": {
17313 syntax: "<color>",
17314 media: "visual",
17315 inherited: false,
17316 animationType: "color",
17317 percentages: "no",
17318 groups: [
17319 "CSS Columns"
17320 ],
17321 initial: "currentcolor",
17322 appliesto: "multicolElements",
17323 computed: "computedColor",
17324 order: "perGrammar",
17325 status: "standard",
17326 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-color"
17327},
17328 "column-rule-style": {
17329 syntax: "<'border-style'>",
17330 media: "visual",
17331 inherited: false,
17332 animationType: "discrete",
17333 percentages: "no",
17334 groups: [
17335 "CSS Columns"
17336 ],
17337 initial: "none",
17338 appliesto: "multicolElements",
17339 computed: "asSpecified",
17340 order: "perGrammar",
17341 status: "standard",
17342 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-style"
17343},
17344 "column-rule-width": {
17345 syntax: "<'border-width'>",
17346 media: "visual",
17347 inherited: false,
17348 animationType: "length",
17349 percentages: "no",
17350 groups: [
17351 "CSS Columns"
17352 ],
17353 initial: "medium",
17354 appliesto: "multicolElements",
17355 computed: "absoluteLength0IfColumnRuleStyleNoneOrHidden",
17356 order: "perGrammar",
17357 status: "standard",
17358 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-rule-width"
17359},
17360 "column-span": {
17361 syntax: "none | all",
17362 media: "visual",
17363 inherited: false,
17364 animationType: "discrete",
17365 percentages: "no",
17366 groups: [
17367 "CSS Columns"
17368 ],
17369 initial: "none",
17370 appliesto: "inFlowBlockLevelElements",
17371 computed: "asSpecified",
17372 order: "perGrammar",
17373 status: "standard",
17374 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-span"
17375},
17376 "column-width": {
17377 syntax: "<length> | auto",
17378 media: "visual",
17379 inherited: false,
17380 animationType: "length",
17381 percentages: "no",
17382 groups: [
17383 "CSS Columns"
17384 ],
17385 initial: "auto",
17386 appliesto: "blockContainersExceptTableWrappers",
17387 computed: "absoluteLengthZeroOrLarger",
17388 order: "perGrammar",
17389 status: "standard",
17390 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-width"
17391},
17392 columns: columns,
17393 contain: contain,
17394 content: content,
17395 "counter-increment": {
17396 syntax: "[ <custom-ident> <integer>? ]+ | none",
17397 media: "all",
17398 inherited: false,
17399 animationType: "discrete",
17400 percentages: "no",
17401 groups: [
17402 "CSS Counter Styles"
17403 ],
17404 initial: "none",
17405 appliesto: "allElements",
17406 computed: "asSpecified",
17407 order: "uniqueOrder",
17408 status: "standard",
17409 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-increment"
17410},
17411 "counter-reset": {
17412 syntax: "[ <custom-ident> <integer>? ]+ | none",
17413 media: "all",
17414 inherited: false,
17415 animationType: "discrete",
17416 percentages: "no",
17417 groups: [
17418 "CSS Counter Styles"
17419 ],
17420 initial: "none",
17421 appliesto: "allElements",
17422 computed: "asSpecified",
17423 order: "uniqueOrder",
17424 status: "standard",
17425 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-reset"
17426},
17427 "counter-set": {
17428 syntax: "[ <custom-ident> <integer>? ]+ | none",
17429 media: "all",
17430 inherited: false,
17431 animationType: "discrete",
17432 percentages: "no",
17433 groups: [
17434 "CSS Counter Styles"
17435 ],
17436 initial: "none",
17437 appliesto: "allElements",
17438 computed: "asSpecified",
17439 order: "uniqueOrder",
17440 status: "standard",
17441 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/counter-set"
17442},
17443 cursor: cursor,
17444 direction: direction,
17445 display: display,
17446 "empty-cells": {
17447 syntax: "show | hide",
17448 media: "visual",
17449 inherited: true,
17450 animationType: "discrete",
17451 percentages: "no",
17452 groups: [
17453 "CSS Table"
17454 ],
17455 initial: "show",
17456 appliesto: "tableCellElements",
17457 computed: "asSpecified",
17458 order: "uniqueOrder",
17459 status: "standard",
17460 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/empty-cells"
17461},
17462 filter: filter,
17463 flex: flex,
17464 "flex-basis": {
17465 syntax: "content | <'width'>",
17466 media: "visual",
17467 inherited: false,
17468 animationType: "lpc",
17469 percentages: "referToFlexContainersInnerMainSize",
17470 groups: [
17471 "CSS Flexible Box Layout"
17472 ],
17473 initial: "auto",
17474 appliesto: "flexItemsAndInFlowPseudos",
17475 computed: "asSpecifiedRelativeToAbsoluteLengths",
17476 order: "lengthOrPercentageBeforeKeywordIfBothPresent",
17477 status: "standard",
17478 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-basis"
17479},
17480 "flex-direction": {
17481 syntax: "row | row-reverse | column | column-reverse",
17482 media: "visual",
17483 inherited: false,
17484 animationType: "discrete",
17485 percentages: "no",
17486 groups: [
17487 "CSS Flexible Box Layout"
17488 ],
17489 initial: "row",
17490 appliesto: "flexContainers",
17491 computed: "asSpecified",
17492 order: "uniqueOrder",
17493 status: "standard",
17494 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-direction"
17495},
17496 "flex-flow": {
17497 syntax: "<'flex-direction'> || <'flex-wrap'>",
17498 media: "visual",
17499 inherited: false,
17500 animationType: "discrete",
17501 percentages: "no",
17502 groups: [
17503 "CSS Flexible Box Layout"
17504 ],
17505 initial: [
17506 "flex-direction",
17507 "flex-wrap"
17508 ],
17509 appliesto: "flexContainers",
17510 computed: [
17511 "flex-direction",
17512 "flex-wrap"
17513 ],
17514 order: "orderOfAppearance",
17515 status: "standard",
17516 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-flow"
17517},
17518 "flex-grow": {
17519 syntax: "<number>",
17520 media: "visual",
17521 inherited: false,
17522 animationType: "number",
17523 percentages: "no",
17524 groups: [
17525 "CSS Flexible Box Layout"
17526 ],
17527 initial: "0",
17528 appliesto: "flexItemsAndInFlowPseudos",
17529 computed: "asSpecified",
17530 order: "uniqueOrder",
17531 status: "standard",
17532 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-grow"
17533},
17534 "flex-shrink": {
17535 syntax: "<number>",
17536 media: "visual",
17537 inherited: false,
17538 animationType: "number",
17539 percentages: "no",
17540 groups: [
17541 "CSS Flexible Box Layout"
17542 ],
17543 initial: "1",
17544 appliesto: "flexItemsAndInFlowPseudos",
17545 computed: "asSpecified",
17546 order: "uniqueOrder",
17547 status: "standard",
17548 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-shrink"
17549},
17550 "flex-wrap": {
17551 syntax: "nowrap | wrap | wrap-reverse",
17552 media: "visual",
17553 inherited: false,
17554 animationType: "discrete",
17555 percentages: "no",
17556 groups: [
17557 "CSS Flexible Box Layout"
17558 ],
17559 initial: "nowrap",
17560 appliesto: "flexContainers",
17561 computed: "asSpecified",
17562 order: "uniqueOrder",
17563 status: "standard",
17564 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/flex-wrap"
17565},
17566 float: float,
17567 font: font,
17568 "font-family": {
17569 syntax: "[ <family-name> | <generic-family> ]#",
17570 media: "visual",
17571 inherited: true,
17572 animationType: "discrete",
17573 percentages: "no",
17574 groups: [
17575 "CSS Fonts"
17576 ],
17577 initial: "dependsOnUserAgent",
17578 appliesto: "allElements",
17579 computed: "asSpecified",
17580 order: "uniqueOrder",
17581 alsoAppliesTo: [
17582 "::first-letter",
17583 "::first-line",
17584 "::placeholder"
17585 ],
17586 status: "standard",
17587 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-family"
17588},
17589 "font-feature-settings": {
17590 syntax: "normal | <feature-tag-value>#",
17591 media: "visual",
17592 inherited: true,
17593 animationType: "discrete",
17594 percentages: "no",
17595 groups: [
17596 "CSS Fonts"
17597 ],
17598 initial: "normal",
17599 appliesto: "allElements",
17600 computed: "asSpecified",
17601 order: "uniqueOrder",
17602 alsoAppliesTo: [
17603 "::first-letter",
17604 "::first-line",
17605 "::placeholder"
17606 ],
17607 status: "standard",
17608 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-feature-settings"
17609},
17610 "font-kerning": {
17611 syntax: "auto | normal | none",
17612 media: "visual",
17613 inherited: true,
17614 animationType: "discrete",
17615 percentages: "no",
17616 groups: [
17617 "CSS Fonts"
17618 ],
17619 initial: "auto",
17620 appliesto: "allElements",
17621 computed: "asSpecified",
17622 order: "uniqueOrder",
17623 alsoAppliesTo: [
17624 "::first-letter",
17625 "::first-line",
17626 "::placeholder"
17627 ],
17628 status: "standard",
17629 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-kerning"
17630},
17631 "font-language-override": {
17632 syntax: "normal | <string>",
17633 media: "visual",
17634 inherited: true,
17635 animationType: "discrete",
17636 percentages: "no",
17637 groups: [
17638 "CSS Fonts"
17639 ],
17640 initial: "normal",
17641 appliesto: "allElements",
17642 computed: "asSpecified",
17643 order: "uniqueOrder",
17644 alsoAppliesTo: [
17645 "::first-letter",
17646 "::first-line",
17647 "::placeholder"
17648 ],
17649 status: "standard",
17650 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-language-override"
17651},
17652 "font-optical-sizing": {
17653 syntax: "auto | none",
17654 media: "visual",
17655 inherited: true,
17656 animationType: "discrete",
17657 percentages: "no",
17658 groups: [
17659 "CSS Fonts"
17660 ],
17661 initial: "auto",
17662 appliesto: "allElements",
17663 computed: "asSpecified",
17664 order: "perGrammar",
17665 alsoAppliesTo: [
17666 "::first-letter",
17667 "::first-line",
17668 "::placeholder"
17669 ],
17670 status: "standard",
17671 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-optical-sizing"
17672},
17673 "font-variation-settings": {
17674 syntax: "normal | [ <string> <number> ]#",
17675 media: "visual",
17676 inherited: true,
17677 animationType: "transform",
17678 percentages: "no",
17679 groups: [
17680 "CSS Fonts"
17681 ],
17682 initial: "normal",
17683 appliesto: "allElements",
17684 computed: "asSpecified",
17685 order: "perGrammar",
17686 alsoAppliesTo: [
17687 "::first-letter",
17688 "::first-line",
17689 "::placeholder"
17690 ],
17691 status: "standard",
17692 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variation-settings"
17693},
17694 "font-size": {
17695 syntax: "<absolute-size> | <relative-size> | <length-percentage>",
17696 media: "visual",
17697 inherited: true,
17698 animationType: "length",
17699 percentages: "referToParentElementsFontSize",
17700 groups: [
17701 "CSS Fonts"
17702 ],
17703 initial: "medium",
17704 appliesto: "allElements",
17705 computed: "asSpecifiedRelativeToAbsoluteLengths",
17706 order: "uniqueOrder",
17707 alsoAppliesTo: [
17708 "::first-letter",
17709 "::first-line",
17710 "::placeholder"
17711 ],
17712 status: "standard",
17713 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-size"
17714},
17715 "font-size-adjust": {
17716 syntax: "none | <number>",
17717 media: "visual",
17718 inherited: true,
17719 animationType: "number",
17720 percentages: "no",
17721 groups: [
17722 "CSS Fonts"
17723 ],
17724 initial: "none",
17725 appliesto: "allElements",
17726 computed: "asSpecified",
17727 order: "uniqueOrder",
17728 alsoAppliesTo: [
17729 "::first-letter",
17730 "::first-line",
17731 "::placeholder"
17732 ],
17733 status: "standard",
17734 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-size-adjust"
17735},
17736 "font-smooth": {
17737 syntax: "auto | never | always | <absolute-size> | <length>",
17738 media: "visual",
17739 inherited: true,
17740 animationType: "discrete",
17741 percentages: "no",
17742 groups: [
17743 "CSS Fonts"
17744 ],
17745 initial: "auto",
17746 appliesto: "allElements",
17747 computed: "asSpecified",
17748 order: "uniqueOrder",
17749 status: "nonstandard",
17750 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-smooth"
17751},
17752 "font-stretch": {
17753 syntax: "<font-stretch-absolute>",
17754 media: "visual",
17755 inherited: true,
17756 animationType: "fontStretch",
17757 percentages: "no",
17758 groups: [
17759 "CSS Fonts"
17760 ],
17761 initial: "normal",
17762 appliesto: "allElements",
17763 computed: "asSpecified",
17764 order: "uniqueOrder",
17765 alsoAppliesTo: [
17766 "::first-letter",
17767 "::first-line",
17768 "::placeholder"
17769 ],
17770 status: "standard",
17771 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-stretch"
17772},
17773 "font-style": {
17774 syntax: "normal | italic | oblique <angle>?",
17775 media: "visual",
17776 inherited: true,
17777 animationType: "discrete",
17778 percentages: "no",
17779 groups: [
17780 "CSS Fonts"
17781 ],
17782 initial: "normal",
17783 appliesto: "allElements",
17784 computed: "asSpecified",
17785 order: "uniqueOrder",
17786 alsoAppliesTo: [
17787 "::first-letter",
17788 "::first-line",
17789 "::placeholder"
17790 ],
17791 status: "standard",
17792 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-style"
17793},
17794 "font-synthesis": {
17795 syntax: "none | [ weight || style ]",
17796 media: "visual",
17797 inherited: true,
17798 animationType: "discrete",
17799 percentages: "no",
17800 groups: [
17801 "CSS Fonts"
17802 ],
17803 initial: "weight style",
17804 appliesto: "allElements",
17805 computed: "asSpecified",
17806 order: "orderOfAppearance",
17807 alsoAppliesTo: [
17808 "::first-letter",
17809 "::first-line",
17810 "::placeholder"
17811 ],
17812 status: "standard",
17813 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-synthesis"
17814},
17815 "font-variant": {
17816 syntax: "normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> || stylistic( <feature-value-name> ) || historical-forms || styleset( <feature-value-name># ) || character-variant( <feature-value-name># ) || swash( <feature-value-name> ) || ornaments( <feature-value-name> ) || annotation( <feature-value-name> ) || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero || <east-asian-variant-values> || <east-asian-width-values> || ruby ]",
17817 media: "visual",
17818 inherited: true,
17819 animationType: "discrete",
17820 percentages: "no",
17821 groups: [
17822 "CSS Fonts"
17823 ],
17824 initial: "normal",
17825 appliesto: "allElements",
17826 computed: "asSpecified",
17827 order: "uniqueOrder",
17828 alsoAppliesTo: [
17829 "::first-letter",
17830 "::first-line",
17831 "::placeholder"
17832 ],
17833 status: "standard",
17834 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant"
17835},
17836 "font-variant-alternates": {
17837 syntax: "normal | [ stylistic( <feature-value-name> ) || historical-forms || styleset( <feature-value-name># ) || character-variant( <feature-value-name># ) || swash( <feature-value-name> ) || ornaments( <feature-value-name> ) || annotation( <feature-value-name> ) ]",
17838 media: "visual",
17839 inherited: true,
17840 animationType: "discrete",
17841 percentages: "no",
17842 groups: [
17843 "CSS Fonts"
17844 ],
17845 initial: "normal",
17846 appliesto: "allElements",
17847 computed: "asSpecified",
17848 order: "orderOfAppearance",
17849 alsoAppliesTo: [
17850 "::first-letter",
17851 "::first-line",
17852 "::placeholder"
17853 ],
17854 status: "standard",
17855 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-alternates"
17856},
17857 "font-variant-caps": {
17858 syntax: "normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps",
17859 media: "visual",
17860 inherited: true,
17861 animationType: "discrete",
17862 percentages: "no",
17863 groups: [
17864 "CSS Fonts"
17865 ],
17866 initial: "normal",
17867 appliesto: "allElements",
17868 computed: "asSpecified",
17869 order: "uniqueOrder",
17870 alsoAppliesTo: [
17871 "::first-letter",
17872 "::first-line",
17873 "::placeholder"
17874 ],
17875 status: "standard",
17876 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-caps"
17877},
17878 "font-variant-east-asian": {
17879 syntax: "normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]",
17880 media: "visual",
17881 inherited: true,
17882 animationType: "discrete",
17883 percentages: "no",
17884 groups: [
17885 "CSS Fonts"
17886 ],
17887 initial: "normal",
17888 appliesto: "allElements",
17889 computed: "asSpecified",
17890 order: "orderOfAppearance",
17891 alsoAppliesTo: [
17892 "::first-letter",
17893 "::first-line",
17894 "::placeholder"
17895 ],
17896 status: "standard",
17897 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-east-asian"
17898},
17899 "font-variant-ligatures": {
17900 syntax: "normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]",
17901 media: "visual",
17902 inherited: true,
17903 animationType: "discrete",
17904 percentages: "no",
17905 groups: [
17906 "CSS Fonts"
17907 ],
17908 initial: "normal",
17909 appliesto: "allElements",
17910 computed: "asSpecified",
17911 order: "orderOfAppearance",
17912 alsoAppliesTo: [
17913 "::first-letter",
17914 "::first-line",
17915 "::placeholder"
17916 ],
17917 status: "standard",
17918 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-ligatures"
17919},
17920 "font-variant-numeric": {
17921 syntax: "normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]",
17922 media: "visual",
17923 inherited: true,
17924 animationType: "discrete",
17925 percentages: "no",
17926 groups: [
17927 "CSS Fonts"
17928 ],
17929 initial: "normal",
17930 appliesto: "allElements",
17931 computed: "asSpecified",
17932 order: "orderOfAppearance",
17933 alsoAppliesTo: [
17934 "::first-letter",
17935 "::first-line",
17936 "::placeholder"
17937 ],
17938 status: "standard",
17939 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-numeric"
17940},
17941 "font-variant-position": {
17942 syntax: "normal | sub | super",
17943 media: "visual",
17944 inherited: true,
17945 animationType: "discrete",
17946 percentages: "no",
17947 groups: [
17948 "CSS Fonts"
17949 ],
17950 initial: "normal",
17951 appliesto: "allElements",
17952 computed: "asSpecified",
17953 order: "uniqueOrder",
17954 alsoAppliesTo: [
17955 "::first-letter",
17956 "::first-line",
17957 "::placeholder"
17958 ],
17959 status: "standard",
17960 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-position"
17961},
17962 "font-weight": {
17963 syntax: "<font-weight-absolute> | bolder | lighter",
17964 media: "visual",
17965 inherited: true,
17966 animationType: "fontWeight",
17967 percentages: "no",
17968 groups: [
17969 "CSS Fonts"
17970 ],
17971 initial: "normal",
17972 appliesto: "allElements",
17973 computed: "keywordOrNumericalValueBolderLighterTransformedToRealValue",
17974 order: "uniqueOrder",
17975 alsoAppliesTo: [
17976 "::first-letter",
17977 "::first-line",
17978 "::placeholder"
17979 ],
17980 status: "standard",
17981 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/font-weight"
17982},
17983 gap: gap,
17984 grid: grid,
17985 "grid-area": {
17986 syntax: "<grid-line> [ / <grid-line> ]{0,3}",
17987 media: "visual",
17988 inherited: false,
17989 animationType: "discrete",
17990 percentages: "no",
17991 groups: [
17992 "CSS Grid Layout"
17993 ],
17994 initial: [
17995 "grid-row-start",
17996 "grid-column-start",
17997 "grid-row-end",
17998 "grid-column-end"
17999 ],
18000 appliesto: "gridItemsAndBoxesWithinGridContainer",
18001 computed: [
18002 "grid-row-start",
18003 "grid-column-start",
18004 "grid-row-end",
18005 "grid-column-end"
18006 ],
18007 order: "uniqueOrder",
18008 status: "standard",
18009 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-area"
18010},
18011 "grid-auto-columns": {
18012 syntax: "<track-size>+",
18013 media: "visual",
18014 inherited: false,
18015 animationType: "discrete",
18016 percentages: "referToDimensionOfContentArea",
18017 groups: [
18018 "CSS Grid Layout"
18019 ],
18020 initial: "auto",
18021 appliesto: "gridContainers",
18022 computed: "percentageAsSpecifiedOrAbsoluteLength",
18023 order: "uniqueOrder",
18024 status: "standard",
18025 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-columns"
18026},
18027 "grid-auto-flow": {
18028 syntax: "[ row | column ] || dense",
18029 media: "visual",
18030 inherited: false,
18031 animationType: "discrete",
18032 percentages: "no",
18033 groups: [
18034 "CSS Grid Layout"
18035 ],
18036 initial: "row",
18037 appliesto: "gridContainers",
18038 computed: "asSpecified",
18039 order: "uniqueOrder",
18040 status: "standard",
18041 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-flow"
18042},
18043 "grid-auto-rows": {
18044 syntax: "<track-size>+",
18045 media: "visual",
18046 inherited: false,
18047 animationType: "discrete",
18048 percentages: "referToDimensionOfContentArea",
18049 groups: [
18050 "CSS Grid Layout"
18051 ],
18052 initial: "auto",
18053 appliesto: "gridContainers",
18054 computed: "percentageAsSpecifiedOrAbsoluteLength",
18055 order: "uniqueOrder",
18056 status: "standard",
18057 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-auto-rows"
18058},
18059 "grid-column": {
18060 syntax: "<grid-line> [ / <grid-line> ]?",
18061 media: "visual",
18062 inherited: false,
18063 animationType: "discrete",
18064 percentages: "no",
18065 groups: [
18066 "CSS Grid Layout"
18067 ],
18068 initial: [
18069 "grid-column-start",
18070 "grid-column-end"
18071 ],
18072 appliesto: "gridItemsAndBoxesWithinGridContainer",
18073 computed: [
18074 "grid-column-start",
18075 "grid-column-end"
18076 ],
18077 order: "uniqueOrder",
18078 status: "standard",
18079 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column"
18080},
18081 "grid-column-end": {
18082 syntax: "<grid-line>",
18083 media: "visual",
18084 inherited: false,
18085 animationType: "discrete",
18086 percentages: "no",
18087 groups: [
18088 "CSS Grid Layout"
18089 ],
18090 initial: "auto",
18091 appliesto: "gridItemsAndBoxesWithinGridContainer",
18092 computed: "asSpecified",
18093 order: "uniqueOrder",
18094 status: "standard",
18095 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column-end"
18096},
18097 "grid-column-gap": {
18098 syntax: "<length-percentage>",
18099 media: "visual",
18100 inherited: false,
18101 animationType: "length",
18102 percentages: "referToDimensionOfContentArea",
18103 groups: [
18104 "CSS Grid Layout"
18105 ],
18106 initial: "0",
18107 appliesto: "gridContainers",
18108 computed: "percentageAsSpecifiedOrAbsoluteLength",
18109 order: "uniqueOrder",
18110 status: "obsolete",
18111 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/column-gap"
18112},
18113 "grid-column-start": {
18114 syntax: "<grid-line>",
18115 media: "visual",
18116 inherited: false,
18117 animationType: "discrete",
18118 percentages: "no",
18119 groups: [
18120 "CSS Grid Layout"
18121 ],
18122 initial: "auto",
18123 appliesto: "gridItemsAndBoxesWithinGridContainer",
18124 computed: "asSpecified",
18125 order: "uniqueOrder",
18126 status: "standard",
18127 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-column-start"
18128},
18129 "grid-gap": {
18130 syntax: "<'grid-row-gap'> <'grid-column-gap'>?",
18131 media: "visual",
18132 inherited: false,
18133 animationType: [
18134 "grid-row-gap",
18135 "grid-column-gap"
18136 ],
18137 percentages: "no",
18138 groups: [
18139 "CSS Grid Layout"
18140 ],
18141 initial: [
18142 "grid-row-gap",
18143 "grid-column-gap"
18144 ],
18145 appliesto: "gridContainers",
18146 computed: [
18147 "grid-row-gap",
18148 "grid-column-gap"
18149 ],
18150 order: "uniqueOrder",
18151 status: "obsolete",
18152 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/gap"
18153},
18154 "grid-row": {
18155 syntax: "<grid-line> [ / <grid-line> ]?",
18156 media: "visual",
18157 inherited: false,
18158 animationType: "discrete",
18159 percentages: "no",
18160 groups: [
18161 "CSS Grid Layout"
18162 ],
18163 initial: [
18164 "grid-row-start",
18165 "grid-row-end"
18166 ],
18167 appliesto: "gridItemsAndBoxesWithinGridContainer",
18168 computed: [
18169 "grid-row-start",
18170 "grid-row-end"
18171 ],
18172 order: "uniqueOrder",
18173 status: "standard",
18174 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row"
18175},
18176 "grid-row-end": {
18177 syntax: "<grid-line>",
18178 media: "visual",
18179 inherited: false,
18180 animationType: "discrete",
18181 percentages: "no",
18182 groups: [
18183 "CSS Grid Layout"
18184 ],
18185 initial: "auto",
18186 appliesto: "gridItemsAndBoxesWithinGridContainer",
18187 computed: "asSpecified",
18188 order: "uniqueOrder",
18189 status: "standard",
18190 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row-end"
18191},
18192 "grid-row-gap": {
18193 syntax: "<length-percentage>",
18194 media: "visual",
18195 inherited: false,
18196 animationType: "length",
18197 percentages: "referToDimensionOfContentArea",
18198 groups: [
18199 "CSS Grid Layout"
18200 ],
18201 initial: "0",
18202 appliesto: "gridContainers",
18203 computed: "percentageAsSpecifiedOrAbsoluteLength",
18204 order: "uniqueOrder",
18205 status: "obsolete",
18206 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/row-gap"
18207},
18208 "grid-row-start": {
18209 syntax: "<grid-line>",
18210 media: "visual",
18211 inherited: false,
18212 animationType: "discrete",
18213 percentages: "no",
18214 groups: [
18215 "CSS Grid Layout"
18216 ],
18217 initial: "auto",
18218 appliesto: "gridItemsAndBoxesWithinGridContainer",
18219 computed: "asSpecified",
18220 order: "uniqueOrder",
18221 status: "standard",
18222 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-row-start"
18223},
18224 "grid-template": {
18225 syntax: "none | [ <'grid-template-rows'> / <'grid-template-columns'> ] | [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?",
18226 media: "visual",
18227 inherited: false,
18228 animationType: "discrete",
18229 percentages: [
18230 "grid-template-columns",
18231 "grid-template-rows"
18232 ],
18233 groups: [
18234 "CSS Grid Layout"
18235 ],
18236 initial: [
18237 "grid-template-columns",
18238 "grid-template-rows",
18239 "grid-template-areas"
18240 ],
18241 appliesto: "gridContainers",
18242 computed: [
18243 "grid-template-columns",
18244 "grid-template-rows",
18245 "grid-template-areas"
18246 ],
18247 order: "uniqueOrder",
18248 status: "standard",
18249 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template"
18250},
18251 "grid-template-areas": {
18252 syntax: "none | <string>+",
18253 media: "visual",
18254 inherited: false,
18255 animationType: "discrete",
18256 percentages: "no",
18257 groups: [
18258 "CSS Grid Layout"
18259 ],
18260 initial: "none",
18261 appliesto: "gridContainers",
18262 computed: "asSpecified",
18263 order: "uniqueOrder",
18264 status: "standard",
18265 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-areas"
18266},
18267 "grid-template-columns": {
18268 syntax: "none | <track-list> | <auto-track-list> | subgrid <line-name-list>?",
18269 media: "visual",
18270 inherited: false,
18271 animationType: "simpleListOfLpcDifferenceLpc",
18272 percentages: "referToDimensionOfContentArea",
18273 groups: [
18274 "CSS Grid Layout"
18275 ],
18276 initial: "none",
18277 appliesto: "gridContainers",
18278 computed: "asSpecifiedRelativeToAbsoluteLengths",
18279 order: "uniqueOrder",
18280 status: "standard",
18281 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-columns"
18282},
18283 "grid-template-rows": {
18284 syntax: "none | <track-list> | <auto-track-list> | subgrid <line-name-list>?",
18285 media: "visual",
18286 inherited: false,
18287 animationType: "simpleListOfLpcDifferenceLpc",
18288 percentages: "referToDimensionOfContentArea",
18289 groups: [
18290 "CSS Grid Layout"
18291 ],
18292 initial: "none",
18293 appliesto: "gridContainers",
18294 computed: "asSpecifiedRelativeToAbsoluteLengths",
18295 order: "uniqueOrder",
18296 status: "standard",
18297 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/grid-template-rows"
18298},
18299 "hanging-punctuation": {
18300 syntax: "none | [ first || [ force-end | allow-end ] || last ]",
18301 media: "visual",
18302 inherited: true,
18303 animationType: "discrete",
18304 percentages: "no",
18305 groups: [
18306 "CSS Text"
18307 ],
18308 initial: "none",
18309 appliesto: "allElements",
18310 computed: "asSpecified",
18311 order: "uniqueOrder",
18312 status: "standard",
18313 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/hanging-punctuation"
18314},
18315 height: height,
18316 hyphens: hyphens,
18317 "image-orientation": {
18318 syntax: "from-image | <angle> | [ <angle>? flip ]",
18319 media: "visual",
18320 inherited: true,
18321 animationType: "discrete",
18322 percentages: "no",
18323 groups: [
18324 "CSS Images"
18325 ],
18326 initial: "from-image",
18327 appliesto: "allElements",
18328 computed: "angleRoundedToNextQuarter",
18329 order: "uniqueOrder",
18330 status: "standard",
18331 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/image-orientation"
18332},
18333 "image-rendering": {
18334 syntax: "auto | crisp-edges | pixelated",
18335 media: "visual",
18336 inherited: true,
18337 animationType: "discrete",
18338 percentages: "no",
18339 groups: [
18340 "CSS Images"
18341 ],
18342 initial: "auto",
18343 appliesto: "allElements",
18344 computed: "asSpecified",
18345 order: "uniqueOrder",
18346 status: "standard",
18347 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/image-rendering"
18348},
18349 "image-resolution": {
18350 syntax: "[ from-image || <resolution> ] && snap?",
18351 media: "visual",
18352 inherited: true,
18353 animationType: "discrete",
18354 percentages: "no",
18355 groups: [
18356 "CSS Images"
18357 ],
18358 initial: "1dppx",
18359 appliesto: "allElements",
18360 computed: "asSpecifiedWithExceptionOfResolution",
18361 order: "uniqueOrder",
18362 status: "experimental"
18363},
18364 "ime-mode": {
18365 syntax: "auto | normal | active | inactive | disabled",
18366 media: "interactive",
18367 inherited: false,
18368 animationType: "discrete",
18369 percentages: "no",
18370 groups: [
18371 "CSS Basic User Interface"
18372 ],
18373 initial: "auto",
18374 appliesto: "textFields",
18375 computed: "asSpecified",
18376 order: "uniqueOrder",
18377 status: "obsolete",
18378 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ime-mode"
18379},
18380 "initial-letter": {
18381 syntax: "normal | [ <number> <integer>? ]",
18382 media: "visual",
18383 inherited: false,
18384 animationType: "discrete",
18385 percentages: "no",
18386 groups: [
18387 "CSS Inline"
18388 ],
18389 initial: "normal",
18390 appliesto: "firstLetterPseudoElementsAndInlineLevelFirstChildren",
18391 computed: "asSpecified",
18392 order: "uniqueOrder",
18393 status: "experimental",
18394 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/initial-letter"
18395},
18396 "initial-letter-align": {
18397 syntax: "[ auto | alphabetic | hanging | ideographic ]",
18398 media: "visual",
18399 inherited: false,
18400 animationType: "discrete",
18401 percentages: "no",
18402 groups: [
18403 "CSS Inline"
18404 ],
18405 initial: "auto",
18406 appliesto: "firstLetterPseudoElementsAndInlineLevelFirstChildren",
18407 computed: "asSpecified",
18408 order: "uniqueOrder",
18409 status: "experimental",
18410 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/initial-letter-align"
18411},
18412 "inline-size": {
18413 syntax: "<'width'>",
18414 media: "visual",
18415 inherited: false,
18416 animationType: "lpc",
18417 percentages: "inlineSizeOfContainingBlock",
18418 groups: [
18419 "CSS Logical Properties"
18420 ],
18421 initial: "auto",
18422 appliesto: "sameAsWidthAndHeight",
18423 computed: "sameAsWidthAndHeight",
18424 order: "uniqueOrder",
18425 status: "standard",
18426 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inline-size"
18427},
18428 inset: inset,
18429 "inset-block": {
18430 syntax: "<'top'>{1,2}",
18431 media: "visual",
18432 inherited: false,
18433 animationType: "lpc",
18434 percentages: "logicalHeightOfContainingBlock",
18435 groups: [
18436 "CSS Logical Properties"
18437 ],
18438 initial: "auto",
18439 appliesto: "positionedElements",
18440 computed: "sameAsBoxOffsets",
18441 order: "uniqueOrder",
18442 status: "standard",
18443 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block"
18444},
18445 "inset-block-end": {
18446 syntax: "<'top'>",
18447 media: "visual",
18448 inherited: false,
18449 animationType: "lpc",
18450 percentages: "logicalHeightOfContainingBlock",
18451 groups: [
18452 "CSS Logical Properties"
18453 ],
18454 initial: "auto",
18455 appliesto: "positionedElements",
18456 computed: "sameAsBoxOffsets",
18457 order: "uniqueOrder",
18458 status: "standard",
18459 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block-end"
18460},
18461 "inset-block-start": {
18462 syntax: "<'top'>",
18463 media: "visual",
18464 inherited: false,
18465 animationType: "lpc",
18466 percentages: "logicalHeightOfContainingBlock",
18467 groups: [
18468 "CSS Logical Properties"
18469 ],
18470 initial: "auto",
18471 appliesto: "positionedElements",
18472 computed: "sameAsBoxOffsets",
18473 order: "uniqueOrder",
18474 status: "standard",
18475 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-block-start"
18476},
18477 "inset-inline": {
18478 syntax: "<'top'>{1,2}",
18479 media: "visual",
18480 inherited: false,
18481 animationType: "lpc",
18482 percentages: "logicalWidthOfContainingBlock",
18483 groups: [
18484 "CSS Logical Properties"
18485 ],
18486 initial: "auto",
18487 appliesto: "positionedElements",
18488 computed: "sameAsBoxOffsets",
18489 order: "uniqueOrder",
18490 status: "standard",
18491 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline"
18492},
18493 "inset-inline-end": {
18494 syntax: "<'top'>",
18495 media: "visual",
18496 inherited: false,
18497 animationType: "lpc",
18498 percentages: "logicalWidthOfContainingBlock",
18499 groups: [
18500 "CSS Logical Properties"
18501 ],
18502 initial: "auto",
18503 appliesto: "positionedElements",
18504 computed: "sameAsBoxOffsets",
18505 order: "uniqueOrder",
18506 status: "standard",
18507 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline-end"
18508},
18509 "inset-inline-start": {
18510 syntax: "<'top'>",
18511 media: "visual",
18512 inherited: false,
18513 animationType: "lpc",
18514 percentages: "logicalWidthOfContainingBlock",
18515 groups: [
18516 "CSS Logical Properties"
18517 ],
18518 initial: "auto",
18519 appliesto: "positionedElements",
18520 computed: "sameAsBoxOffsets",
18521 order: "uniqueOrder",
18522 status: "standard",
18523 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/inset-inline-start"
18524},
18525 isolation: isolation,
18526 "justify-content": {
18527 syntax: "normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]",
18528 media: "visual",
18529 inherited: false,
18530 animationType: "discrete",
18531 percentages: "no",
18532 groups: [
18533 "CSS Box Alignment"
18534 ],
18535 initial: "normal",
18536 appliesto: "flexContainers",
18537 computed: "asSpecified",
18538 order: "uniqueOrder",
18539 status: "standard",
18540 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-content"
18541},
18542 "justify-items": {
18543 syntax: "normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ]",
18544 media: "visual",
18545 inherited: false,
18546 animationType: "discrete",
18547 percentages: "no",
18548 groups: [
18549 "CSS Box Alignment"
18550 ],
18551 initial: "legacy",
18552 appliesto: "allElements",
18553 computed: "asSpecified",
18554 order: "perGrammar",
18555 status: "standard",
18556 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-items"
18557},
18558 "justify-self": {
18559 syntax: "auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ]",
18560 media: "visual",
18561 inherited: false,
18562 animationType: "discrete",
18563 percentages: "no",
18564 groups: [
18565 "CSS Box Alignment"
18566 ],
18567 initial: "auto",
18568 appliesto: "blockLevelBoxesAndAbsolutelyPositionedBoxesAndGridItems",
18569 computed: "asSpecified",
18570 order: "uniqueOrder",
18571 status: "standard",
18572 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-self"
18573},
18574 "justify-tracks": {
18575 syntax: "[ normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ] ]#",
18576 media: "visual",
18577 inherited: false,
18578 animationType: "discrete",
18579 percentages: "no",
18580 groups: [
18581 "CSS Grid Layout"
18582 ],
18583 initial: "normal",
18584 appliesto: "gridContainersWithMasonryLayoutInTheirInlineAxis",
18585 computed: "asSpecified",
18586 order: "uniqueOrder",
18587 status: "experimental",
18588 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/justify-tracks"
18589},
18590 left: left,
18591 "letter-spacing": {
18592 syntax: "normal | <length>",
18593 media: "visual",
18594 inherited: true,
18595 animationType: "length",
18596 percentages: "no",
18597 groups: [
18598 "CSS Text"
18599 ],
18600 initial: "normal",
18601 appliesto: "allElements",
18602 computed: "optimumValueOfAbsoluteLengthOrNormal",
18603 order: "uniqueOrder",
18604 alsoAppliesTo: [
18605 "::first-letter",
18606 "::first-line"
18607 ],
18608 status: "standard",
18609 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/letter-spacing"
18610},
18611 "line-break": {
18612 syntax: "auto | loose | normal | strict | anywhere",
18613 media: "visual",
18614 inherited: true,
18615 animationType: "discrete",
18616 percentages: "no",
18617 groups: [
18618 "CSS Text"
18619 ],
18620 initial: "auto",
18621 appliesto: "allElements",
18622 computed: "asSpecified",
18623 order: "uniqueOrder",
18624 status: "standard",
18625 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-break"
18626},
18627 "line-clamp": {
18628 syntax: "none | <integer>",
18629 media: "visual",
18630 inherited: false,
18631 animationType: "integer",
18632 percentages: "no",
18633 groups: [
18634 "CSS Overflow"
18635 ],
18636 initial: "none",
18637 appliesto: "blockContainersExceptMultiColumnContainers",
18638 computed: "asSpecified",
18639 order: "perGrammar",
18640 status: "experimental"
18641},
18642 "line-height": {
18643 syntax: "normal | <number> | <length> | <percentage>",
18644 media: "visual",
18645 inherited: true,
18646 animationType: "numberOrLength",
18647 percentages: "referToElementFontSize",
18648 groups: [
18649 "CSS Fonts"
18650 ],
18651 initial: "normal",
18652 appliesto: "allElements",
18653 computed: "absoluteLengthOrAsSpecified",
18654 order: "uniqueOrder",
18655 alsoAppliesTo: [
18656 "::first-letter",
18657 "::first-line",
18658 "::placeholder"
18659 ],
18660 status: "standard",
18661 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-height"
18662},
18663 "line-height-step": {
18664 syntax: "<length>",
18665 media: "visual",
18666 inherited: true,
18667 animationType: "discrete",
18668 percentages: "no",
18669 groups: [
18670 "CSS Fonts"
18671 ],
18672 initial: "0",
18673 appliesto: "blockContainers",
18674 computed: "absoluteLength",
18675 order: "perGrammar",
18676 status: "experimental",
18677 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/line-height-step"
18678},
18679 "list-style": {
18680 syntax: "<'list-style-type'> || <'list-style-position'> || <'list-style-image'>",
18681 media: "visual",
18682 inherited: true,
18683 animationType: "discrete",
18684 percentages: "no",
18685 groups: [
18686 "CSS Lists and Counters"
18687 ],
18688 initial: [
18689 "list-style-type",
18690 "list-style-position",
18691 "list-style-image"
18692 ],
18693 appliesto: "listItems",
18694 computed: [
18695 "list-style-image",
18696 "list-style-position",
18697 "list-style-type"
18698 ],
18699 order: "orderOfAppearance",
18700 status: "standard",
18701 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style"
18702},
18703 "list-style-image": {
18704 syntax: "<url> | none",
18705 media: "visual",
18706 inherited: true,
18707 animationType: "discrete",
18708 percentages: "no",
18709 groups: [
18710 "CSS Lists and Counters"
18711 ],
18712 initial: "none",
18713 appliesto: "listItems",
18714 computed: "noneOrImageWithAbsoluteURI",
18715 order: "uniqueOrder",
18716 status: "standard",
18717 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-image"
18718},
18719 "list-style-position": {
18720 syntax: "inside | outside",
18721 media: "visual",
18722 inherited: true,
18723 animationType: "discrete",
18724 percentages: "no",
18725 groups: [
18726 "CSS Lists and Counters"
18727 ],
18728 initial: "outside",
18729 appliesto: "listItems",
18730 computed: "asSpecified",
18731 order: "uniqueOrder",
18732 status: "standard",
18733 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-position"
18734},
18735 "list-style-type": {
18736 syntax: "<counter-style> | <string> | none",
18737 media: "visual",
18738 inherited: true,
18739 animationType: "discrete",
18740 percentages: "no",
18741 groups: [
18742 "CSS Lists and Counters"
18743 ],
18744 initial: "disc",
18745 appliesto: "listItems",
18746 computed: "asSpecified",
18747 order: "uniqueOrder",
18748 status: "standard",
18749 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/list-style-type"
18750},
18751 margin: margin,
18752 "margin-block": {
18753 syntax: "<'margin-left'>{1,2}",
18754 media: "visual",
18755 inherited: false,
18756 animationType: "discrete",
18757 percentages: "dependsOnLayoutModel",
18758 groups: [
18759 "CSS Logical Properties"
18760 ],
18761 initial: "0",
18762 appliesto: "sameAsMargin",
18763 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18764 order: "uniqueOrder",
18765 status: "standard",
18766 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block"
18767},
18768 "margin-block-end": {
18769 syntax: "<'margin-left'>",
18770 media: "visual",
18771 inherited: false,
18772 animationType: "length",
18773 percentages: "dependsOnLayoutModel",
18774 groups: [
18775 "CSS Logical Properties"
18776 ],
18777 initial: "0",
18778 appliesto: "sameAsMargin",
18779 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18780 order: "uniqueOrder",
18781 status: "standard",
18782 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block-end"
18783},
18784 "margin-block-start": {
18785 syntax: "<'margin-left'>",
18786 media: "visual",
18787 inherited: false,
18788 animationType: "length",
18789 percentages: "dependsOnLayoutModel",
18790 groups: [
18791 "CSS Logical Properties"
18792 ],
18793 initial: "0",
18794 appliesto: "sameAsMargin",
18795 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18796 order: "uniqueOrder",
18797 status: "standard",
18798 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-block-start"
18799},
18800 "margin-bottom": {
18801 syntax: "<length> | <percentage> | auto",
18802 media: "visual",
18803 inherited: false,
18804 animationType: "length",
18805 percentages: "referToWidthOfContainingBlock",
18806 groups: [
18807 "CSS Box Model"
18808 ],
18809 initial: "0",
18810 appliesto: "allElementsExceptTableDisplayTypes",
18811 computed: "percentageAsSpecifiedOrAbsoluteLength",
18812 order: "uniqueOrder",
18813 alsoAppliesTo: [
18814 "::first-letter",
18815 "::first-line"
18816 ],
18817 status: "standard",
18818 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-bottom"
18819},
18820 "margin-inline": {
18821 syntax: "<'margin-left'>{1,2}",
18822 media: "visual",
18823 inherited: false,
18824 animationType: "discrete",
18825 percentages: "dependsOnLayoutModel",
18826 groups: [
18827 "CSS Logical Properties"
18828 ],
18829 initial: "0",
18830 appliesto: "sameAsMargin",
18831 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18832 order: "uniqueOrder",
18833 status: "standard",
18834 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline"
18835},
18836 "margin-inline-end": {
18837 syntax: "<'margin-left'>",
18838 media: "visual",
18839 inherited: false,
18840 animationType: "length",
18841 percentages: "dependsOnLayoutModel",
18842 groups: [
18843 "CSS Logical Properties"
18844 ],
18845 initial: "0",
18846 appliesto: "sameAsMargin",
18847 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18848 order: "uniqueOrder",
18849 status: "standard",
18850 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline-end"
18851},
18852 "margin-inline-start": {
18853 syntax: "<'margin-left'>",
18854 media: "visual",
18855 inherited: false,
18856 animationType: "length",
18857 percentages: "dependsOnLayoutModel",
18858 groups: [
18859 "CSS Logical Properties"
18860 ],
18861 initial: "0",
18862 appliesto: "sameAsMargin",
18863 computed: "lengthAbsolutePercentageAsSpecifiedOtherwiseAuto",
18864 order: "uniqueOrder",
18865 status: "standard",
18866 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-inline-start"
18867},
18868 "margin-left": {
18869 syntax: "<length> | <percentage> | auto",
18870 media: "visual",
18871 inherited: false,
18872 animationType: "length",
18873 percentages: "referToWidthOfContainingBlock",
18874 groups: [
18875 "CSS Box Model"
18876 ],
18877 initial: "0",
18878 appliesto: "allElementsExceptTableDisplayTypes",
18879 computed: "percentageAsSpecifiedOrAbsoluteLength",
18880 order: "uniqueOrder",
18881 alsoAppliesTo: [
18882 "::first-letter",
18883 "::first-line"
18884 ],
18885 status: "standard",
18886 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-left"
18887},
18888 "margin-right": {
18889 syntax: "<length> | <percentage> | auto",
18890 media: "visual",
18891 inherited: false,
18892 animationType: "length",
18893 percentages: "referToWidthOfContainingBlock",
18894 groups: [
18895 "CSS Box Model"
18896 ],
18897 initial: "0",
18898 appliesto: "allElementsExceptTableDisplayTypes",
18899 computed: "percentageAsSpecifiedOrAbsoluteLength",
18900 order: "uniqueOrder",
18901 alsoAppliesTo: [
18902 "::first-letter",
18903 "::first-line"
18904 ],
18905 status: "standard",
18906 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-right"
18907},
18908 "margin-top": {
18909 syntax: "<length> | <percentage> | auto",
18910 media: "visual",
18911 inherited: false,
18912 animationType: "length",
18913 percentages: "referToWidthOfContainingBlock",
18914 groups: [
18915 "CSS Box Model"
18916 ],
18917 initial: "0",
18918 appliesto: "allElementsExceptTableDisplayTypes",
18919 computed: "percentageAsSpecifiedOrAbsoluteLength",
18920 order: "uniqueOrder",
18921 alsoAppliesTo: [
18922 "::first-letter",
18923 "::first-line"
18924 ],
18925 status: "standard",
18926 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-top"
18927},
18928 "margin-trim": {
18929 syntax: "none | in-flow | all",
18930 media: "visual",
18931 inherited: false,
18932 animationType: "discrete",
18933 percentages: "no",
18934 groups: [
18935 "CSS Box Model"
18936 ],
18937 initial: "none",
18938 appliesto: "blockContainersAndMultiColumnContainers",
18939 computed: "asSpecified",
18940 order: "perGrammar",
18941 alsoAppliesTo: [
18942 "::first-letter",
18943 "::first-line"
18944 ],
18945 status: "experimental",
18946 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/margin-trim"
18947},
18948 mask: mask,
18949 "mask-border": {
18950 syntax: "<'mask-border-source'> || <'mask-border-slice'> [ / <'mask-border-width'>? [ / <'mask-border-outset'> ]? ]? || <'mask-border-repeat'> || <'mask-border-mode'>",
18951 media: "visual",
18952 inherited: false,
18953 animationType: [
18954 "mask-border-mode",
18955 "mask-border-outset",
18956 "mask-border-repeat",
18957 "mask-border-slice",
18958 "mask-border-source",
18959 "mask-border-width"
18960 ],
18961 percentages: [
18962 "mask-border-slice",
18963 "mask-border-width"
18964 ],
18965 groups: [
18966 "CSS Masking"
18967 ],
18968 initial: [
18969 "mask-border-mode",
18970 "mask-border-outset",
18971 "mask-border-repeat",
18972 "mask-border-slice",
18973 "mask-border-source",
18974 "mask-border-width"
18975 ],
18976 appliesto: "allElementsSVGContainerElements",
18977 computed: [
18978 "mask-border-mode",
18979 "mask-border-outset",
18980 "mask-border-repeat",
18981 "mask-border-slice",
18982 "mask-border-source",
18983 "mask-border-width"
18984 ],
18985 order: "perGrammar",
18986 stacking: true,
18987 status: "standard",
18988 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border"
18989},
18990 "mask-border-mode": {
18991 syntax: "luminance | alpha",
18992 media: "visual",
18993 inherited: false,
18994 animationType: "discrete",
18995 percentages: "no",
18996 groups: [
18997 "CSS Masking"
18998 ],
18999 initial: "alpha",
19000 appliesto: "allElementsSVGContainerElements",
19001 computed: "asSpecified",
19002 order: "perGrammar",
19003 status: "standard",
19004 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-mode"
19005},
19006 "mask-border-outset": {
19007 syntax: "[ <length> | <number> ]{1,4}",
19008 media: "visual",
19009 inherited: false,
19010 animationType: "discrete",
19011 percentages: "no",
19012 groups: [
19013 "CSS Masking"
19014 ],
19015 initial: "0",
19016 appliesto: "allElementsSVGContainerElements",
19017 computed: "asSpecifiedRelativeToAbsoluteLengths",
19018 order: "perGrammar",
19019 status: "standard",
19020 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-outset"
19021},
19022 "mask-border-repeat": {
19023 syntax: "[ stretch | repeat | round | space ]{1,2}",
19024 media: "visual",
19025 inherited: false,
19026 animationType: "discrete",
19027 percentages: "no",
19028 groups: [
19029 "CSS Masking"
19030 ],
19031 initial: "stretch",
19032 appliesto: "allElementsSVGContainerElements",
19033 computed: "asSpecified",
19034 order: "perGrammar",
19035 status: "standard",
19036 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-repeat"
19037},
19038 "mask-border-slice": {
19039 syntax: "<number-percentage>{1,4} fill?",
19040 media: "visual",
19041 inherited: false,
19042 animationType: "discrete",
19043 percentages: "referToSizeOfMaskBorderImage",
19044 groups: [
19045 "CSS Masking"
19046 ],
19047 initial: "0",
19048 appliesto: "allElementsSVGContainerElements",
19049 computed: "asSpecified",
19050 order: "perGrammar",
19051 status: "standard",
19052 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-slice"
19053},
19054 "mask-border-source": {
19055 syntax: "none | <image>",
19056 media: "visual",
19057 inherited: false,
19058 animationType: "discrete",
19059 percentages: "no",
19060 groups: [
19061 "CSS Masking"
19062 ],
19063 initial: "none",
19064 appliesto: "allElementsSVGContainerElements",
19065 computed: "asSpecifiedURLsAbsolute",
19066 order: "perGrammar",
19067 status: "standard",
19068 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-source"
19069},
19070 "mask-border-width": {
19071 syntax: "[ <length-percentage> | <number> | auto ]{1,4}",
19072 media: "visual",
19073 inherited: false,
19074 animationType: "discrete",
19075 percentages: "relativeToMaskBorderImageArea",
19076 groups: [
19077 "CSS Masking"
19078 ],
19079 initial: "auto",
19080 appliesto: "allElementsSVGContainerElements",
19081 computed: "asSpecifiedRelativeToAbsoluteLengths",
19082 order: "perGrammar",
19083 status: "standard",
19084 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-border-width"
19085},
19086 "mask-clip": {
19087 syntax: "[ <geometry-box> | no-clip ]#",
19088 media: "visual",
19089 inherited: false,
19090 animationType: "discrete",
19091 percentages: "no",
19092 groups: [
19093 "CSS Masking"
19094 ],
19095 initial: "border-box",
19096 appliesto: "allElementsSVGContainerElements",
19097 computed: "asSpecified",
19098 order: "perGrammar",
19099 status: "standard",
19100 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-clip"
19101},
19102 "mask-composite": {
19103 syntax: "<compositing-operator>#",
19104 media: "visual",
19105 inherited: false,
19106 animationType: "discrete",
19107 percentages: "no",
19108 groups: [
19109 "CSS Masking"
19110 ],
19111 initial: "add",
19112 appliesto: "allElementsSVGContainerElements",
19113 computed: "asSpecified",
19114 order: "perGrammar",
19115 status: "standard",
19116 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-composite"
19117},
19118 "mask-image": {
19119 syntax: "<mask-reference>#",
19120 media: "visual",
19121 inherited: false,
19122 animationType: "discrete",
19123 percentages: "no",
19124 groups: [
19125 "CSS Masking"
19126 ],
19127 initial: "none",
19128 appliesto: "allElementsSVGContainerElements",
19129 computed: "asSpecifiedURLsAbsolute",
19130 order: "perGrammar",
19131 status: "standard",
19132 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-image"
19133},
19134 "mask-mode": {
19135 syntax: "<masking-mode>#",
19136 media: "visual",
19137 inherited: false,
19138 animationType: "discrete",
19139 percentages: "no",
19140 groups: [
19141 "CSS Masking"
19142 ],
19143 initial: "match-source",
19144 appliesto: "allElementsSVGContainerElements",
19145 computed: "asSpecified",
19146 order: "perGrammar",
19147 status: "standard",
19148 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-mode"
19149},
19150 "mask-origin": {
19151 syntax: "<geometry-box>#",
19152 media: "visual",
19153 inherited: false,
19154 animationType: "discrete",
19155 percentages: "no",
19156 groups: [
19157 "CSS Masking"
19158 ],
19159 initial: "border-box",
19160 appliesto: "allElementsSVGContainerElements",
19161 computed: "asSpecified",
19162 order: "perGrammar",
19163 status: "standard",
19164 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-origin"
19165},
19166 "mask-position": {
19167 syntax: "<position>#",
19168 media: "visual",
19169 inherited: false,
19170 animationType: "repeatableListOfSimpleListOfLpc",
19171 percentages: "referToSizeOfMaskPaintingArea",
19172 groups: [
19173 "CSS Masking"
19174 ],
19175 initial: "center",
19176 appliesto: "allElementsSVGContainerElements",
19177 computed: "consistsOfTwoKeywordsForOriginAndOffsets",
19178 order: "perGrammar",
19179 status: "standard",
19180 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-position"
19181},
19182 "mask-repeat": {
19183 syntax: "<repeat-style>#",
19184 media: "visual",
19185 inherited: false,
19186 animationType: "discrete",
19187 percentages: "no",
19188 groups: [
19189 "CSS Masking"
19190 ],
19191 initial: "no-repeat",
19192 appliesto: "allElementsSVGContainerElements",
19193 computed: "consistsOfTwoDimensionKeywords",
19194 order: "perGrammar",
19195 status: "standard",
19196 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-repeat"
19197},
19198 "mask-size": {
19199 syntax: "<bg-size>#",
19200 media: "visual",
19201 inherited: false,
19202 animationType: "repeatableListOfSimpleListOfLpc",
19203 percentages: "no",
19204 groups: [
19205 "CSS Masking"
19206 ],
19207 initial: "auto",
19208 appliesto: "allElementsSVGContainerElements",
19209 computed: "asSpecifiedRelativeToAbsoluteLengths",
19210 order: "perGrammar",
19211 status: "standard",
19212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-size"
19213},
19214 "mask-type": {
19215 syntax: "luminance | alpha",
19216 media: "visual",
19217 inherited: false,
19218 animationType: "discrete",
19219 percentages: "no",
19220 groups: [
19221 "CSS Masking"
19222 ],
19223 initial: "luminance",
19224 appliesto: "maskElements",
19225 computed: "asSpecified",
19226 order: "perGrammar",
19227 status: "standard",
19228 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mask-type"
19229},
19230 "masonry-auto-flow": {
19231 syntax: "[ pack | next ] || [ definite-first | ordered ]",
19232 media: "visual",
19233 inherited: false,
19234 animationType: "discrete",
19235 percentages: "no",
19236 groups: [
19237 "CSS Grid Layout"
19238 ],
19239 initial: "pack",
19240 appliesto: "gridContainersWithMasonryLayout",
19241 computed: "asSpecified",
19242 order: "uniqueOrder",
19243 status: "experimental",
19244 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/masonry-auto-flow"
19245},
19246 "math-style": {
19247 syntax: "normal | compact",
19248 media: "visual",
19249 inherited: true,
19250 animationType: "notAnimatable",
19251 percentages: "no",
19252 groups: [
19253 "MathML"
19254 ],
19255 initial: "normal",
19256 appliesto: "allElements",
19257 computed: "asSpecified",
19258 order: "perGrammar",
19259 status: "standard",
19260 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/math-style"
19261},
19262 "max-block-size": {
19263 syntax: "<'max-width'>",
19264 media: "visual",
19265 inherited: false,
19266 animationType: "lpc",
19267 percentages: "blockSizeOfContainingBlock",
19268 groups: [
19269 "CSS Logical Properties"
19270 ],
19271 initial: "0",
19272 appliesto: "sameAsWidthAndHeight",
19273 computed: "sameAsMaxWidthAndMaxHeight",
19274 order: "uniqueOrder",
19275 status: "standard",
19276 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-block-size"
19277},
19278 "max-height": {
19279 syntax: "none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)",
19280 media: "visual",
19281 inherited: false,
19282 animationType: "lpc",
19283 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentagesNone",
19284 groups: [
19285 "CSS Box Model"
19286 ],
19287 initial: "none",
19288 appliesto: "allElementsButNonReplacedAndTableColumns",
19289 computed: "percentageAsSpecifiedAbsoluteLengthOrNone",
19290 order: "uniqueOrder",
19291 status: "standard",
19292 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-height"
19293},
19294 "max-inline-size": {
19295 syntax: "<'max-width'>",
19296 media: "visual",
19297 inherited: false,
19298 animationType: "lpc",
19299 percentages: "inlineSizeOfContainingBlock",
19300 groups: [
19301 "CSS Logical Properties"
19302 ],
19303 initial: "0",
19304 appliesto: "sameAsWidthAndHeight",
19305 computed: "sameAsMaxWidthAndMaxHeight",
19306 order: "uniqueOrder",
19307 status: "standard",
19308 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-inline-size"
19309},
19310 "max-lines": {
19311 syntax: "none | <integer>",
19312 media: "visual",
19313 inherited: false,
19314 animationType: "integer",
19315 percentages: "no",
19316 groups: [
19317 "CSS Overflow"
19318 ],
19319 initial: "none",
19320 appliesto: "blockContainersExceptMultiColumnContainers",
19321 computed: "asSpecified",
19322 order: "perGrammar",
19323 status: "experimental"
19324},
19325 "max-width": {
19326 syntax: "none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)",
19327 media: "visual",
19328 inherited: false,
19329 animationType: "lpc",
19330 percentages: "referToWidthOfContainingBlock",
19331 groups: [
19332 "CSS Box Model"
19333 ],
19334 initial: "none",
19335 appliesto: "allElementsButNonReplacedAndTableRows",
19336 computed: "percentageAsSpecifiedAbsoluteLengthOrNone",
19337 order: "uniqueOrder",
19338 status: "standard",
19339 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/max-width"
19340},
19341 "min-block-size": {
19342 syntax: "<'min-width'>",
19343 media: "visual",
19344 inherited: false,
19345 animationType: "lpc",
19346 percentages: "blockSizeOfContainingBlock",
19347 groups: [
19348 "CSS Logical Properties"
19349 ],
19350 initial: "0",
19351 appliesto: "sameAsWidthAndHeight",
19352 computed: "sameAsMinWidthAndMinHeight",
19353 order: "uniqueOrder",
19354 status: "standard",
19355 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-block-size"
19356},
19357 "min-height": {
19358 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
19359 media: "visual",
19360 inherited: false,
19361 animationType: "lpc",
19362 percentages: "regardingHeightOfGeneratedBoxContainingBlockPercentages0",
19363 groups: [
19364 "CSS Box Model"
19365 ],
19366 initial: "auto",
19367 appliesto: "allElementsButNonReplacedAndTableColumns",
19368 computed: "percentageAsSpecifiedOrAbsoluteLength",
19369 order: "uniqueOrder",
19370 status: "standard",
19371 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-height"
19372},
19373 "min-inline-size": {
19374 syntax: "<'min-width'>",
19375 media: "visual",
19376 inherited: false,
19377 animationType: "lpc",
19378 percentages: "inlineSizeOfContainingBlock",
19379 groups: [
19380 "CSS Logical Properties"
19381 ],
19382 initial: "0",
19383 appliesto: "sameAsWidthAndHeight",
19384 computed: "sameAsMinWidthAndMinHeight",
19385 order: "uniqueOrder",
19386 status: "standard",
19387 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-inline-size"
19388},
19389 "min-width": {
19390 syntax: "auto | <length> | <percentage> | min-content | max-content | fit-content(<length-percentage>)",
19391 media: "visual",
19392 inherited: false,
19393 animationType: "lpc",
19394 percentages: "referToWidthOfContainingBlock",
19395 groups: [
19396 "CSS Box Model"
19397 ],
19398 initial: "auto",
19399 appliesto: "allElementsButNonReplacedAndTableRows",
19400 computed: "percentageAsSpecifiedOrAbsoluteLength",
19401 order: "uniqueOrder",
19402 status: "standard",
19403 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/min-width"
19404},
19405 "mix-blend-mode": {
19406 syntax: "<blend-mode>",
19407 media: "visual",
19408 inherited: false,
19409 animationType: "discrete",
19410 percentages: "no",
19411 groups: [
19412 "Compositing and Blending"
19413 ],
19414 initial: "normal",
19415 appliesto: "allElements",
19416 computed: "asSpecified",
19417 order: "uniqueOrder",
19418 stacking: true,
19419 status: "standard",
19420 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/mix-blend-mode"
19421},
19422 "object-fit": {
19423 syntax: "fill | contain | cover | none | scale-down",
19424 media: "visual",
19425 inherited: false,
19426 animationType: "discrete",
19427 percentages: "no",
19428 groups: [
19429 "CSS Images"
19430 ],
19431 initial: "fill",
19432 appliesto: "replacedElements",
19433 computed: "asSpecified",
19434 order: "uniqueOrder",
19435 status: "standard",
19436 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/object-fit"
19437},
19438 "object-position": {
19439 syntax: "<position>",
19440 media: "visual",
19441 inherited: true,
19442 animationType: "repeatableListOfSimpleListOfLpc",
19443 percentages: "referToWidthAndHeightOfElement",
19444 groups: [
19445 "CSS Images"
19446 ],
19447 initial: "50% 50%",
19448 appliesto: "replacedElements",
19449 computed: "asSpecified",
19450 order: "uniqueOrder",
19451 status: "standard",
19452 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/object-position"
19453},
19454 offset: offset,
19455 "offset-anchor": {
19456 syntax: "auto | <position>",
19457 media: "visual",
19458 inherited: false,
19459 animationType: "position",
19460 percentages: "relativeToWidthAndHeight",
19461 groups: [
19462 "CSS Motion Path"
19463 ],
19464 initial: "auto",
19465 appliesto: "transformableElements",
19466 computed: "forLengthAbsoluteValueOtherwisePercentage",
19467 order: "perGrammar",
19468 status: "standard"
19469},
19470 "offset-distance": {
19471 syntax: "<length-percentage>",
19472 media: "visual",
19473 inherited: false,
19474 animationType: "lpc",
19475 percentages: "referToTotalPathLength",
19476 groups: [
19477 "CSS Motion Path"
19478 ],
19479 initial: "0",
19480 appliesto: "transformableElements",
19481 computed: "forLengthAbsoluteValueOtherwisePercentage",
19482 order: "perGrammar",
19483 status: "standard",
19484 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-distance"
19485},
19486 "offset-path": {
19487 syntax: "none | ray( [ <angle> && <size> && contain? ] ) | <path()> | <url> | [ <basic-shape> || <geometry-box> ]",
19488 media: "visual",
19489 inherited: false,
19490 animationType: "angleOrBasicShapeOrPath",
19491 percentages: "no",
19492 groups: [
19493 "CSS Motion Path"
19494 ],
19495 initial: "none",
19496 appliesto: "transformableElements",
19497 computed: "asSpecified",
19498 order: "perGrammar",
19499 stacking: true,
19500 status: "standard",
19501 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-path"
19502},
19503 "offset-position": {
19504 syntax: "auto | <position>",
19505 media: "visual",
19506 inherited: false,
19507 animationType: "position",
19508 percentages: "referToSizeOfContainingBlock",
19509 groups: [
19510 "CSS Motion Path"
19511 ],
19512 initial: "auto",
19513 appliesto: "transformableElements",
19514 computed: "forLengthAbsoluteValueOtherwisePercentage",
19515 order: "perGrammar",
19516 status: "experimental"
19517},
19518 "offset-rotate": {
19519 syntax: "[ auto | reverse ] || <angle>",
19520 media: "visual",
19521 inherited: false,
19522 animationType: "angleOrBasicShapeOrPath",
19523 percentages: "no",
19524 groups: [
19525 "CSS Motion Path"
19526 ],
19527 initial: "auto",
19528 appliesto: "transformableElements",
19529 computed: "asSpecified",
19530 order: "perGrammar",
19531 status: "standard",
19532 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/offset-rotate"
19533},
19534 opacity: opacity,
19535 order: order,
19536 orphans: orphans,
19537 outline: outline,
19538 "outline-color": {
19539 syntax: "<color> | invert",
19540 media: [
19541 "visual",
19542 "interactive"
19543 ],
19544 inherited: false,
19545 animationType: "color",
19546 percentages: "no",
19547 groups: [
19548 "CSS Basic User Interface"
19549 ],
19550 initial: "invertOrCurrentColor",
19551 appliesto: "allElements",
19552 computed: "invertForTranslucentColorRGBAOtherwiseRGB",
19553 order: "uniqueOrder",
19554 status: "standard",
19555 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-color"
19556},
19557 "outline-offset": {
19558 syntax: "<length>",
19559 media: [
19560 "visual",
19561 "interactive"
19562 ],
19563 inherited: false,
19564 animationType: "length",
19565 percentages: "no",
19566 groups: [
19567 "CSS Basic User Interface"
19568 ],
19569 initial: "0",
19570 appliesto: "allElements",
19571 computed: "asSpecifiedRelativeToAbsoluteLengths",
19572 order: "uniqueOrder",
19573 status: "standard",
19574 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-offset"
19575},
19576 "outline-style": {
19577 syntax: "auto | <'border-style'>",
19578 media: [
19579 "visual",
19580 "interactive"
19581 ],
19582 inherited: false,
19583 animationType: "discrete",
19584 percentages: "no",
19585 groups: [
19586 "CSS Basic User Interface"
19587 ],
19588 initial: "none",
19589 appliesto: "allElements",
19590 computed: "asSpecified",
19591 order: "uniqueOrder",
19592 status: "standard",
19593 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-style"
19594},
19595 "outline-width": {
19596 syntax: "<line-width>",
19597 media: [
19598 "visual",
19599 "interactive"
19600 ],
19601 inherited: false,
19602 animationType: "length",
19603 percentages: "no",
19604 groups: [
19605 "CSS Basic User Interface"
19606 ],
19607 initial: "medium",
19608 appliesto: "allElements",
19609 computed: "absoluteLength0ForNone",
19610 order: "uniqueOrder",
19611 status: "standard",
19612 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/outline-width"
19613},
19614 overflow: overflow,
19615 "overflow-anchor": {
19616 syntax: "auto | none",
19617 media: "visual",
19618 inherited: false,
19619 animationType: "discrete",
19620 percentages: "no",
19621 groups: [
19622 "CSS Scroll Anchoring"
19623 ],
19624 initial: "auto",
19625 appliesto: "allElements",
19626 computed: "asSpecified",
19627 order: "perGrammar",
19628 status: "standard"
19629},
19630 "overflow-block": {
19631 syntax: "visible | hidden | clip | scroll | auto",
19632 media: "visual",
19633 inherited: false,
19634 animationType: "discrete",
19635 percentages: "no",
19636 groups: [
19637 "CSS Overflow"
19638 ],
19639 initial: "auto",
19640 appliesto: "blockContainersFlexContainersGridContainers",
19641 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19642 order: "perGrammar",
19643 status: "standard"
19644},
19645 "overflow-clip-box": {
19646 syntax: "padding-box | content-box",
19647 media: "visual",
19648 inherited: false,
19649 animationType: "discrete",
19650 percentages: "no",
19651 groups: [
19652 "Mozilla Extensions"
19653 ],
19654 initial: "padding-box",
19655 appliesto: "allElements",
19656 computed: "asSpecified",
19657 order: "uniqueOrder",
19658 status: "nonstandard",
19659 mdn_url: "https://developer.mozilla.org/docs/Mozilla/CSS/overflow-clip-box"
19660},
19661 "overflow-inline": {
19662 syntax: "visible | hidden | clip | scroll | auto",
19663 media: "visual",
19664 inherited: false,
19665 animationType: "discrete",
19666 percentages: "no",
19667 groups: [
19668 "CSS Overflow"
19669 ],
19670 initial: "auto",
19671 appliesto: "blockContainersFlexContainersGridContainers",
19672 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19673 order: "perGrammar",
19674 status: "standard"
19675},
19676 "overflow-wrap": {
19677 syntax: "normal | break-word | anywhere",
19678 media: "visual",
19679 inherited: true,
19680 animationType: "discrete",
19681 percentages: "no",
19682 groups: [
19683 "CSS Text"
19684 ],
19685 initial: "normal",
19686 appliesto: "nonReplacedInlineElements",
19687 computed: "asSpecified",
19688 order: "uniqueOrder",
19689 status: "standard",
19690 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-wrap"
19691},
19692 "overflow-x": {
19693 syntax: "visible | hidden | clip | scroll | auto",
19694 media: "visual",
19695 inherited: false,
19696 animationType: "discrete",
19697 percentages: "no",
19698 groups: [
19699 "CSS Overflow"
19700 ],
19701 initial: "visible",
19702 appliesto: "blockContainersFlexContainersGridContainers",
19703 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19704 order: "uniqueOrder",
19705 status: "standard",
19706 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-x"
19707},
19708 "overflow-y": {
19709 syntax: "visible | hidden | clip | scroll | auto",
19710 media: "visual",
19711 inherited: false,
19712 animationType: "discrete",
19713 percentages: "no",
19714 groups: [
19715 "CSS Overflow"
19716 ],
19717 initial: "visible",
19718 appliesto: "blockContainersFlexContainersGridContainers",
19719 computed: "asSpecifiedButVisibleOrClipReplacedToAutoOrHiddenIfOtherValueDifferent",
19720 order: "uniqueOrder",
19721 status: "standard",
19722 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-y"
19723},
19724 "overscroll-behavior": {
19725 syntax: "[ contain | none | auto ]{1,2}",
19726 media: "visual",
19727 inherited: false,
19728 animationType: "discrete",
19729 percentages: "no",
19730 groups: [
19731 "CSS Box Model"
19732 ],
19733 initial: "auto",
19734 appliesto: "nonReplacedBlockAndInlineBlockElements",
19735 computed: "asSpecified",
19736 order: "uniqueOrder",
19737 status: "standard",
19738 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior"
19739},
19740 "overscroll-behavior-block": {
19741 syntax: "contain | none | auto",
19742 media: "visual",
19743 inherited: false,
19744 animationType: "discrete",
19745 percentages: "no",
19746 groups: [
19747 "CSS Box Model"
19748 ],
19749 initial: "auto",
19750 appliesto: "nonReplacedBlockAndInlineBlockElements",
19751 computed: "asSpecified",
19752 order: "uniqueOrder",
19753 status: "standard",
19754 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-block"
19755},
19756 "overscroll-behavior-inline": {
19757 syntax: "contain | none | auto",
19758 media: "visual",
19759 inherited: false,
19760 animationType: "discrete",
19761 percentages: "no",
19762 groups: [
19763 "CSS Box Model"
19764 ],
19765 initial: "auto",
19766 appliesto: "nonReplacedBlockAndInlineBlockElements",
19767 computed: "asSpecified",
19768 order: "uniqueOrder",
19769 status: "standard",
19770 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-inline"
19771},
19772 "overscroll-behavior-x": {
19773 syntax: "contain | none | auto",
19774 media: "visual",
19775 inherited: false,
19776 animationType: "discrete",
19777 percentages: "no",
19778 groups: [
19779 "CSS Box Model"
19780 ],
19781 initial: "auto",
19782 appliesto: "nonReplacedBlockAndInlineBlockElements",
19783 computed: "asSpecified",
19784 order: "uniqueOrder",
19785 status: "standard",
19786 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-x"
19787},
19788 "overscroll-behavior-y": {
19789 syntax: "contain | none | auto",
19790 media: "visual",
19791 inherited: false,
19792 animationType: "discrete",
19793 percentages: "no",
19794 groups: [
19795 "CSS Box Model"
19796 ],
19797 initial: "auto",
19798 appliesto: "nonReplacedBlockAndInlineBlockElements",
19799 computed: "asSpecified",
19800 order: "uniqueOrder",
19801 status: "standard",
19802 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-y"
19803},
19804 padding: padding,
19805 "padding-block": {
19806 syntax: "<'padding-left'>{1,2}",
19807 media: "visual",
19808 inherited: false,
19809 animationType: "discrete",
19810 percentages: "logicalWidthOfContainingBlock",
19811 groups: [
19812 "CSS Logical Properties"
19813 ],
19814 initial: "0",
19815 appliesto: "allElements",
19816 computed: "asLength",
19817 order: "uniqueOrder",
19818 status: "standard",
19819 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block"
19820},
19821 "padding-block-end": {
19822 syntax: "<'padding-left'>",
19823 media: "visual",
19824 inherited: false,
19825 animationType: "length",
19826 percentages: "logicalWidthOfContainingBlock",
19827 groups: [
19828 "CSS Logical Properties"
19829 ],
19830 initial: "0",
19831 appliesto: "allElements",
19832 computed: "asLength",
19833 order: "uniqueOrder",
19834 status: "standard",
19835 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block-end"
19836},
19837 "padding-block-start": {
19838 syntax: "<'padding-left'>",
19839 media: "visual",
19840 inherited: false,
19841 animationType: "length",
19842 percentages: "logicalWidthOfContainingBlock",
19843 groups: [
19844 "CSS Logical Properties"
19845 ],
19846 initial: "0",
19847 appliesto: "allElements",
19848 computed: "asLength",
19849 order: "uniqueOrder",
19850 status: "standard",
19851 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-block-start"
19852},
19853 "padding-bottom": {
19854 syntax: "<length> | <percentage>",
19855 media: "visual",
19856 inherited: false,
19857 animationType: "length",
19858 percentages: "referToWidthOfContainingBlock",
19859 groups: [
19860 "CSS Box Model"
19861 ],
19862 initial: "0",
19863 appliesto: "allElementsExceptInternalTableDisplayTypes",
19864 computed: "percentageAsSpecifiedOrAbsoluteLength",
19865 order: "uniqueOrder",
19866 alsoAppliesTo: [
19867 "::first-letter",
19868 "::first-line"
19869 ],
19870 status: "standard",
19871 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-bottom"
19872},
19873 "padding-inline": {
19874 syntax: "<'padding-left'>{1,2}",
19875 media: "visual",
19876 inherited: false,
19877 animationType: "discrete",
19878 percentages: "logicalWidthOfContainingBlock",
19879 groups: [
19880 "CSS Logical Properties"
19881 ],
19882 initial: "0",
19883 appliesto: "allElements",
19884 computed: "asLength",
19885 order: "uniqueOrder",
19886 status: "standard",
19887 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline"
19888},
19889 "padding-inline-end": {
19890 syntax: "<'padding-left'>",
19891 media: "visual",
19892 inherited: false,
19893 animationType: "length",
19894 percentages: "logicalWidthOfContainingBlock",
19895 groups: [
19896 "CSS Logical Properties"
19897 ],
19898 initial: "0",
19899 appliesto: "allElements",
19900 computed: "asLength",
19901 order: "uniqueOrder",
19902 status: "standard",
19903 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline-end"
19904},
19905 "padding-inline-start": {
19906 syntax: "<'padding-left'>",
19907 media: "visual",
19908 inherited: false,
19909 animationType: "length",
19910 percentages: "logicalWidthOfContainingBlock",
19911 groups: [
19912 "CSS Logical Properties"
19913 ],
19914 initial: "0",
19915 appliesto: "allElements",
19916 computed: "asLength",
19917 order: "uniqueOrder",
19918 status: "standard",
19919 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-inline-start"
19920},
19921 "padding-left": {
19922 syntax: "<length> | <percentage>",
19923 media: "visual",
19924 inherited: false,
19925 animationType: "length",
19926 percentages: "referToWidthOfContainingBlock",
19927 groups: [
19928 "CSS Box Model"
19929 ],
19930 initial: "0",
19931 appliesto: "allElementsExceptInternalTableDisplayTypes",
19932 computed: "percentageAsSpecifiedOrAbsoluteLength",
19933 order: "uniqueOrder",
19934 alsoAppliesTo: [
19935 "::first-letter",
19936 "::first-line"
19937 ],
19938 status: "standard",
19939 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-left"
19940},
19941 "padding-right": {
19942 syntax: "<length> | <percentage>",
19943 media: "visual",
19944 inherited: false,
19945 animationType: "length",
19946 percentages: "referToWidthOfContainingBlock",
19947 groups: [
19948 "CSS Box Model"
19949 ],
19950 initial: "0",
19951 appliesto: "allElementsExceptInternalTableDisplayTypes",
19952 computed: "percentageAsSpecifiedOrAbsoluteLength",
19953 order: "uniqueOrder",
19954 alsoAppliesTo: [
19955 "::first-letter",
19956 "::first-line"
19957 ],
19958 status: "standard",
19959 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-right"
19960},
19961 "padding-top": {
19962 syntax: "<length> | <percentage>",
19963 media: "visual",
19964 inherited: false,
19965 animationType: "length",
19966 percentages: "referToWidthOfContainingBlock",
19967 groups: [
19968 "CSS Box Model"
19969 ],
19970 initial: "0",
19971 appliesto: "allElementsExceptInternalTableDisplayTypes",
19972 computed: "percentageAsSpecifiedOrAbsoluteLength",
19973 order: "uniqueOrder",
19974 alsoAppliesTo: [
19975 "::first-letter",
19976 "::first-line"
19977 ],
19978 status: "standard",
19979 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/padding-top"
19980},
19981 "page-break-after": {
19982 syntax: "auto | always | avoid | left | right | recto | verso",
19983 media: [
19984 "visual",
19985 "paged"
19986 ],
19987 inherited: false,
19988 animationType: "discrete",
19989 percentages: "no",
19990 groups: [
19991 "CSS Pages"
19992 ],
19993 initial: "auto",
19994 appliesto: "blockElementsInNormalFlow",
19995 computed: "asSpecified",
19996 order: "uniqueOrder",
19997 status: "standard",
19998 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-after"
19999},
20000 "page-break-before": {
20001 syntax: "auto | always | avoid | left | right | recto | verso",
20002 media: [
20003 "visual",
20004 "paged"
20005 ],
20006 inherited: false,
20007 animationType: "discrete",
20008 percentages: "no",
20009 groups: [
20010 "CSS Pages"
20011 ],
20012 initial: "auto",
20013 appliesto: "blockElementsInNormalFlow",
20014 computed: "asSpecified",
20015 order: "uniqueOrder",
20016 status: "standard",
20017 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-before"
20018},
20019 "page-break-inside": {
20020 syntax: "auto | avoid",
20021 media: [
20022 "visual",
20023 "paged"
20024 ],
20025 inherited: false,
20026 animationType: "discrete",
20027 percentages: "no",
20028 groups: [
20029 "CSS Pages"
20030 ],
20031 initial: "auto",
20032 appliesto: "blockElementsInNormalFlow",
20033 computed: "asSpecified",
20034 order: "uniqueOrder",
20035 status: "standard",
20036 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/page-break-inside"
20037},
20038 "paint-order": {
20039 syntax: "normal | [ fill || stroke || markers ]",
20040 media: "visual",
20041 inherited: true,
20042 animationType: "discrete",
20043 percentages: "no",
20044 groups: [
20045 "CSS Text"
20046 ],
20047 initial: "normal",
20048 appliesto: "textElements",
20049 computed: "asSpecified",
20050 order: "uniqueOrder",
20051 status: "standard",
20052 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/paint-order"
20053},
20054 perspective: perspective,
20055 "perspective-origin": {
20056 syntax: "<position>",
20057 media: "visual",
20058 inherited: false,
20059 animationType: "simpleListOfLpc",
20060 percentages: "referToSizeOfBoundingBox",
20061 groups: [
20062 "CSS Transforms"
20063 ],
20064 initial: "50% 50%",
20065 appliesto: "transformableElements",
20066 computed: "forLengthAbsoluteValueOtherwisePercentage",
20067 order: "oneOrTwoValuesLengthAbsoluteKeywordsPercentages",
20068 status: "standard",
20069 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/perspective-origin"
20070},
20071 "place-content": {
20072 syntax: "<'align-content'> <'justify-content'>?",
20073 media: "visual",
20074 inherited: false,
20075 animationType: "discrete",
20076 percentages: "no",
20077 groups: [
20078 "CSS Box Alignment"
20079 ],
20080 initial: "normal",
20081 appliesto: "multilineFlexContainers",
20082 computed: "asSpecified",
20083 order: "uniqueOrder",
20084 status: "standard",
20085 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-content"
20086},
20087 "place-items": {
20088 syntax: "<'align-items'> <'justify-items'>?",
20089 media: "visual",
20090 inherited: false,
20091 animationType: "discrete",
20092 percentages: "no",
20093 groups: [
20094 "CSS Box Alignment"
20095 ],
20096 initial: [
20097 "align-items",
20098 "justify-items"
20099 ],
20100 appliesto: "allElements",
20101 computed: [
20102 "align-items",
20103 "justify-items"
20104 ],
20105 order: "uniqueOrder",
20106 status: "standard",
20107 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-items"
20108},
20109 "place-self": {
20110 syntax: "<'align-self'> <'justify-self'>?",
20111 media: "visual",
20112 inherited: false,
20113 animationType: "discrete",
20114 percentages: "no",
20115 groups: [
20116 "CSS Box Alignment"
20117 ],
20118 initial: [
20119 "align-self",
20120 "justify-self"
20121 ],
20122 appliesto: "blockLevelBoxesAndAbsolutelyPositionedBoxesAndGridItems",
20123 computed: [
20124 "align-self",
20125 "justify-self"
20126 ],
20127 order: "uniqueOrder",
20128 status: "standard",
20129 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/place-self"
20130},
20131 "pointer-events": {
20132 syntax: "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",
20133 media: "visual",
20134 inherited: true,
20135 animationType: "discrete",
20136 percentages: "no",
20137 groups: [
20138 "Pointer Events"
20139 ],
20140 initial: "auto",
20141 appliesto: "allElements",
20142 computed: "asSpecified",
20143 order: "uniqueOrder",
20144 status: "standard",
20145 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/pointer-events"
20146},
20147 position: position$1,
20148 quotes: quotes,
20149 resize: resize,
20150 right: right,
20151 rotate: rotate,
20152 "row-gap": {
20153 syntax: "normal | <length-percentage>",
20154 media: "visual",
20155 inherited: false,
20156 animationType: "lpc",
20157 percentages: "referToDimensionOfContentArea",
20158 groups: [
20159 "CSS Box Alignment"
20160 ],
20161 initial: "normal",
20162 appliesto: "multiColumnElementsFlexContainersGridContainers",
20163 computed: "asSpecifiedWithLengthsAbsoluteAndNormalComputingToZeroExceptMultiColumn",
20164 order: "perGrammar",
20165 status: "standard",
20166 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/row-gap"
20167},
20168 "ruby-align": {
20169 syntax: "start | center | space-between | space-around",
20170 media: "visual",
20171 inherited: true,
20172 animationType: "discrete",
20173 percentages: "no",
20174 groups: [
20175 "CSS Ruby"
20176 ],
20177 initial: "space-around",
20178 appliesto: "rubyBasesAnnotationsBaseAnnotationContainers",
20179 computed: "asSpecified",
20180 order: "uniqueOrder",
20181 status: "experimental",
20182 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ruby-align"
20183},
20184 "ruby-merge": {
20185 syntax: "separate | collapse | auto",
20186 media: "visual",
20187 inherited: true,
20188 animationType: "discrete",
20189 percentages: "no",
20190 groups: [
20191 "CSS Ruby"
20192 ],
20193 initial: "separate",
20194 appliesto: "rubyAnnotationsContainers",
20195 computed: "asSpecified",
20196 order: "uniqueOrder",
20197 status: "experimental"
20198},
20199 "ruby-position": {
20200 syntax: "over | under | inter-character",
20201 media: "visual",
20202 inherited: true,
20203 animationType: "discrete",
20204 percentages: "no",
20205 groups: [
20206 "CSS Ruby"
20207 ],
20208 initial: "over",
20209 appliesto: "rubyAnnotationsContainers",
20210 computed: "asSpecified",
20211 order: "uniqueOrder",
20212 status: "experimental",
20213 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/ruby-position"
20214},
20215 scale: scale,
20216 "scrollbar-color": {
20217 syntax: "auto | dark | light | <color>{2}",
20218 media: "visual",
20219 inherited: true,
20220 animationType: "color",
20221 percentages: "no",
20222 groups: [
20223 "CSS Scrollbars"
20224 ],
20225 initial: "auto",
20226 appliesto: "scrollingBoxes",
20227 computed: "asSpecified",
20228 order: "perGrammar",
20229 status: "standard",
20230 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-color"
20231},
20232 "scrollbar-gutter": {
20233 syntax: "auto | [ stable | always ] && both? && force?",
20234 media: "visual",
20235 inherited: false,
20236 animationType: "discrete",
20237 percentages: "no",
20238 groups: [
20239 "CSS Overflow"
20240 ],
20241 initial: "auto",
20242 appliesto: "allElements",
20243 computed: "asSpecified",
20244 order: "perGrammar",
20245 status: "standard",
20246 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-gutter"
20247},
20248 "scrollbar-width": {
20249 syntax: "auto | thin | none",
20250 media: "visual",
20251 inherited: false,
20252 animationType: "discrete",
20253 percentages: "no",
20254 groups: [
20255 "CSS Scrollbars"
20256 ],
20257 initial: "auto",
20258 appliesto: "scrollingBoxes",
20259 computed: "asSpecified",
20260 order: "perGrammar",
20261 status: "standard",
20262 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scrollbar-width"
20263},
20264 "scroll-behavior": {
20265 syntax: "auto | smooth",
20266 media: "visual",
20267 inherited: false,
20268 animationType: "discrete",
20269 percentages: "no",
20270 groups: [
20271 "CSSOM View"
20272 ],
20273 initial: "auto",
20274 appliesto: "scrollingBoxes",
20275 computed: "asSpecified",
20276 order: "uniqueOrder",
20277 status: "standard",
20278 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-behavior"
20279},
20280 "scroll-margin": {
20281 syntax: "<length>{1,4}",
20282 media: "visual",
20283 inherited: false,
20284 animationType: "byComputedValueType",
20285 percentages: "no",
20286 groups: [
20287 "CSS Scroll Snap"
20288 ],
20289 initial: "0",
20290 appliesto: "allElements",
20291 computed: "asSpecified",
20292 order: "perGrammar",
20293 status: "standard",
20294 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin"
20295},
20296 "scroll-margin-block": {
20297 syntax: "<length>{1,2}",
20298 media: "visual",
20299 inherited: false,
20300 animationType: "byComputedValueType",
20301 percentages: "no",
20302 groups: [
20303 "CSS Scroll Snap"
20304 ],
20305 initial: "0",
20306 appliesto: "allElements",
20307 computed: "asSpecified",
20308 order: "perGrammar",
20309 status: "standard",
20310 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block"
20311},
20312 "scroll-margin-block-start": {
20313 syntax: "<length>",
20314 media: "visual",
20315 inherited: false,
20316 animationType: "byComputedValueType",
20317 percentages: "no",
20318 groups: [
20319 "CSS Scroll Snap"
20320 ],
20321 initial: "0",
20322 appliesto: "allElements",
20323 computed: "asSpecified",
20324 order: "perGrammar",
20325 status: "standard",
20326 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-start"
20327},
20328 "scroll-margin-block-end": {
20329 syntax: "<length>",
20330 media: "visual",
20331 inherited: false,
20332 animationType: "byComputedValueType",
20333 percentages: "no",
20334 groups: [
20335 "CSS Scroll Snap"
20336 ],
20337 initial: "0",
20338 appliesto: "allElements",
20339 computed: "asSpecified",
20340 order: "perGrammar",
20341 status: "standard",
20342 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-end"
20343},
20344 "scroll-margin-bottom": {
20345 syntax: "<length>",
20346 media: "visual",
20347 inherited: false,
20348 animationType: "byComputedValueType",
20349 percentages: "no",
20350 groups: [
20351 "CSS Scroll Snap"
20352 ],
20353 initial: "0",
20354 appliesto: "allElements",
20355 computed: "asSpecified",
20356 order: "perGrammar",
20357 status: "standard",
20358 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-bottom"
20359},
20360 "scroll-margin-inline": {
20361 syntax: "<length>{1,2}",
20362 media: "visual",
20363 inherited: false,
20364 animationType: "byComputedValueType",
20365 percentages: "no",
20366 groups: [
20367 "CSS Scroll Snap"
20368 ],
20369 initial: "0",
20370 appliesto: "allElements",
20371 computed: "asSpecified",
20372 order: "perGrammar",
20373 status: "standard",
20374 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline"
20375},
20376 "scroll-margin-inline-start": {
20377 syntax: "<length>",
20378 media: "visual",
20379 inherited: false,
20380 animationType: "byComputedValueType",
20381 percentages: "no",
20382 groups: [
20383 "CSS Scroll Snap"
20384 ],
20385 initial: "0",
20386 appliesto: "allElements",
20387 computed: "asSpecified",
20388 order: "perGrammar",
20389 status: "standard",
20390 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-start"
20391},
20392 "scroll-margin-inline-end": {
20393 syntax: "<length>",
20394 media: "visual",
20395 inherited: false,
20396 animationType: "byComputedValueType",
20397 percentages: "no",
20398 groups: [
20399 "CSS Scroll Snap"
20400 ],
20401 initial: "0",
20402 appliesto: "allElements",
20403 computed: "asSpecified",
20404 order: "perGrammar",
20405 status: "standard",
20406 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-end"
20407},
20408 "scroll-margin-left": {
20409 syntax: "<length>",
20410 media: "visual",
20411 inherited: false,
20412 animationType: "byComputedValueType",
20413 percentages: "no",
20414 groups: [
20415 "CSS Scroll Snap"
20416 ],
20417 initial: "0",
20418 appliesto: "allElements",
20419 computed: "asSpecified",
20420 order: "perGrammar",
20421 status: "standard",
20422 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-left"
20423},
20424 "scroll-margin-right": {
20425 syntax: "<length>",
20426 media: "visual",
20427 inherited: false,
20428 animationType: "byComputedValueType",
20429 percentages: "no",
20430 groups: [
20431 "CSS Scroll Snap"
20432 ],
20433 initial: "0",
20434 appliesto: "allElements",
20435 computed: "asSpecified",
20436 order: "perGrammar",
20437 status: "standard",
20438 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-right"
20439},
20440 "scroll-margin-top": {
20441 syntax: "<length>",
20442 media: "visual",
20443 inherited: false,
20444 animationType: "byComputedValueType",
20445 percentages: "no",
20446 groups: [
20447 "CSS Scroll Snap"
20448 ],
20449 initial: "0",
20450 appliesto: "allElements",
20451 computed: "asSpecified",
20452 order: "perGrammar",
20453 status: "standard",
20454 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-margin-top"
20455},
20456 "scroll-padding": {
20457 syntax: "[ auto | <length-percentage> ]{1,4}",
20458 media: "visual",
20459 inherited: false,
20460 animationType: "byComputedValueType",
20461 percentages: "relativeToTheScrollContainersScrollport",
20462 groups: [
20463 "CSS Scroll Snap"
20464 ],
20465 initial: "auto",
20466 appliesto: "scrollContainers",
20467 computed: "asSpecified",
20468 order: "perGrammar",
20469 status: "standard",
20470 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding"
20471},
20472 "scroll-padding-block": {
20473 syntax: "[ auto | <length-percentage> ]{1,2}",
20474 media: "visual",
20475 inherited: false,
20476 animationType: "byComputedValueType",
20477 percentages: "relativeToTheScrollContainersScrollport",
20478 groups: [
20479 "CSS Scroll Snap"
20480 ],
20481 initial: "auto",
20482 appliesto: "scrollContainers",
20483 computed: "asSpecified",
20484 order: "perGrammar",
20485 status: "standard",
20486 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block"
20487},
20488 "scroll-padding-block-start": {
20489 syntax: "auto | <length-percentage>",
20490 media: "visual",
20491 inherited: false,
20492 animationType: "byComputedValueType",
20493 percentages: "relativeToTheScrollContainersScrollport",
20494 groups: [
20495 "CSS Scroll Snap"
20496 ],
20497 initial: "auto",
20498 appliesto: "scrollContainers",
20499 computed: "asSpecified",
20500 order: "perGrammar",
20501 status: "standard",
20502 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-start"
20503},
20504 "scroll-padding-block-end": {
20505 syntax: "auto | <length-percentage>",
20506 media: "visual",
20507 inherited: false,
20508 animationType: "byComputedValueType",
20509 percentages: "relativeToTheScrollContainersScrollport",
20510 groups: [
20511 "CSS Scroll Snap"
20512 ],
20513 initial: "auto",
20514 appliesto: "scrollContainers",
20515 computed: "asSpecified",
20516 order: "perGrammar",
20517 status: "standard",
20518 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-end"
20519},
20520 "scroll-padding-bottom": {
20521 syntax: "auto | <length-percentage>",
20522 media: "visual",
20523 inherited: false,
20524 animationType: "byComputedValueType",
20525 percentages: "relativeToTheScrollContainersScrollport",
20526 groups: [
20527 "CSS Scroll Snap"
20528 ],
20529 initial: "auto",
20530 appliesto: "scrollContainers",
20531 computed: "asSpecified",
20532 order: "perGrammar",
20533 status: "standard",
20534 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-bottom"
20535},
20536 "scroll-padding-inline": {
20537 syntax: "[ auto | <length-percentage> ]{1,2}",
20538 media: "visual",
20539 inherited: false,
20540 animationType: "byComputedValueType",
20541 percentages: "relativeToTheScrollContainersScrollport",
20542 groups: [
20543 "CSS Scroll Snap"
20544 ],
20545 initial: "auto",
20546 appliesto: "scrollContainers",
20547 computed: "asSpecified",
20548 order: "perGrammar",
20549 status: "standard",
20550 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline"
20551},
20552 "scroll-padding-inline-start": {
20553 syntax: "auto | <length-percentage>",
20554 media: "visual",
20555 inherited: false,
20556 animationType: "byComputedValueType",
20557 percentages: "relativeToTheScrollContainersScrollport",
20558 groups: [
20559 "CSS Scroll Snap"
20560 ],
20561 initial: "auto",
20562 appliesto: "scrollContainers",
20563 computed: "asSpecified",
20564 order: "perGrammar",
20565 status: "standard",
20566 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-start"
20567},
20568 "scroll-padding-inline-end": {
20569 syntax: "auto | <length-percentage>",
20570 media: "visual",
20571 inherited: false,
20572 animationType: "byComputedValueType",
20573 percentages: "relativeToTheScrollContainersScrollport",
20574 groups: [
20575 "CSS Scroll Snap"
20576 ],
20577 initial: "auto",
20578 appliesto: "scrollContainers",
20579 computed: "asSpecified",
20580 order: "perGrammar",
20581 status: "standard",
20582 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-end"
20583},
20584 "scroll-padding-left": {
20585 syntax: "auto | <length-percentage>",
20586 media: "visual",
20587 inherited: false,
20588 animationType: "byComputedValueType",
20589 percentages: "relativeToTheScrollContainersScrollport",
20590 groups: [
20591 "CSS Scroll Snap"
20592 ],
20593 initial: "auto",
20594 appliesto: "scrollContainers",
20595 computed: "asSpecified",
20596 order: "perGrammar",
20597 status: "standard",
20598 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-left"
20599},
20600 "scroll-padding-right": {
20601 syntax: "auto | <length-percentage>",
20602 media: "visual",
20603 inherited: false,
20604 animationType: "byComputedValueType",
20605 percentages: "relativeToTheScrollContainersScrollport",
20606 groups: [
20607 "CSS Scroll Snap"
20608 ],
20609 initial: "auto",
20610 appliesto: "scrollContainers",
20611 computed: "asSpecified",
20612 order: "perGrammar",
20613 status: "standard",
20614 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-right"
20615},
20616 "scroll-padding-top": {
20617 syntax: "auto | <length-percentage>",
20618 media: "visual",
20619 inherited: false,
20620 animationType: "byComputedValueType",
20621 percentages: "relativeToTheScrollContainersScrollport",
20622 groups: [
20623 "CSS Scroll Snap"
20624 ],
20625 initial: "auto",
20626 appliesto: "scrollContainers",
20627 computed: "asSpecified",
20628 order: "perGrammar",
20629 status: "standard",
20630 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-padding-top"
20631},
20632 "scroll-snap-align": {
20633 syntax: "[ none | start | end | center ]{1,2}",
20634 media: "visual",
20635 inherited: false,
20636 animationType: "discrete",
20637 percentages: "no",
20638 groups: [
20639 "CSS Scroll Snap"
20640 ],
20641 initial: "none",
20642 appliesto: "allElements",
20643 computed: "asSpecified",
20644 order: "perGrammar",
20645 status: "standard",
20646 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-align"
20647},
20648 "scroll-snap-coordinate": {
20649 syntax: "none | <position>#",
20650 media: "interactive",
20651 inherited: false,
20652 animationType: "position",
20653 percentages: "referToBorderBox",
20654 groups: [
20655 "CSS Scroll Snap"
20656 ],
20657 initial: "none",
20658 appliesto: "allElements",
20659 computed: "asSpecifiedRelativeToAbsoluteLengths",
20660 order: "uniqueOrder",
20661 status: "obsolete",
20662 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-coordinate"
20663},
20664 "scroll-snap-destination": {
20665 syntax: "<position>",
20666 media: "interactive",
20667 inherited: false,
20668 animationType: "position",
20669 percentages: "relativeToScrollContainerPaddingBoxAxis",
20670 groups: [
20671 "CSS Scroll Snap"
20672 ],
20673 initial: "0px 0px",
20674 appliesto: "scrollContainers",
20675 computed: "asSpecifiedRelativeToAbsoluteLengths",
20676 order: "uniqueOrder",
20677 status: "obsolete",
20678 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-destination"
20679},
20680 "scroll-snap-points-x": {
20681 syntax: "none | repeat( <length-percentage> )",
20682 media: "interactive",
20683 inherited: false,
20684 animationType: "discrete",
20685 percentages: "relativeToScrollContainerPaddingBoxAxis",
20686 groups: [
20687 "CSS Scroll Snap"
20688 ],
20689 initial: "none",
20690 appliesto: "scrollContainers",
20691 computed: "asSpecifiedRelativeToAbsoluteLengths",
20692 order: "uniqueOrder",
20693 status: "obsolete",
20694 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-points-x"
20695},
20696 "scroll-snap-points-y": {
20697 syntax: "none | repeat( <length-percentage> )",
20698 media: "interactive",
20699 inherited: false,
20700 animationType: "discrete",
20701 percentages: "relativeToScrollContainerPaddingBoxAxis",
20702 groups: [
20703 "CSS Scroll Snap"
20704 ],
20705 initial: "none",
20706 appliesto: "scrollContainers",
20707 computed: "asSpecifiedRelativeToAbsoluteLengths",
20708 order: "uniqueOrder",
20709 status: "obsolete",
20710 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-points-y"
20711},
20712 "scroll-snap-stop": {
20713 syntax: "normal | always",
20714 media: "visual",
20715 inherited: false,
20716 animationType: "discrete",
20717 percentages: "no",
20718 groups: [
20719 "CSS Scroll Snap"
20720 ],
20721 initial: "normal",
20722 appliesto: "allElements",
20723 computed: "asSpecified",
20724 order: "perGrammar",
20725 status: "standard",
20726 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-stop"
20727},
20728 "scroll-snap-type": {
20729 syntax: "none | [ x | y | block | inline | both ] [ mandatory | proximity ]?",
20730 media: "interactive",
20731 inherited: false,
20732 animationType: "discrete",
20733 percentages: "no",
20734 groups: [
20735 "CSS Scroll Snap"
20736 ],
20737 initial: "none",
20738 appliesto: "allElements",
20739 computed: "asSpecified",
20740 order: "uniqueOrder",
20741 status: "standard",
20742 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type"
20743},
20744 "scroll-snap-type-x": {
20745 syntax: "none | mandatory | proximity",
20746 media: "interactive",
20747 inherited: false,
20748 animationType: "discrete",
20749 percentages: "no",
20750 groups: [
20751 "CSS Scroll Snap"
20752 ],
20753 initial: "none",
20754 appliesto: "scrollContainers",
20755 computed: "asSpecified",
20756 order: "uniqueOrder",
20757 status: "obsolete",
20758 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type-x"
20759},
20760 "scroll-snap-type-y": {
20761 syntax: "none | mandatory | proximity",
20762 media: "interactive",
20763 inherited: false,
20764 animationType: "discrete",
20765 percentages: "no",
20766 groups: [
20767 "CSS Scroll Snap"
20768 ],
20769 initial: "none",
20770 appliesto: "scrollContainers",
20771 computed: "asSpecified",
20772 order: "uniqueOrder",
20773 status: "obsolete",
20774 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type-y"
20775},
20776 "shape-image-threshold": {
20777 syntax: "<alpha-value>",
20778 media: "visual",
20779 inherited: false,
20780 animationType: "number",
20781 percentages: "no",
20782 groups: [
20783 "CSS Shapes"
20784 ],
20785 initial: "0.0",
20786 appliesto: "floats",
20787 computed: "specifiedValueNumberClipped0To1",
20788 order: "uniqueOrder",
20789 status: "standard",
20790 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-image-threshold"
20791},
20792 "shape-margin": {
20793 syntax: "<length-percentage>",
20794 media: "visual",
20795 inherited: false,
20796 animationType: "lpc",
20797 percentages: "referToWidthOfContainingBlock",
20798 groups: [
20799 "CSS Shapes"
20800 ],
20801 initial: "0",
20802 appliesto: "floats",
20803 computed: "asSpecifiedRelativeToAbsoluteLengths",
20804 order: "uniqueOrder",
20805 status: "standard",
20806 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-margin"
20807},
20808 "shape-outside": {
20809 syntax: "none | <shape-box> || <basic-shape> | <image>",
20810 media: "visual",
20811 inherited: false,
20812 animationType: "basicShapeOtherwiseNo",
20813 percentages: "no",
20814 groups: [
20815 "CSS Shapes"
20816 ],
20817 initial: "none",
20818 appliesto: "floats",
20819 computed: "asDefinedForBasicShapeWithAbsoluteURIOtherwiseAsSpecified",
20820 order: "uniqueOrder",
20821 status: "standard",
20822 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/shape-outside"
20823},
20824 "tab-size": {
20825 syntax: "<integer> | <length>",
20826 media: "visual",
20827 inherited: true,
20828 animationType: "length",
20829 percentages: "no",
20830 groups: [
20831 "CSS Text"
20832 ],
20833 initial: "8",
20834 appliesto: "blockContainers",
20835 computed: "specifiedIntegerOrAbsoluteLength",
20836 order: "uniqueOrder",
20837 status: "standard",
20838 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/tab-size"
20839},
20840 "table-layout": {
20841 syntax: "auto | fixed",
20842 media: "visual",
20843 inherited: false,
20844 animationType: "discrete",
20845 percentages: "no",
20846 groups: [
20847 "CSS Table"
20848 ],
20849 initial: "auto",
20850 appliesto: "tableElements",
20851 computed: "asSpecified",
20852 order: "uniqueOrder",
20853 status: "standard",
20854 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/table-layout"
20855},
20856 "text-align": {
20857 syntax: "start | end | left | right | center | justify | match-parent",
20858 media: "visual",
20859 inherited: true,
20860 animationType: "discrete",
20861 percentages: "no",
20862 groups: [
20863 "CSS Text"
20864 ],
20865 initial: "startOrNamelessValueIfLTRRightIfRTL",
20866 appliesto: "blockContainers",
20867 computed: "asSpecifiedExceptMatchParent",
20868 order: "orderOfAppearance",
20869 alsoAppliesTo: [
20870 "::placeholder"
20871 ],
20872 status: "standard",
20873 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-align"
20874},
20875 "text-align-last": {
20876 syntax: "auto | start | end | left | right | center | justify",
20877 media: "visual",
20878 inherited: true,
20879 animationType: "discrete",
20880 percentages: "no",
20881 groups: [
20882 "CSS Text"
20883 ],
20884 initial: "auto",
20885 appliesto: "blockContainers",
20886 computed: "asSpecified",
20887 order: "uniqueOrder",
20888 status: "standard",
20889 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-align-last"
20890},
20891 "text-combine-upright": {
20892 syntax: "none | all | [ digits <integer>? ]",
20893 media: "visual",
20894 inherited: true,
20895 animationType: "notAnimatable",
20896 percentages: "no",
20897 groups: [
20898 "CSS Writing Modes"
20899 ],
20900 initial: "none",
20901 appliesto: "nonReplacedInlineElements",
20902 computed: "keywordPlusIntegerIfDigits",
20903 order: "uniqueOrder",
20904 status: "standard",
20905 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-combine-upright"
20906},
20907 "text-decoration": {
20908 syntax: "<'text-decoration-line'> || <'text-decoration-style'> || <'text-decoration-color'> || <'text-decoration-thickness'>",
20909 media: "visual",
20910 inherited: false,
20911 animationType: [
20912 "text-decoration-color",
20913 "text-decoration-style",
20914 "text-decoration-line",
20915 "text-decoration-thickness"
20916 ],
20917 percentages: "no",
20918 groups: [
20919 "CSS Text Decoration"
20920 ],
20921 initial: [
20922 "text-decoration-color",
20923 "text-decoration-style",
20924 "text-decoration-line"
20925 ],
20926 appliesto: "allElements",
20927 computed: [
20928 "text-decoration-line",
20929 "text-decoration-style",
20930 "text-decoration-color",
20931 "text-decoration-thickness"
20932 ],
20933 order: "orderOfAppearance",
20934 alsoAppliesTo: [
20935 "::first-letter",
20936 "::first-line",
20937 "::placeholder"
20938 ],
20939 status: "standard",
20940 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration"
20941},
20942 "text-decoration-color": {
20943 syntax: "<color>",
20944 media: "visual",
20945 inherited: false,
20946 animationType: "color",
20947 percentages: "no",
20948 groups: [
20949 "CSS Text Decoration"
20950 ],
20951 initial: "currentcolor",
20952 appliesto: "allElements",
20953 computed: "computedColor",
20954 order: "uniqueOrder",
20955 alsoAppliesTo: [
20956 "::first-letter",
20957 "::first-line",
20958 "::placeholder"
20959 ],
20960 status: "standard",
20961 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-color"
20962},
20963 "text-decoration-line": {
20964 syntax: "none | [ underline || overline || line-through || blink ] | spelling-error | grammar-error",
20965 media: "visual",
20966 inherited: false,
20967 animationType: "discrete",
20968 percentages: "no",
20969 groups: [
20970 "CSS Text Decoration"
20971 ],
20972 initial: "none",
20973 appliesto: "allElements",
20974 computed: "asSpecified",
20975 order: "orderOfAppearance",
20976 alsoAppliesTo: [
20977 "::first-letter",
20978 "::first-line",
20979 "::placeholder"
20980 ],
20981 status: "standard",
20982 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-line"
20983},
20984 "text-decoration-skip": {
20985 syntax: "none | [ objects || [ spaces | [ leading-spaces || trailing-spaces ] ] || edges || box-decoration ]",
20986 media: "visual",
20987 inherited: true,
20988 animationType: "discrete",
20989 percentages: "no",
20990 groups: [
20991 "CSS Text Decoration"
20992 ],
20993 initial: "objects",
20994 appliesto: "allElements",
20995 computed: "asSpecified",
20996 order: "orderOfAppearance",
20997 status: "experimental",
20998 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip"
20999},
21000 "text-decoration-skip-ink": {
21001 syntax: "auto | all | none",
21002 media: "visual",
21003 inherited: true,
21004 animationType: "discrete",
21005 percentages: "no",
21006 groups: [
21007 "CSS Text Decoration"
21008 ],
21009 initial: "auto",
21010 appliesto: "allElements",
21011 computed: "asSpecified",
21012 order: "orderOfAppearance",
21013 status: "standard",
21014 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip-ink"
21015},
21016 "text-decoration-style": {
21017 syntax: "solid | double | dotted | dashed | wavy",
21018 media: "visual",
21019 inherited: false,
21020 animationType: "discrete",
21021 percentages: "no",
21022 groups: [
21023 "CSS Text Decoration"
21024 ],
21025 initial: "solid",
21026 appliesto: "allElements",
21027 computed: "asSpecified",
21028 order: "uniqueOrder",
21029 alsoAppliesTo: [
21030 "::first-letter",
21031 "::first-line",
21032 "::placeholder"
21033 ],
21034 status: "standard",
21035 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-style"
21036},
21037 "text-decoration-thickness": {
21038 syntax: "auto | from-font | <length> | <percentage> ",
21039 media: "visual",
21040 inherited: false,
21041 animationType: "byComputedValueType",
21042 percentages: "referToElementFontSize",
21043 groups: [
21044 "CSS Text Decoration"
21045 ],
21046 initial: "auto",
21047 appliesto: "allElements",
21048 computed: "asSpecified",
21049 order: "uniqueOrder",
21050 alsoAppliesTo: [
21051 "::first-letter",
21052 "::first-line",
21053 "::placeholder"
21054 ],
21055 status: "standard",
21056 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-decoration-thickness"
21057},
21058 "text-emphasis": {
21059 syntax: "<'text-emphasis-style'> || <'text-emphasis-color'>",
21060 media: "visual",
21061 inherited: false,
21062 animationType: [
21063 "text-emphasis-color",
21064 "text-emphasis-style"
21065 ],
21066 percentages: "no",
21067 groups: [
21068 "CSS Text Decoration"
21069 ],
21070 initial: [
21071 "text-emphasis-style",
21072 "text-emphasis-color"
21073 ],
21074 appliesto: "allElements",
21075 computed: [
21076 "text-emphasis-style",
21077 "text-emphasis-color"
21078 ],
21079 order: "orderOfAppearance",
21080 status: "standard",
21081 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis"
21082},
21083 "text-emphasis-color": {
21084 syntax: "<color>",
21085 media: "visual",
21086 inherited: false,
21087 animationType: "color",
21088 percentages: "no",
21089 groups: [
21090 "CSS Text Decoration"
21091 ],
21092 initial: "currentcolor",
21093 appliesto: "allElements",
21094 computed: "computedColor",
21095 order: "uniqueOrder",
21096 status: "standard",
21097 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-color"
21098},
21099 "text-emphasis-position": {
21100 syntax: "[ over | under ] && [ right | left ]",
21101 media: "visual",
21102 inherited: false,
21103 animationType: "discrete",
21104 percentages: "no",
21105 groups: [
21106 "CSS Text Decoration"
21107 ],
21108 initial: "over right",
21109 appliesto: "allElements",
21110 computed: "asSpecified",
21111 order: "uniqueOrder",
21112 status: "standard",
21113 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-position"
21114},
21115 "text-emphasis-style": {
21116 syntax: "none | [ [ filled | open ] || [ dot | circle | double-circle | triangle | sesame ] ] | <string>",
21117 media: "visual",
21118 inherited: false,
21119 animationType: "discrete",
21120 percentages: "no",
21121 groups: [
21122 "CSS Text Decoration"
21123 ],
21124 initial: "none",
21125 appliesto: "allElements",
21126 computed: "asSpecified",
21127 order: "uniqueOrder",
21128 status: "standard",
21129 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-emphasis-style"
21130},
21131 "text-indent": {
21132 syntax: "<length-percentage> && hanging? && each-line?",
21133 media: "visual",
21134 inherited: true,
21135 animationType: "lpc",
21136 percentages: "referToWidthOfContainingBlock",
21137 groups: [
21138 "CSS Text"
21139 ],
21140 initial: "0",
21141 appliesto: "blockContainers",
21142 computed: "percentageOrAbsoluteLengthPlusKeywords",
21143 order: "lengthOrPercentageBeforeKeywords",
21144 status: "standard",
21145 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-indent"
21146},
21147 "text-justify": {
21148 syntax: "auto | inter-character | inter-word | none",
21149 media: "visual",
21150 inherited: true,
21151 animationType: "discrete",
21152 percentages: "no",
21153 groups: [
21154 "CSS Text"
21155 ],
21156 initial: "auto",
21157 appliesto: "inlineLevelAndTableCellElements",
21158 computed: "asSpecified",
21159 order: "uniqueOrder",
21160 status: "standard",
21161 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-justify"
21162},
21163 "text-orientation": {
21164 syntax: "mixed | upright | sideways",
21165 media: "visual",
21166 inherited: true,
21167 animationType: "discrete",
21168 percentages: "no",
21169 groups: [
21170 "CSS Writing Modes"
21171 ],
21172 initial: "mixed",
21173 appliesto: "allElementsExceptTableRowGroupsRowsColumnGroupsAndColumns",
21174 computed: "asSpecified",
21175 order: "uniqueOrder",
21176 status: "standard",
21177 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-orientation"
21178},
21179 "text-overflow": {
21180 syntax: "[ clip | ellipsis | <string> ]{1,2}",
21181 media: "visual",
21182 inherited: false,
21183 animationType: "discrete",
21184 percentages: "no",
21185 groups: [
21186 "CSS Basic User Interface"
21187 ],
21188 initial: "clip",
21189 appliesto: "blockContainerElements",
21190 computed: "asSpecified",
21191 order: "uniqueOrder",
21192 alsoAppliesTo: [
21193 "::placeholder"
21194 ],
21195 status: "standard",
21196 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-overflow"
21197},
21198 "text-rendering": {
21199 syntax: "auto | optimizeSpeed | optimizeLegibility | geometricPrecision",
21200 media: "visual",
21201 inherited: true,
21202 animationType: "discrete",
21203 percentages: "no",
21204 groups: [
21205 "CSS Miscellaneous"
21206 ],
21207 initial: "auto",
21208 appliesto: "textElements",
21209 computed: "asSpecified",
21210 order: "uniqueOrder",
21211 status: "standard",
21212 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-rendering"
21213},
21214 "text-shadow": {
21215 syntax: "none | <shadow-t>#",
21216 media: "visual",
21217 inherited: true,
21218 animationType: "shadowList",
21219 percentages: "no",
21220 groups: [
21221 "CSS Text Decoration"
21222 ],
21223 initial: "none",
21224 appliesto: "allElements",
21225 computed: "colorPlusThreeAbsoluteLengths",
21226 order: "uniqueOrder",
21227 alsoAppliesTo: [
21228 "::first-letter",
21229 "::first-line",
21230 "::placeholder"
21231 ],
21232 status: "standard",
21233 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-shadow"
21234},
21235 "text-size-adjust": {
21236 syntax: "none | auto | <percentage>",
21237 media: "visual",
21238 inherited: true,
21239 animationType: "discrete",
21240 percentages: "referToSizeOfFont",
21241 groups: [
21242 "CSS Text"
21243 ],
21244 initial: "autoForSmartphoneBrowsersSupportingInflation",
21245 appliesto: "allElements",
21246 computed: "asSpecified",
21247 order: "uniqueOrder",
21248 status: "experimental",
21249 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-size-adjust"
21250},
21251 "text-transform": {
21252 syntax: "none | capitalize | uppercase | lowercase | full-width | full-size-kana",
21253 media: "visual",
21254 inherited: true,
21255 animationType: "discrete",
21256 percentages: "no",
21257 groups: [
21258 "CSS Text"
21259 ],
21260 initial: "none",
21261 appliesto: "allElements",
21262 computed: "asSpecified",
21263 order: "uniqueOrder",
21264 alsoAppliesTo: [
21265 "::first-letter",
21266 "::first-line",
21267 "::placeholder"
21268 ],
21269 status: "standard",
21270 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-transform"
21271},
21272 "text-underline-offset": {
21273 syntax: "auto | <length> | <percentage> ",
21274 media: "visual",
21275 inherited: true,
21276 animationType: "byComputedValueType",
21277 percentages: "referToElementFontSize",
21278 groups: [
21279 "CSS Text Decoration"
21280 ],
21281 initial: "auto",
21282 appliesto: "allElements",
21283 computed: "asSpecified",
21284 order: "uniqueOrder",
21285 alsoAppliesTo: [
21286 "::first-letter",
21287 "::first-line",
21288 "::placeholder"
21289 ],
21290 status: "standard",
21291 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-underline-offset"
21292},
21293 "text-underline-position": {
21294 syntax: "auto | from-font | [ under || [ left | right ] ]",
21295 media: "visual",
21296 inherited: true,
21297 animationType: "discrete",
21298 percentages: "no",
21299 groups: [
21300 "CSS Text Decoration"
21301 ],
21302 initial: "auto",
21303 appliesto: "allElements",
21304 computed: "asSpecified",
21305 order: "orderOfAppearance",
21306 status: "standard",
21307 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/text-underline-position"
21308},
21309 top: top,
21310 "touch-action": {
21311 syntax: "auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] || pinch-zoom ] | manipulation",
21312 media: "visual",
21313 inherited: false,
21314 animationType: "discrete",
21315 percentages: "no",
21316 groups: [
21317 "Pointer Events"
21318 ],
21319 initial: "auto",
21320 appliesto: "allElementsExceptNonReplacedInlineElementsTableRowsColumnsRowColumnGroups",
21321 computed: "asSpecified",
21322 order: "uniqueOrder",
21323 status: "standard",
21324 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/touch-action"
21325},
21326 transform: transform,
21327 "transform-box": {
21328 syntax: "content-box | border-box | fill-box | stroke-box | view-box",
21329 media: "visual",
21330 inherited: false,
21331 animationType: "discrete",
21332 percentages: "no",
21333 groups: [
21334 "CSS Transforms"
21335 ],
21336 initial: "view-box",
21337 appliesto: "transformableElements",
21338 computed: "asSpecified",
21339 order: "perGrammar",
21340 status: "standard",
21341 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-box"
21342},
21343 "transform-origin": {
21344 syntax: "[ <length-percentage> | left | center | right | top | bottom ] | [ [ <length-percentage> | left | center | right ] && [ <length-percentage> | top | center | bottom ] ] <length>?",
21345 media: "visual",
21346 inherited: false,
21347 animationType: "simpleListOfLpc",
21348 percentages: "referToSizeOfBoundingBox",
21349 groups: [
21350 "CSS Transforms"
21351 ],
21352 initial: "50% 50% 0",
21353 appliesto: "transformableElements",
21354 computed: "forLengthAbsoluteValueOtherwisePercentage",
21355 order: "oneOrTwoValuesLengthAbsoluteKeywordsPercentages",
21356 status: "standard",
21357 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-origin"
21358},
21359 "transform-style": {
21360 syntax: "flat | preserve-3d",
21361 media: "visual",
21362 inherited: false,
21363 animationType: "discrete",
21364 percentages: "no",
21365 groups: [
21366 "CSS Transforms"
21367 ],
21368 initial: "flat",
21369 appliesto: "transformableElements",
21370 computed: "asSpecified",
21371 order: "uniqueOrder",
21372 stacking: true,
21373 status: "standard",
21374 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transform-style"
21375},
21376 transition: transition,
21377 "transition-delay": {
21378 syntax: "<time>#",
21379 media: "interactive",
21380 inherited: false,
21381 animationType: "discrete",
21382 percentages: "no",
21383 groups: [
21384 "CSS Transitions"
21385 ],
21386 initial: "0s",
21387 appliesto: "allElementsAndPseudos",
21388 computed: "asSpecified",
21389 order: "uniqueOrder",
21390 status: "standard",
21391 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-delay"
21392},
21393 "transition-duration": {
21394 syntax: "<time>#",
21395 media: "interactive",
21396 inherited: false,
21397 animationType: "discrete",
21398 percentages: "no",
21399 groups: [
21400 "CSS Transitions"
21401 ],
21402 initial: "0s",
21403 appliesto: "allElementsAndPseudos",
21404 computed: "asSpecified",
21405 order: "uniqueOrder",
21406 status: "standard",
21407 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-duration"
21408},
21409 "transition-property": {
21410 syntax: "none | <single-transition-property>#",
21411 media: "visual",
21412 inherited: false,
21413 animationType: "discrete",
21414 percentages: "no",
21415 groups: [
21416 "CSS Transitions"
21417 ],
21418 initial: "all",
21419 appliesto: "allElementsAndPseudos",
21420 computed: "asSpecified",
21421 order: "uniqueOrder",
21422 status: "standard",
21423 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-property"
21424},
21425 "transition-timing-function": {
21426 syntax: "<timing-function>#",
21427 media: "interactive",
21428 inherited: false,
21429 animationType: "discrete",
21430 percentages: "no",
21431 groups: [
21432 "CSS Transitions"
21433 ],
21434 initial: "ease",
21435 appliesto: "allElementsAndPseudos",
21436 computed: "asSpecified",
21437 order: "uniqueOrder",
21438 status: "standard",
21439 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/transition-timing-function"
21440},
21441 translate: translate,
21442 "unicode-bidi": {
21443 syntax: "normal | embed | isolate | bidi-override | isolate-override | plaintext",
21444 media: "visual",
21445 inherited: false,
21446 animationType: "discrete",
21447 percentages: "no",
21448 groups: [
21449 "CSS Writing Modes"
21450 ],
21451 initial: "normal",
21452 appliesto: "allElementsSomeValuesNoEffectOnNonInlineElements",
21453 computed: "asSpecified",
21454 order: "uniqueOrder",
21455 status: "standard",
21456 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/unicode-bidi"
21457},
21458 "user-select": {
21459 syntax: "auto | text | none | contain | all",
21460 media: "visual",
21461 inherited: false,
21462 animationType: "discrete",
21463 percentages: "no",
21464 groups: [
21465 "CSS Basic User Interface"
21466 ],
21467 initial: "auto",
21468 appliesto: "allElements",
21469 computed: "asSpecified",
21470 order: "uniqueOrder",
21471 status: "nonstandard",
21472 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/user-select"
21473},
21474 "vertical-align": {
21475 syntax: "baseline | sub | super | text-top | text-bottom | middle | top | bottom | <percentage> | <length>",
21476 media: "visual",
21477 inherited: false,
21478 animationType: "length",
21479 percentages: "referToLineHeight",
21480 groups: [
21481 "CSS Table"
21482 ],
21483 initial: "baseline",
21484 appliesto: "inlineLevelAndTableCellElements",
21485 computed: "absoluteLengthOrKeyword",
21486 order: "uniqueOrder",
21487 alsoAppliesTo: [
21488 "::first-letter",
21489 "::first-line",
21490 "::placeholder"
21491 ],
21492 status: "standard",
21493 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/vertical-align"
21494},
21495 visibility: visibility,
21496 "white-space": {
21497 syntax: "normal | pre | nowrap | pre-wrap | pre-line | break-spaces",
21498 media: "visual",
21499 inherited: true,
21500 animationType: "discrete",
21501 percentages: "no",
21502 groups: [
21503 "CSS Text"
21504 ],
21505 initial: "normal",
21506 appliesto: "allElements",
21507 computed: "asSpecified",
21508 order: "uniqueOrder",
21509 status: "standard",
21510 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/white-space"
21511},
21512 widows: widows,
21513 width: width,
21514 "will-change": {
21515 syntax: "auto | <animateable-feature>#",
21516 media: "all",
21517 inherited: false,
21518 animationType: "discrete",
21519 percentages: "no",
21520 groups: [
21521 "CSS Will Change"
21522 ],
21523 initial: "auto",
21524 appliesto: "allElements",
21525 computed: "asSpecified",
21526 order: "uniqueOrder",
21527 status: "standard",
21528 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/will-change"
21529},
21530 "word-break": {
21531 syntax: "normal | break-all | keep-all | break-word",
21532 media: "visual",
21533 inherited: true,
21534 animationType: "discrete",
21535 percentages: "no",
21536 groups: [
21537 "CSS Text"
21538 ],
21539 initial: "normal",
21540 appliesto: "allElements",
21541 computed: "asSpecified",
21542 order: "uniqueOrder",
21543 status: "standard",
21544 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/word-break"
21545},
21546 "word-spacing": {
21547 syntax: "normal | <length-percentage>",
21548 media: "visual",
21549 inherited: true,
21550 animationType: "length",
21551 percentages: "referToWidthOfAffectedGlyph",
21552 groups: [
21553 "CSS Text"
21554 ],
21555 initial: "normal",
21556 appliesto: "allElements",
21557 computed: "optimumMinAndMaxValueOfAbsoluteLengthPercentageOrNormal",
21558 order: "uniqueOrder",
21559 alsoAppliesTo: [
21560 "::first-letter",
21561 "::first-line",
21562 "::placeholder"
21563 ],
21564 status: "standard",
21565 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/word-spacing"
21566},
21567 "word-wrap": {
21568 syntax: "normal | break-word",
21569 media: "visual",
21570 inherited: true,
21571 animationType: "discrete",
21572 percentages: "no",
21573 groups: [
21574 "CSS Text"
21575 ],
21576 initial: "normal",
21577 appliesto: "nonReplacedInlineElements",
21578 computed: "asSpecified",
21579 order: "uniqueOrder",
21580 status: "standard",
21581 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/overflow-wrap"
21582},
21583 "writing-mode": {
21584 syntax: "horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr",
21585 media: "visual",
21586 inherited: true,
21587 animationType: "discrete",
21588 percentages: "no",
21589 groups: [
21590 "CSS Writing Modes"
21591 ],
21592 initial: "horizontal-tb",
21593 appliesto: "allElementsExceptTableRowColumnGroupsTableRowsColumns",
21594 computed: "asSpecified",
21595 order: "uniqueOrder",
21596 status: "standard",
21597 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/writing-mode"
21598},
21599 "z-index": {
21600 syntax: "auto | <integer>",
21601 media: "visual",
21602 inherited: false,
21603 animationType: "integer",
21604 percentages: "no",
21605 groups: [
21606 "CSS Positioning"
21607 ],
21608 initial: "auto",
21609 appliesto: "positionedElements",
21610 computed: "asSpecified",
21611 order: "uniqueOrder",
21612 stacking: true,
21613 status: "standard",
21614 mdn_url: "https://developer.mozilla.org/docs/Web/CSS/z-index"
21615},
21616 zoom: zoom
21617};
21618
21619var attachment = {
21620 syntax: "scroll | fixed | local"
21621};
21622var box = {
21623 syntax: "border-box | padding-box | content-box"
21624};
21625var color = {
21626 syntax: "<rgb()> | <rgba()> | <hsl()> | <hsla()> | <hex-color> | <named-color> | currentcolor | <deprecated-system-color>"
21627};
21628var combinator = {
21629 syntax: "'>' | '+' | '~' | [ '||' ]"
21630};
21631var gradient = {
21632 syntax: "<linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()> | <conic-gradient()>"
21633};
21634var hue = {
21635 syntax: "<number> | <angle>"
21636};
21637var image = {
21638 syntax: "<url> | <image()> | <image-set()> | <element()> | <paint()> | <cross-fade()> | <gradient>"
21639};
21640var nth$1 = {
21641 syntax: "<an-plus-b> | even | odd"
21642};
21643var position = {
21644 syntax: "[ [ left | center | right ] || [ top | center | bottom ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]? | [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ] ]"
21645};
21646var quote = {
21647 syntax: "open-quote | close-quote | no-open-quote | no-close-quote"
21648};
21649var shadow = {
21650 syntax: "inset? && <length>{2,4} && <color>?"
21651};
21652var shape = {
21653 syntax: "rect(<top>, <right>, <bottom>, <left>)"
21654};
21655var size = {
21656 syntax: "closest-side | farthest-side | closest-corner | farthest-corner | <length> | <length-percentage>{2}"
21657};
21658var symbol = {
21659 syntax: "<string> | <image> | <custom-ident>"
21660};
21661var target = {
21662 syntax: "<target-counter()> | <target-counters()> | <target-text()>"
21663};
21664var require$$2 = {
21665 "absolute-size": {
21666 syntax: "xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large"
21667},
21668 "alpha-value": {
21669 syntax: "<number> | <percentage>"
21670},
21671 "angle-percentage": {
21672 syntax: "<angle> | <percentage>"
21673},
21674 "angular-color-hint": {
21675 syntax: "<angle-percentage>"
21676},
21677 "angular-color-stop": {
21678 syntax: "<color> && <color-stop-angle>?"
21679},
21680 "angular-color-stop-list": {
21681 syntax: "[ <angular-color-stop> [, <angular-color-hint>]? ]# , <angular-color-stop>"
21682},
21683 "animateable-feature": {
21684 syntax: "scroll-position | contents | <custom-ident>"
21685},
21686 attachment: attachment,
21687 "attr()": {
21688 syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
21689},
21690 "attr-matcher": {
21691 syntax: "[ '~' | '|' | '^' | '$' | '*' ]? '='"
21692},
21693 "attr-modifier": {
21694 syntax: "i | s"
21695},
21696 "attribute-selector": {
21697 syntax: "'[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'"
21698},
21699 "auto-repeat": {
21700 syntax: "repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )"
21701},
21702 "auto-track-list": {
21703 syntax: "[ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <auto-repeat>\n[ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>?"
21704},
21705 "baseline-position": {
21706 syntax: "[ first | last ]? baseline"
21707},
21708 "basic-shape": {
21709 syntax: "<inset()> | <circle()> | <ellipse()> | <polygon()> | <path()>"
21710},
21711 "bg-image": {
21712 syntax: "none | <image>"
21713},
21714 "bg-layer": {
21715 syntax: "<bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>"
21716},
21717 "bg-position": {
21718 syntax: "[ [ left | center | right | top | bottom | <length-percentage> ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | [ center | [ left | right ] <length-percentage>? ] && [ center | [ top | bottom ] <length-percentage>? ] ]"
21719},
21720 "bg-size": {
21721 syntax: "[ <length-percentage> | auto ]{1,2} | cover | contain"
21722},
21723 "blur()": {
21724 syntax: "blur( <length> )"
21725},
21726 "blend-mode": {
21727 syntax: "normal | multiply | screen | overlay | darken | lighten | color-dodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity"
21728},
21729 box: box,
21730 "brightness()": {
21731 syntax: "brightness( <number-percentage> )"
21732},
21733 "calc()": {
21734 syntax: "calc( <calc-sum> )"
21735},
21736 "calc-sum": {
21737 syntax: "<calc-product> [ [ '+' | '-' ] <calc-product> ]*"
21738},
21739 "calc-product": {
21740 syntax: "<calc-value> [ '*' <calc-value> | '/' <number> ]*"
21741},
21742 "calc-value": {
21743 syntax: "<number> | <dimension> | <percentage> | ( <calc-sum> )"
21744},
21745 "cf-final-image": {
21746 syntax: "<image> | <color>"
21747},
21748 "cf-mixing-image": {
21749 syntax: "<percentage>? && <image>"
21750},
21751 "circle()": {
21752 syntax: "circle( [ <shape-radius> ]? [ at <position> ]? )"
21753},
21754 "clamp()": {
21755 syntax: "clamp( <calc-sum>#{3} )"
21756},
21757 "class-selector": {
21758 syntax: "'.' <ident-token>"
21759},
21760 "clip-source": {
21761 syntax: "<url>"
21762},
21763 color: color,
21764 "color-stop": {
21765 syntax: "<color-stop-length> | <color-stop-angle>"
21766},
21767 "color-stop-angle": {
21768 syntax: "<angle-percentage>{1,2}"
21769},
21770 "color-stop-length": {
21771 syntax: "<length-percentage>{1,2}"
21772},
21773 "color-stop-list": {
21774 syntax: "[ <linear-color-stop> [, <linear-color-hint>]? ]# , <linear-color-stop>"
21775},
21776 combinator: combinator,
21777 "common-lig-values": {
21778 syntax: "[ common-ligatures | no-common-ligatures ]"
21779},
21780 "compat-auto": {
21781 syntax: "searchfield | textarea | push-button | slider-horizontal | checkbox | radio | square-button | menulist | listbox | meter | progress-bar | button"
21782},
21783 "composite-style": {
21784 syntax: "clear | copy | source-over | source-in | source-out | source-atop | destination-over | destination-in | destination-out | destination-atop | xor"
21785},
21786 "compositing-operator": {
21787 syntax: "add | subtract | intersect | exclude"
21788},
21789 "compound-selector": {
21790 syntax: "[ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!"
21791},
21792 "compound-selector-list": {
21793 syntax: "<compound-selector>#"
21794},
21795 "complex-selector": {
21796 syntax: "<compound-selector> [ <combinator>? <compound-selector> ]*"
21797},
21798 "complex-selector-list": {
21799 syntax: "<complex-selector>#"
21800},
21801 "conic-gradient()": {
21802 syntax: "conic-gradient( [ from <angle> ]? [ at <position> ]?, <angular-color-stop-list> )"
21803},
21804 "contextual-alt-values": {
21805 syntax: "[ contextual | no-contextual ]"
21806},
21807 "content-distribution": {
21808 syntax: "space-between | space-around | space-evenly | stretch"
21809},
21810 "content-list": {
21811 syntax: "[ <string> | contents | <image> | <quote> | <target> | <leader()> ]+"
21812},
21813 "content-position": {
21814 syntax: "center | start | end | flex-start | flex-end"
21815},
21816 "content-replacement": {
21817 syntax: "<image>"
21818},
21819 "contrast()": {
21820 syntax: "contrast( [ <number-percentage> ] )"
21821},
21822 "counter()": {
21823 syntax: "counter( <custom-ident>, <counter-style>? )"
21824},
21825 "counter-style": {
21826 syntax: "<counter-style-name> | symbols()"
21827},
21828 "counter-style-name": {
21829 syntax: "<custom-ident>"
21830},
21831 "counters()": {
21832 syntax: "counters( <custom-ident>, <string>, <counter-style>? )"
21833},
21834 "cross-fade()": {
21835 syntax: "cross-fade( <cf-mixing-image> , <cf-final-image>? )"
21836},
21837 "cubic-bezier-timing-function": {
21838 syntax: "ease | ease-in | ease-out | ease-in-out | cubic-bezier(<number [0,1]>, <number>, <number [0,1]>, <number>)"
21839},
21840 "deprecated-system-color": {
21841 syntax: "ActiveBorder | ActiveCaption | AppWorkspace | Background | ButtonFace | ButtonHighlight | ButtonShadow | ButtonText | CaptionText | GrayText | Highlight | HighlightText | InactiveBorder | InactiveCaption | InactiveCaptionText | InfoBackground | InfoText | Menu | MenuText | Scrollbar | ThreeDDarkShadow | ThreeDFace | ThreeDHighlight | ThreeDLightShadow | ThreeDShadow | Window | WindowFrame | WindowText"
21842},
21843 "discretionary-lig-values": {
21844 syntax: "[ discretionary-ligatures | no-discretionary-ligatures ]"
21845},
21846 "display-box": {
21847 syntax: "contents | none"
21848},
21849 "display-inside": {
21850 syntax: "flow | flow-root | table | flex | grid | ruby"
21851},
21852 "display-internal": {
21853 syntax: "table-row-group | table-header-group | table-footer-group | table-row | table-cell | table-column-group | table-column | table-caption | ruby-base | ruby-text | ruby-base-container | ruby-text-container"
21854},
21855 "display-legacy": {
21856 syntax: "inline-block | inline-list-item | inline-table | inline-flex | inline-grid"
21857},
21858 "display-listitem": {
21859 syntax: "<display-outside>? && [ flow | flow-root ]? && list-item"
21860},
21861 "display-outside": {
21862 syntax: "block | inline | run-in"
21863},
21864 "drop-shadow()": {
21865 syntax: "drop-shadow( <length>{2,3} <color>? )"
21866},
21867 "east-asian-variant-values": {
21868 syntax: "[ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]"
21869},
21870 "east-asian-width-values": {
21871 syntax: "[ full-width | proportional-width ]"
21872},
21873 "element()": {
21874 syntax: "element( <id-selector> )"
21875},
21876 "ellipse()": {
21877 syntax: "ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )"
21878},
21879 "ending-shape": {
21880 syntax: "circle | ellipse"
21881},
21882 "env()": {
21883 syntax: "env( <custom-ident> , <declaration-value>? )"
21884},
21885 "explicit-track-list": {
21886 syntax: "[ <line-names>? <track-size> ]+ <line-names>?"
21887},
21888 "family-name": {
21889 syntax: "<string> | <custom-ident>+"
21890},
21891 "feature-tag-value": {
21892 syntax: "<string> [ <integer> | on | off ]?"
21893},
21894 "feature-type": {
21895 syntax: "@stylistic | @historical-forms | @styleset | @character-variant | @swash | @ornaments | @annotation"
21896},
21897 "feature-value-block": {
21898 syntax: "<feature-type> '{' <feature-value-declaration-list> '}'"
21899},
21900 "feature-value-block-list": {
21901 syntax: "<feature-value-block>+"
21902},
21903 "feature-value-declaration": {
21904 syntax: "<custom-ident>: <integer>+;"
21905},
21906 "feature-value-declaration-list": {
21907 syntax: "<feature-value-declaration>"
21908},
21909 "feature-value-name": {
21910 syntax: "<custom-ident>"
21911},
21912 "fill-rule": {
21913 syntax: "nonzero | evenodd"
21914},
21915 "filter-function": {
21916 syntax: "<blur()> | <brightness()> | <contrast()> | <drop-shadow()> | <grayscale()> | <hue-rotate()> | <invert()> | <opacity()> | <saturate()> | <sepia()>"
21917},
21918 "filter-function-list": {
21919 syntax: "[ <filter-function> | <url> ]+"
21920},
21921 "final-bg-layer": {
21922 syntax: "<'background-color'> || <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>"
21923},
21924 "fit-content()": {
21925 syntax: "fit-content( [ <length> | <percentage> ] )"
21926},
21927 "fixed-breadth": {
21928 syntax: "<length-percentage>"
21929},
21930 "fixed-repeat": {
21931 syntax: "repeat( [ <positive-integer> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )"
21932},
21933 "fixed-size": {
21934 syntax: "<fixed-breadth> | minmax( <fixed-breadth> , <track-breadth> ) | minmax( <inflexible-breadth> , <fixed-breadth> )"
21935},
21936 "font-stretch-absolute": {
21937 syntax: "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | <percentage>"
21938},
21939 "font-variant-css21": {
21940 syntax: "[ normal | small-caps ]"
21941},
21942 "font-weight-absolute": {
21943 syntax: "normal | bold | <number [1,1000]>"
21944},
21945 "frequency-percentage": {
21946 syntax: "<frequency> | <percentage>"
21947},
21948 "general-enclosed": {
21949 syntax: "[ <function-token> <any-value> ) ] | ( <ident> <any-value> )"
21950},
21951 "generic-family": {
21952 syntax: "serif | sans-serif | cursive | fantasy | monospace"
21953},
21954 "generic-name": {
21955 syntax: "serif | sans-serif | cursive | fantasy | monospace"
21956},
21957 "geometry-box": {
21958 syntax: "<shape-box> | fill-box | stroke-box | view-box"
21959},
21960 gradient: gradient,
21961 "grayscale()": {
21962 syntax: "grayscale( <number-percentage> )"
21963},
21964 "grid-line": {
21965 syntax: "auto | <custom-ident> | [ <integer> && <custom-ident>? ] | [ span && [ <integer> || <custom-ident> ] ]"
21966},
21967 "historical-lig-values": {
21968 syntax: "[ historical-ligatures | no-historical-ligatures ]"
21969},
21970 "hsl()": {
21971 syntax: "hsl( <hue> <percentage> <percentage> [ / <alpha-value> ]? ) | hsl( <hue>, <percentage>, <percentage>, <alpha-value>? )"
21972},
21973 "hsla()": {
21974 syntax: "hsla( <hue> <percentage> <percentage> [ / <alpha-value> ]? ) | hsla( <hue>, <percentage>, <percentage>, <alpha-value>? )"
21975},
21976 hue: hue,
21977 "hue-rotate()": {
21978 syntax: "hue-rotate( <angle> )"
21979},
21980 "id-selector": {
21981 syntax: "<hash-token>"
21982},
21983 image: image,
21984 "image()": {
21985 syntax: "image( <image-tags>? [ <image-src>? , <color>? ]! )"
21986},
21987 "image-set()": {
21988 syntax: "image-set( <image-set-option># )"
21989},
21990 "image-set-option": {
21991 syntax: "[ <image> | <string> ] <resolution>"
21992},
21993 "image-src": {
21994 syntax: "<url> | <string>"
21995},
21996 "image-tags": {
21997 syntax: "ltr | rtl"
21998},
21999 "inflexible-breadth": {
22000 syntax: "<length> | <percentage> | min-content | max-content | auto"
22001},
22002 "inset()": {
22003 syntax: "inset( <length-percentage>{1,4} [ round <'border-radius'> ]? )"
22004},
22005 "invert()": {
22006 syntax: "invert( <number-percentage> )"
22007},
22008 "keyframes-name": {
22009 syntax: "<custom-ident> | <string>"
22010},
22011 "keyframe-block": {
22012 syntax: "<keyframe-selector># {\n <declaration-list>\n}"
22013},
22014 "keyframe-block-list": {
22015 syntax: "<keyframe-block>+"
22016},
22017 "keyframe-selector": {
22018 syntax: "from | to | <percentage>"
22019},
22020 "leader()": {
22021 syntax: "leader( <leader-type> )"
22022},
22023 "leader-type": {
22024 syntax: "dotted | solid | space | <string>"
22025},
22026 "length-percentage": {
22027 syntax: "<length> | <percentage>"
22028},
22029 "line-names": {
22030 syntax: "'[' <custom-ident>* ']'"
22031},
22032 "line-name-list": {
22033 syntax: "[ <line-names> | <name-repeat> ]+"
22034},
22035 "line-style": {
22036 syntax: "none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset"
22037},
22038 "line-width": {
22039 syntax: "<length> | thin | medium | thick"
22040},
22041 "linear-color-hint": {
22042 syntax: "<length-percentage>"
22043},
22044 "linear-color-stop": {
22045 syntax: "<color> <color-stop-length>?"
22046},
22047 "linear-gradient()": {
22048 syntax: "linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )"
22049},
22050 "mask-layer": {
22051 syntax: "<mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> || <masking-mode>"
22052},
22053 "mask-position": {
22054 syntax: "[ <length-percentage> | left | center | right ] [ <length-percentage> | top | center | bottom ]?"
22055},
22056 "mask-reference": {
22057 syntax: "none | <image> | <mask-source>"
22058},
22059 "mask-source": {
22060 syntax: "<url>"
22061},
22062 "masking-mode": {
22063 syntax: "alpha | luminance | match-source"
22064},
22065 "matrix()": {
22066 syntax: "matrix( <number>#{6} )"
22067},
22068 "matrix3d()": {
22069 syntax: "matrix3d( <number>#{16} )"
22070},
22071 "max()": {
22072 syntax: "max( <calc-sum># )"
22073},
22074 "media-and": {
22075 syntax: "<media-in-parens> [ and <media-in-parens> ]+"
22076},
22077 "media-condition": {
22078 syntax: "<media-not> | <media-and> | <media-or> | <media-in-parens>"
22079},
22080 "media-condition-without-or": {
22081 syntax: "<media-not> | <media-and> | <media-in-parens>"
22082},
22083 "media-feature": {
22084 syntax: "( [ <mf-plain> | <mf-boolean> | <mf-range> ] )"
22085},
22086 "media-in-parens": {
22087 syntax: "( <media-condition> ) | <media-feature> | <general-enclosed>"
22088},
22089 "media-not": {
22090 syntax: "not <media-in-parens>"
22091},
22092 "media-or": {
22093 syntax: "<media-in-parens> [ or <media-in-parens> ]+"
22094},
22095 "media-query": {
22096 syntax: "<media-condition> | [ not | only ]? <media-type> [ and <media-condition-without-or> ]?"
22097},
22098 "media-query-list": {
22099 syntax: "<media-query>#"
22100},
22101 "media-type": {
22102 syntax: "<ident>"
22103},
22104 "mf-boolean": {
22105 syntax: "<mf-name>"
22106},
22107 "mf-name": {
22108 syntax: "<ident>"
22109},
22110 "mf-plain": {
22111 syntax: "<mf-name> : <mf-value>"
22112},
22113 "mf-range": {
22114 syntax: "<mf-name> [ '<' | '>' ]? '='? <mf-value>\n| <mf-value> [ '<' | '>' ]? '='? <mf-name>\n| <mf-value> '<' '='? <mf-name> '<' '='? <mf-value>\n| <mf-value> '>' '='? <mf-name> '>' '='? <mf-value>"
22115},
22116 "mf-value": {
22117 syntax: "<number> | <dimension> | <ident> | <ratio>"
22118},
22119 "min()": {
22120 syntax: "min( <calc-sum># )"
22121},
22122 "minmax()": {
22123 syntax: "minmax( [ <length> | <percentage> | min-content | max-content | auto ] , [ <length> | <percentage> | <flex> | min-content | max-content | auto ] )"
22124},
22125 "named-color": {
22126 syntax: "transparent | aliceblue | antiquewhite | aqua | aquamarine | azure | beige | bisque | black | blanchedalmond | blue | blueviolet | brown | burlywood | cadetblue | chartreuse | chocolate | coral | cornflowerblue | cornsilk | crimson | cyan | darkblue | darkcyan | darkgoldenrod | darkgray | darkgreen | darkgrey | darkkhaki | darkmagenta | darkolivegreen | darkorange | darkorchid | darkred | darksalmon | darkseagreen | darkslateblue | darkslategray | darkslategrey | darkturquoise | darkviolet | deeppink | deepskyblue | dimgray | dimgrey | dodgerblue | firebrick | floralwhite | forestgreen | fuchsia | gainsboro | ghostwhite | gold | goldenrod | gray | green | greenyellow | grey | honeydew | hotpink | indianred | indigo | ivory | khaki | lavender | lavenderblush | lawngreen | lemonchiffon | lightblue | lightcoral | lightcyan | lightgoldenrodyellow | lightgray | lightgreen | lightgrey | lightpink | lightsalmon | lightseagreen | lightskyblue | lightslategray | lightslategrey | lightsteelblue | lightyellow | lime | limegreen | linen | magenta | maroon | mediumaquamarine | mediumblue | mediumorchid | mediumpurple | mediumseagreen | mediumslateblue | mediumspringgreen | mediumturquoise | mediumvioletred | midnightblue | mintcream | mistyrose | moccasin | navajowhite | navy | oldlace | olive | olivedrab | orange | orangered | orchid | palegoldenrod | palegreen | paleturquoise | palevioletred | papayawhip | peachpuff | peru | pink | plum | powderblue | purple | rebeccapurple | red | rosybrown | royalblue | saddlebrown | salmon | sandybrown | seagreen | seashell | sienna | silver | skyblue | slateblue | slategray | slategrey | snow | springgreen | steelblue | tan | teal | thistle | tomato | turquoise | violet | wheat | white | whitesmoke | yellow | yellowgreen"
22127},
22128 "namespace-prefix": {
22129 syntax: "<ident>"
22130},
22131 "ns-prefix": {
22132 syntax: "[ <ident-token> | '*' ]? '|'"
22133},
22134 "number-percentage": {
22135 syntax: "<number> | <percentage>"
22136},
22137 "numeric-figure-values": {
22138 syntax: "[ lining-nums | oldstyle-nums ]"
22139},
22140 "numeric-fraction-values": {
22141 syntax: "[ diagonal-fractions | stacked-fractions ]"
22142},
22143 "numeric-spacing-values": {
22144 syntax: "[ proportional-nums | tabular-nums ]"
22145},
22146 nth: nth$1,
22147 "opacity()": {
22148 syntax: "opacity( [ <number-percentage> ] )"
22149},
22150 "overflow-position": {
22151 syntax: "unsafe | safe"
22152},
22153 "outline-radius": {
22154 syntax: "<length> | <percentage>"
22155},
22156 "page-body": {
22157 syntax: "<declaration>? [ ; <page-body> ]? | <page-margin-box> <page-body>"
22158},
22159 "page-margin-box": {
22160 syntax: "<page-margin-box-type> '{' <declaration-list> '}'"
22161},
22162 "page-margin-box-type": {
22163 syntax: "@top-left-corner | @top-left | @top-center | @top-right | @top-right-corner | @bottom-left-corner | @bottom-left | @bottom-center | @bottom-right | @bottom-right-corner | @left-top | @left-middle | @left-bottom | @right-top | @right-middle | @right-bottom"
22164},
22165 "page-selector-list": {
22166 syntax: "[ <page-selector># ]?"
22167},
22168 "page-selector": {
22169 syntax: "<pseudo-page>+ | <ident> <pseudo-page>*"
22170},
22171 "path()": {
22172 syntax: "path( [ <fill-rule>, ]? <string> )"
22173},
22174 "paint()": {
22175 syntax: "paint( <ident>, <declaration-value>? )"
22176},
22177 "perspective()": {
22178 syntax: "perspective( <length> )"
22179},
22180 "polygon()": {
22181 syntax: "polygon( <fill-rule>? , [ <length-percentage> <length-percentage> ]# )"
22182},
22183 position: position,
22184 "pseudo-class-selector": {
22185 syntax: "':' <ident-token> | ':' <function-token> <any-value> ')'"
22186},
22187 "pseudo-element-selector": {
22188 syntax: "':' <pseudo-class-selector>"
22189},
22190 "pseudo-page": {
22191 syntax: ": [ left | right | first | blank ]"
22192},
22193 quote: quote,
22194 "radial-gradient()": {
22195 syntax: "radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )"
22196},
22197 "relative-selector": {
22198 syntax: "<combinator>? <complex-selector>"
22199},
22200 "relative-selector-list": {
22201 syntax: "<relative-selector>#"
22202},
22203 "relative-size": {
22204 syntax: "larger | smaller"
22205},
22206 "repeat-style": {
22207 syntax: "repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2}"
22208},
22209 "repeating-linear-gradient()": {
22210 syntax: "repeating-linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )"
22211},
22212 "repeating-radial-gradient()": {
22213 syntax: "repeating-radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )"
22214},
22215 "rgb()": {
22216 syntax: "rgb( <percentage>{3} [ / <alpha-value> ]? ) | rgb( <number>{3} [ / <alpha-value> ]? ) | rgb( <percentage>#{3} , <alpha-value>? ) | rgb( <number>#{3} , <alpha-value>? )"
22217},
22218 "rgba()": {
22219 syntax: "rgba( <percentage>{3} [ / <alpha-value> ]? ) | rgba( <number>{3} [ / <alpha-value> ]? ) | rgba( <percentage>#{3} , <alpha-value>? ) | rgba( <number>#{3} , <alpha-value>? )"
22220},
22221 "rotate()": {
22222 syntax: "rotate( [ <angle> | <zero> ] )"
22223},
22224 "rotate3d()": {
22225 syntax: "rotate3d( <number> , <number> , <number> , [ <angle> | <zero> ] )"
22226},
22227 "rotateX()": {
22228 syntax: "rotateX( [ <angle> | <zero> ] )"
22229},
22230 "rotateY()": {
22231 syntax: "rotateY( [ <angle> | <zero> ] )"
22232},
22233 "rotateZ()": {
22234 syntax: "rotateZ( [ <angle> | <zero> ] )"
22235},
22236 "saturate()": {
22237 syntax: "saturate( <number-percentage> )"
22238},
22239 "scale()": {
22240 syntax: "scale( <number> , <number>? )"
22241},
22242 "scale3d()": {
22243 syntax: "scale3d( <number> , <number> , <number> )"
22244},
22245 "scaleX()": {
22246 syntax: "scaleX( <number> )"
22247},
22248 "scaleY()": {
22249 syntax: "scaleY( <number> )"
22250},
22251 "scaleZ()": {
22252 syntax: "scaleZ( <number> )"
22253},
22254 "self-position": {
22255 syntax: "center | start | end | self-start | self-end | flex-start | flex-end"
22256},
22257 "shape-radius": {
22258 syntax: "<length-percentage> | closest-side | farthest-side"
22259},
22260 "skew()": {
22261 syntax: "skew( [ <angle> | <zero> ] , [ <angle> | <zero> ]? )"
22262},
22263 "skewX()": {
22264 syntax: "skewX( [ <angle> | <zero> ] )"
22265},
22266 "skewY()": {
22267 syntax: "skewY( [ <angle> | <zero> ] )"
22268},
22269 "sepia()": {
22270 syntax: "sepia( <number-percentage> )"
22271},
22272 shadow: shadow,
22273 "shadow-t": {
22274 syntax: "[ <length>{2,3} && <color>? ]"
22275},
22276 shape: shape,
22277 "shape-box": {
22278 syntax: "<box> | margin-box"
22279},
22280 "side-or-corner": {
22281 syntax: "[ left | right ] || [ top | bottom ]"
22282},
22283 "single-animation": {
22284 syntax: "<time> || <timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]"
22285},
22286 "single-animation-direction": {
22287 syntax: "normal | reverse | alternate | alternate-reverse"
22288},
22289 "single-animation-fill-mode": {
22290 syntax: "none | forwards | backwards | both"
22291},
22292 "single-animation-iteration-count": {
22293 syntax: "infinite | <number>"
22294},
22295 "single-animation-play-state": {
22296 syntax: "running | paused"
22297},
22298 "single-transition": {
22299 syntax: "[ none | <single-transition-property> ] || <time> || <timing-function> || <time>"
22300},
22301 "single-transition-property": {
22302 syntax: "all | <custom-ident>"
22303},
22304 size: size,
22305 "step-position": {
22306 syntax: "jump-start | jump-end | jump-none | jump-both | start | end"
22307},
22308 "step-timing-function": {
22309 syntax: "step-start | step-end | steps(<integer>[, <step-position>]?)"
22310},
22311 "subclass-selector": {
22312 syntax: "<id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>"
22313},
22314 "supports-condition": {
22315 syntax: "not <supports-in-parens> | <supports-in-parens> [ and <supports-in-parens> ]* | <supports-in-parens> [ or <supports-in-parens> ]*"
22316},
22317 "supports-in-parens": {
22318 syntax: "( <supports-condition> ) | <supports-feature> | <general-enclosed>"
22319},
22320 "supports-feature": {
22321 syntax: "<supports-decl> | <supports-selector-fn>"
22322},
22323 "supports-decl": {
22324 syntax: "( <declaration> )"
22325},
22326 "supports-selector-fn": {
22327 syntax: "selector( <complex-selector> )"
22328},
22329 symbol: symbol,
22330 target: target,
22331 "target-counter()": {
22332 syntax: "target-counter( [ <string> | <url> ] , <custom-ident> , <counter-style>? )"
22333},
22334 "target-counters()": {
22335 syntax: "target-counters( [ <string> | <url> ] , <custom-ident> , <string> , <counter-style>? )"
22336},
22337 "target-text()": {
22338 syntax: "target-text( [ <string> | <url> ] , [ content | before | after | first-letter ]? )"
22339},
22340 "time-percentage": {
22341 syntax: "<time> | <percentage>"
22342},
22343 "timing-function": {
22344 syntax: "linear | <cubic-bezier-timing-function> | <step-timing-function>"
22345},
22346 "track-breadth": {
22347 syntax: "<length-percentage> | <flex> | min-content | max-content | auto"
22348},
22349 "track-list": {
22350 syntax: "[ <line-names>? [ <track-size> | <track-repeat> ] ]+ <line-names>?"
22351},
22352 "track-repeat": {
22353 syntax: "repeat( [ <positive-integer> ] , [ <line-names>? <track-size> ]+ <line-names>? )"
22354},
22355 "track-size": {
22356 syntax: "<track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( [ <length> | <percentage> ] )"
22357},
22358 "transform-function": {
22359 syntax: "<matrix()> | <translate()> | <translateX()> | <translateY()> | <scale()> | <scaleX()> | <scaleY()> | <rotate()> | <skew()> | <skewX()> | <skewY()> | <matrix3d()> | <translate3d()> | <translateZ()> | <scale3d()> | <scaleZ()> | <rotate3d()> | <rotateX()> | <rotateY()> | <rotateZ()> | <perspective()>"
22360},
22361 "transform-list": {
22362 syntax: "<transform-function>+"
22363},
22364 "translate()": {
22365 syntax: "translate( <length-percentage> , <length-percentage>? )"
22366},
22367 "translate3d()": {
22368 syntax: "translate3d( <length-percentage> , <length-percentage> , <length> )"
22369},
22370 "translateX()": {
22371 syntax: "translateX( <length-percentage> )"
22372},
22373 "translateY()": {
22374 syntax: "translateY( <length-percentage> )"
22375},
22376 "translateZ()": {
22377 syntax: "translateZ( <length> )"
22378},
22379 "type-or-unit": {
22380 syntax: "string | color | url | integer | number | length | angle | time | frequency | cap | ch | em | ex | ic | lh | rlh | rem | vb | vi | vw | vh | vmin | vmax | mm | Q | cm | in | pt | pc | px | deg | grad | rad | turn | ms | s | Hz | kHz | %"
22381},
22382 "type-selector": {
22383 syntax: "<wq-name> | <ns-prefix>? '*'"
22384},
22385 "var()": {
22386 syntax: "var( <custom-property-name> , <declaration-value>? )"
22387},
22388 "viewport-length": {
22389 syntax: "auto | <length-percentage>"
22390},
22391 "wq-name": {
22392 syntax: "<ns-prefix>? <ident-token>"
22393}
22394};
22395
22396var atrules = {
22397 charset: {
22398 prelude: "<string>"
22399 },
22400 "font-face": {
22401 descriptors: {
22402 "unicode-range": {
22403 comment: "replaces <unicode-range>, an old production name",
22404 syntax: "<urange>#"
22405 }
22406 }
22407 }
22408};
22409var properties = {
22410 "-moz-background-clip": {
22411 comment: "deprecated syntax in old Firefox, https://developer.mozilla.org/en/docs/Web/CSS/background-clip",
22412 syntax: "padding | border"
22413 },
22414 "-moz-border-radius-bottomleft": {
22415 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-left-radius",
22416 syntax: "<'border-bottom-left-radius'>"
22417 },
22418 "-moz-border-radius-bottomright": {
22419 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius",
22420 syntax: "<'border-bottom-right-radius'>"
22421 },
22422 "-moz-border-radius-topleft": {
22423 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-top-left-radius",
22424 syntax: "<'border-top-left-radius'>"
22425 },
22426 "-moz-border-radius-topright": {
22427 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-right-radius",
22428 syntax: "<'border-bottom-right-radius'>"
22429 },
22430 "-moz-control-character-visibility": {
22431 comment: "firefox specific keywords, https://bugzilla.mozilla.org/show_bug.cgi?id=947588",
22432 syntax: "visible | hidden"
22433 },
22434 "-moz-osx-font-smoothing": {
22435 comment: "misssed old syntax https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth",
22436 syntax: "auto | grayscale"
22437 },
22438 "-moz-user-select": {
22439 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/user-select",
22440 syntax: "none | text | all | -moz-none"
22441 },
22442 "-ms-flex-align": {
22443 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align",
22444 syntax: "start | end | center | baseline | stretch"
22445 },
22446 "-ms-flex-item-align": {
22447 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-align",
22448 syntax: "auto | start | end | center | baseline | stretch"
22449 },
22450 "-ms-flex-line-pack": {
22451 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-line-pack",
22452 syntax: "start | end | center | justify | distribute | stretch"
22453 },
22454 "-ms-flex-negative": {
22455 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
22456 syntax: "<'flex-shrink'>"
22457 },
22458 "-ms-flex-pack": {
22459 comment: "misssed old syntax implemented in IE, https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/#flex-pack",
22460 syntax: "start | end | center | justify | distribute"
22461 },
22462 "-ms-flex-order": {
22463 comment: "misssed old syntax implemented in IE; https://msdn.microsoft.com/en-us/library/jj127303(v=vs.85).aspx",
22464 syntax: "<integer>"
22465 },
22466 "-ms-flex-positive": {
22467 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
22468 syntax: "<'flex-grow'>"
22469 },
22470 "-ms-flex-preferred-size": {
22471 comment: "misssed old syntax implemented in IE; TODO: find references for comfirmation",
22472 syntax: "<'flex-basis'>"
22473 },
22474 "-ms-interpolation-mode": {
22475 comment: "https://msdn.microsoft.com/en-us/library/ff521095(v=vs.85).aspx",
22476 syntax: "nearest-neighbor | bicubic"
22477 },
22478 "-ms-grid-column-align": {
22479 comment: "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466338.aspx",
22480 syntax: "start | end | center | stretch"
22481 },
22482 "-ms-grid-row-align": {
22483 comment: "add this property first since it uses as fallback for flexbox, https://msdn.microsoft.com/en-us/library/windows/apps/hh466348.aspx",
22484 syntax: "start | end | center | stretch"
22485 },
22486 "-ms-hyphenate-limit-last": {
22487 comment: "misssed old syntax implemented in IE; https://www.w3.org/TR/css-text-4/#hyphenate-line-limits",
22488 syntax: "none | always | column | page | spread"
22489 },
22490 "-webkit-appearance": {
22491 comment: "webkit specific keywords",
22492 references: [
22493 "http://css-infos.net/property/-webkit-appearance"
22494 ],
22495 syntax: "none | button | button-bevel | caps-lock-indicator | caret | checkbox | default-button | inner-spin-button | listbox | listitem | media-controls-background | media-controls-fullscreen-background | media-current-time-display | media-enter-fullscreen-button | media-exit-fullscreen-button | media-fullscreen-button | media-mute-button | media-overlay-play-button | media-play-button | media-seek-back-button | media-seek-forward-button | media-slider | media-sliderthumb | media-time-remaining-display | media-toggle-closed-captions-button | media-volume-slider | media-volume-slider-container | media-volume-sliderthumb | menulist | menulist-button | menulist-text | menulist-textfield | meter | progress-bar | progress-bar-value | push-button | radio | scrollbarbutton-down | scrollbarbutton-left | scrollbarbutton-right | scrollbarbutton-up | scrollbargripper-horizontal | scrollbargripper-vertical | scrollbarthumb-horizontal | scrollbarthumb-vertical | scrollbartrack-horizontal | scrollbartrack-vertical | searchfield | searchfield-cancel-button | searchfield-decoration | searchfield-results-button | searchfield-results-decoration | slider-horizontal | slider-vertical | sliderthumb-horizontal | sliderthumb-vertical | square-button | textarea | textfield | -apple-pay-button"
22496 },
22497 "-webkit-background-clip": {
22498 comment: "https://developer.mozilla.org/en/docs/Web/CSS/background-clip",
22499 syntax: "[ <box> | border | padding | content | text ]#"
22500 },
22501 "-webkit-column-break-after": {
22502 comment: "added, http://help.dottoro.com/lcrthhhv.php",
22503 syntax: "always | auto | avoid"
22504 },
22505 "-webkit-column-break-before": {
22506 comment: "added, http://help.dottoro.com/lcxquvkf.php",
22507 syntax: "always | auto | avoid"
22508 },
22509 "-webkit-column-break-inside": {
22510 comment: "added, http://help.dottoro.com/lclhnthl.php",
22511 syntax: "always | auto | avoid"
22512 },
22513 "-webkit-font-smoothing": {
22514 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth",
22515 syntax: "auto | none | antialiased | subpixel-antialiased"
22516 },
22517 "-webkit-mask-box-image": {
22518 comment: "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image",
22519 syntax: "[ <url> | <gradient> | none ] [ <length-percentage>{4} <-webkit-mask-box-repeat>{2} ]?"
22520 },
22521 "-webkit-print-color-adjust": {
22522 comment: "missed",
22523 references: [
22524 "https://developer.mozilla.org/en/docs/Web/CSS/-webkit-print-color-adjust"
22525 ],
22526 syntax: "economy | exact"
22527 },
22528 "-webkit-text-security": {
22529 comment: "missed; http://help.dottoro.com/lcbkewgt.php",
22530 syntax: "none | circle | disc | square"
22531 },
22532 "-webkit-user-drag": {
22533 comment: "missed; http://help.dottoro.com/lcbixvwm.php",
22534 syntax: "none | element | auto"
22535 },
22536 "-webkit-user-select": {
22537 comment: "auto is supported by old webkit, https://developer.mozilla.org/en-US/docs/Web/CSS/user-select",
22538 syntax: "auto | none | text | all"
22539 },
22540 "alignment-baseline": {
22541 comment: "added SVG property",
22542 references: [
22543 "https://www.w3.org/TR/SVG/text.html#AlignmentBaselineProperty"
22544 ],
22545 syntax: "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical"
22546 },
22547 "baseline-shift": {
22548 comment: "added SVG property",
22549 references: [
22550 "https://www.w3.org/TR/SVG/text.html#BaselineShiftProperty"
22551 ],
22552 syntax: "baseline | sub | super | <svg-length>"
22553 },
22554 behavior: {
22555 comment: "added old IE property https://msdn.microsoft.com/en-us/library/ms530723(v=vs.85).aspx",
22556 syntax: "<url>+"
22557 },
22558 "clip-rule": {
22559 comment: "added SVG property",
22560 references: [
22561 "https://www.w3.org/TR/SVG/masking.html#ClipRuleProperty"
22562 ],
22563 syntax: "nonzero | evenodd"
22564 },
22565 cue: {
22566 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22567 syntax: "<'cue-before'> <'cue-after'>?"
22568 },
22569 "cue-after": {
22570 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22571 syntax: "<url> <decibel>? | none"
22572 },
22573 "cue-before": {
22574 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22575 syntax: "<url> <decibel>? | none"
22576 },
22577 cursor: {
22578 comment: "added legacy keywords: hand, -webkit-grab. -webkit-grabbing, -webkit-zoom-in, -webkit-zoom-out, -moz-grab, -moz-grabbing, -moz-zoom-in, -moz-zoom-out",
22579 references: [
22580 "https://www.sitepoint.com/css3-cursor-styles/"
22581 ],
22582 syntax: "[ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing | hand | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out | -moz-grab | -moz-grabbing | -moz-zoom-in | -moz-zoom-out ] ]"
22583 },
22584 display: {
22585 comment: "extended with -ms-flexbox",
22586 syntax: "| <-non-standard-display>"
22587 },
22588 position: {
22589 comment: "extended with -webkit-sticky",
22590 syntax: "| -webkit-sticky"
22591 },
22592 "dominant-baseline": {
22593 comment: "added SVG property",
22594 references: [
22595 "https://www.w3.org/TR/SVG/text.html#DominantBaselineProperty"
22596 ],
22597 syntax: "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge"
22598 },
22599 "image-rendering": {
22600 comment: "extended with <-non-standard-image-rendering>, added SVG keywords optimizeSpeed and optimizeQuality",
22601 references: [
22602 "https://developer.mozilla.org/en/docs/Web/CSS/image-rendering",
22603 "https://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty"
22604 ],
22605 syntax: "| optimizeSpeed | optimizeQuality | <-non-standard-image-rendering>"
22606 },
22607 fill: {
22608 comment: "added SVG property",
22609 references: [
22610 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
22611 ],
22612 syntax: "<paint>"
22613 },
22614 "fill-opacity": {
22615 comment: "added SVG property",
22616 references: [
22617 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
22618 ],
22619 syntax: "<number-zero-one>"
22620 },
22621 "fill-rule": {
22622 comment: "added SVG property",
22623 references: [
22624 "https://www.w3.org/TR/SVG/painting.html#FillProperty"
22625 ],
22626 syntax: "nonzero | evenodd"
22627 },
22628 filter: {
22629 comment: "extend with IE legacy syntaxes",
22630 syntax: "| <-ms-filter-function-list>"
22631 },
22632 "glyph-orientation-horizontal": {
22633 comment: "added SVG property",
22634 references: [
22635 "https://www.w3.org/TR/SVG/text.html#GlyphOrientationHorizontalProperty"
22636 ],
22637 syntax: "<angle>"
22638 },
22639 "glyph-orientation-vertical": {
22640 comment: "added SVG property",
22641 references: [
22642 "https://www.w3.org/TR/SVG/text.html#GlyphOrientationVerticalProperty"
22643 ],
22644 syntax: "<angle>"
22645 },
22646 kerning: {
22647 comment: "added SVG property",
22648 references: [
22649 "https://www.w3.org/TR/SVG/text.html#KerningProperty"
22650 ],
22651 syntax: "auto | <svg-length>"
22652 },
22653 "letter-spacing": {
22654 comment: "fix syntax <length> -> <length-percentage>",
22655 references: [
22656 "https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/letter-spacing"
22657 ],
22658 syntax: "normal | <length-percentage>"
22659 },
22660 marker: {
22661 comment: "added SVG property",
22662 references: [
22663 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22664 ],
22665 syntax: "none | <url>"
22666 },
22667 "marker-end": {
22668 comment: "added SVG property",
22669 references: [
22670 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22671 ],
22672 syntax: "none | <url>"
22673 },
22674 "marker-mid": {
22675 comment: "added SVG property",
22676 references: [
22677 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22678 ],
22679 syntax: "none | <url>"
22680 },
22681 "marker-start": {
22682 comment: "added SVG property",
22683 references: [
22684 "https://www.w3.org/TR/SVG/painting.html#MarkerProperties"
22685 ],
22686 syntax: "none | <url>"
22687 },
22688 "max-width": {
22689 comment: "fix auto -> none (https://github.com/mdn/data/pull/431); extend by non-standard width keywords https://developer.mozilla.org/en-US/docs/Web/CSS/max-width",
22690 syntax: "none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>) | <-non-standard-width>"
22691 },
22692 width: {
22693 comment: "per spec fit-content should be a function, however browsers are supporting it as a keyword (https://github.com/csstree/stylelint-validator/issues/29)",
22694 syntax: "| fit-content | -moz-fit-content | -webkit-fit-content"
22695 },
22696 "min-width": {
22697 comment: "extend by non-standard width keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width",
22698 syntax: "auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>) | <-non-standard-width>"
22699 },
22700 overflow: {
22701 comment: "extend by vendor keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow",
22702 syntax: "| <-non-standard-overflow>"
22703 },
22704 pause: {
22705 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22706 syntax: "<'pause-before'> <'pause-after'>?"
22707 },
22708 "pause-after": {
22709 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22710 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22711 },
22712 "pause-before": {
22713 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22714 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22715 },
22716 rest: {
22717 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22718 syntax: "<'rest-before'> <'rest-after'>?"
22719 },
22720 "rest-after": {
22721 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22722 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22723 },
22724 "rest-before": {
22725 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22726 syntax: "<time> | none | x-weak | weak | medium | strong | x-strong"
22727 },
22728 "shape-rendering": {
22729 comment: "added SVG property",
22730 references: [
22731 "https://www.w3.org/TR/SVG/painting.html#ShapeRenderingPropert"
22732 ],
22733 syntax: "auto | optimizeSpeed | crispEdges | geometricPrecision"
22734 },
22735 src: {
22736 comment: "added @font-face's src property https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src",
22737 syntax: "[ <url> [ format( <string># ) ]? | local( <family-name> ) ]#"
22738 },
22739 speak: {
22740 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22741 syntax: "auto | none | normal"
22742 },
22743 "speak-as": {
22744 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22745 syntax: "normal | spell-out || digits || [ literal-punctuation | no-punctuation ]"
22746 },
22747 stroke: {
22748 comment: "added SVG property",
22749 references: [
22750 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22751 ],
22752 syntax: "<paint>"
22753 },
22754 "stroke-dasharray": {
22755 comment: "added SVG property; a list of comma and/or white space separated <length>s and <percentage>s",
22756 references: [
22757 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22758 ],
22759 syntax: "none | [ <svg-length>+ ]#"
22760 },
22761 "stroke-dashoffset": {
22762 comment: "added SVG property",
22763 references: [
22764 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22765 ],
22766 syntax: "<svg-length>"
22767 },
22768 "stroke-linecap": {
22769 comment: "added SVG property",
22770 references: [
22771 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22772 ],
22773 syntax: "butt | round | square"
22774 },
22775 "stroke-linejoin": {
22776 comment: "added SVG property",
22777 references: [
22778 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22779 ],
22780 syntax: "miter | round | bevel"
22781 },
22782 "stroke-miterlimit": {
22783 comment: "added SVG property (<miterlimit> = <number-one-or-greater>) ",
22784 references: [
22785 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22786 ],
22787 syntax: "<number-one-or-greater>"
22788 },
22789 "stroke-opacity": {
22790 comment: "added SVG property",
22791 references: [
22792 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22793 ],
22794 syntax: "<number-zero-one>"
22795 },
22796 "stroke-width": {
22797 comment: "added SVG property",
22798 references: [
22799 "https://www.w3.org/TR/SVG/painting.html#StrokeProperties"
22800 ],
22801 syntax: "<svg-length>"
22802 },
22803 "text-anchor": {
22804 comment: "added SVG property",
22805 references: [
22806 "https://www.w3.org/TR/SVG/text.html#TextAlignmentProperties"
22807 ],
22808 syntax: "start | middle | end"
22809 },
22810 "unicode-bidi": {
22811 comment: "added prefixed keywords https://developer.mozilla.org/en-US/docs/Web/CSS/unicode-bidi",
22812 syntax: "| -moz-isolate | -moz-isolate-override | -moz-plaintext | -webkit-isolate | -webkit-isolate-override | -webkit-plaintext"
22813 },
22814 "unicode-range": {
22815 comment: "added missed property https://developer.mozilla.org/en-US/docs/Web/CSS/%40font-face/unicode-range",
22816 syntax: "<urange>#"
22817 },
22818 "voice-balance": {
22819 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22820 syntax: "<number> | left | center | right | leftwards | rightwards"
22821 },
22822 "voice-duration": {
22823 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22824 syntax: "auto | <time>"
22825 },
22826 "voice-family": {
22827 comment: "<name> -> <family-name>, https://www.w3.org/TR/css3-speech/#property-index",
22828 syntax: "[ [ <family-name> | <generic-voice> ] , ]* [ <family-name> | <generic-voice> ] | preserve"
22829 },
22830 "voice-pitch": {
22831 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22832 syntax: "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]"
22833 },
22834 "voice-range": {
22835 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22836 syntax: "<frequency> && absolute | [ [ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ] ]"
22837 },
22838 "voice-rate": {
22839 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22840 syntax: "[ normal | x-slow | slow | medium | fast | x-fast ] || <percentage>"
22841 },
22842 "voice-stress": {
22843 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22844 syntax: "normal | strong | moderate | none | reduced"
22845 },
22846 "voice-volume": {
22847 comment: "https://www.w3.org/TR/css3-speech/#property-index",
22848 syntax: "silent | [ [ x-soft | soft | medium | loud | x-loud ] || <decibel> ]"
22849 },
22850 "writing-mode": {
22851 comment: "extend with SVG keywords",
22852 syntax: "| <svg-writing-mode>"
22853 }
22854};
22855var syntaxes = {
22856 "-legacy-gradient": {
22857 comment: "added collection of legacy gradient syntaxes",
22858 syntax: "<-webkit-gradient()> | <-legacy-linear-gradient> | <-legacy-repeating-linear-gradient> | <-legacy-radial-gradient> | <-legacy-repeating-radial-gradient>"
22859 },
22860 "-legacy-linear-gradient": {
22861 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22862 syntax: "-moz-linear-gradient( <-legacy-linear-gradient-arguments> ) | -webkit-linear-gradient( <-legacy-linear-gradient-arguments> ) | -o-linear-gradient( <-legacy-linear-gradient-arguments> )"
22863 },
22864 "-legacy-repeating-linear-gradient": {
22865 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22866 syntax: "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> ) | -webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> ) | -o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )"
22867 },
22868 "-legacy-linear-gradient-arguments": {
22869 comment: "like standard syntax but w/o `to` keyword https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient",
22870 syntax: "[ <angle> | <side-or-corner> ]? , <color-stop-list>"
22871 },
22872 "-legacy-radial-gradient": {
22873 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22874 syntax: "-moz-radial-gradient( <-legacy-radial-gradient-arguments> ) | -webkit-radial-gradient( <-legacy-radial-gradient-arguments> ) | -o-radial-gradient( <-legacy-radial-gradient-arguments> )"
22875 },
22876 "-legacy-repeating-radial-gradient": {
22877 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22878 syntax: "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> ) | -webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> ) | -o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )"
22879 },
22880 "-legacy-radial-gradient-arguments": {
22881 comment: "deprecated syntax that implemented by some browsers https://www.w3.org/TR/2011/WD-css3-images-20110908/#radial-gradients",
22882 syntax: "[ <position> , ]? [ [ [ <-legacy-radial-gradient-shape> || <-legacy-radial-gradient-size> ] | [ <length> | <percentage> ]{2} ] , ]? <color-stop-list>"
22883 },
22884 "-legacy-radial-gradient-size": {
22885 comment: "before a standard it contains 2 extra keywords (`contain` and `cover`) https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltsize",
22886 syntax: "closest-side | closest-corner | farthest-side | farthest-corner | contain | cover"
22887 },
22888 "-legacy-radial-gradient-shape": {
22889 comment: "define to double sure it doesn't extends in future https://www.w3.org/TR/2011/WD-css3-images-20110908/#ltshape",
22890 syntax: "circle | ellipse"
22891 },
22892 "-non-standard-font": {
22893 comment: "non standard fonts",
22894 references: [
22895 "https://webkit.org/blog/3709/using-the-system-font-in-web-content/"
22896 ],
22897 syntax: "-apple-system-body | -apple-system-headline | -apple-system-subheadline | -apple-system-caption1 | -apple-system-caption2 | -apple-system-footnote | -apple-system-short-body | -apple-system-short-headline | -apple-system-short-subheadline | -apple-system-short-caption1 | -apple-system-short-footnote | -apple-system-tall-body"
22898 },
22899 "-non-standard-color": {
22900 comment: "non standard colors",
22901 references: [
22902 "http://cssdot.ru/%D0%A1%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA_CSS/color-i305.html",
22903 "https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Mozilla_Color_Preference_Extensions"
22904 ],
22905 syntax: "-moz-ButtonDefault | -moz-ButtonHoverFace | -moz-ButtonHoverText | -moz-CellHighlight | -moz-CellHighlightText | -moz-Combobox | -moz-ComboboxText | -moz-Dialog | -moz-DialogText | -moz-dragtargetzone | -moz-EvenTreeRow | -moz-Field | -moz-FieldText | -moz-html-CellHighlight | -moz-html-CellHighlightText | -moz-mac-accentdarkestshadow | -moz-mac-accentdarkshadow | -moz-mac-accentface | -moz-mac-accentlightesthighlight | -moz-mac-accentlightshadow | -moz-mac-accentregularhighlight | -moz-mac-accentregularshadow | -moz-mac-chrome-active | -moz-mac-chrome-inactive | -moz-mac-focusring | -moz-mac-menuselect | -moz-mac-menushadow | -moz-mac-menutextselect | -moz-MenuHover | -moz-MenuHoverText | -moz-MenuBarText | -moz-MenuBarHoverText | -moz-nativehyperlinktext | -moz-OddTreeRow | -moz-win-communicationstext | -moz-win-mediatext | -moz-activehyperlinktext | -moz-default-background-color | -moz-default-color | -moz-hyperlinktext | -moz-visitedhyperlinktext | -webkit-activelink | -webkit-focus-ring-color | -webkit-link | -webkit-text"
22906 },
22907 "-non-standard-image-rendering": {
22908 comment: "non-standard keywords http://phrogz.net/tmp/canvas_image_zoom.html",
22909 syntax: "optimize-contrast | -moz-crisp-edges | -o-crisp-edges | -webkit-optimize-contrast"
22910 },
22911 "-non-standard-overflow": {
22912 comment: "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/overflow",
22913 syntax: "-moz-scrollbars-none | -moz-scrollbars-horizontal | -moz-scrollbars-vertical | -moz-hidden-unscrollable"
22914 },
22915 "-non-standard-width": {
22916 comment: "non-standard keywords https://developer.mozilla.org/en-US/docs/Web/CSS/width",
22917 syntax: "fill-available | min-intrinsic | intrinsic | -moz-available | -moz-fit-content | -moz-min-content | -moz-max-content | -webkit-min-content | -webkit-max-content"
22918 },
22919 "-webkit-gradient()": {
22920 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/ - TODO: simplify when after match algorithm improvement ( [, point, radius | , point] -> [, radius]? , point )",
22921 syntax: "-webkit-gradient( <-webkit-gradient-type>, <-webkit-gradient-point> [, <-webkit-gradient-point> | , <-webkit-gradient-radius>, <-webkit-gradient-point> ] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )"
22922 },
22923 "-webkit-gradient-color-stop": {
22924 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22925 syntax: "from( <color> ) | color-stop( [ <number-zero-one> | <percentage> ] , <color> ) | to( <color> )"
22926 },
22927 "-webkit-gradient-point": {
22928 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22929 syntax: "[ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]"
22930 },
22931 "-webkit-gradient-radius": {
22932 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22933 syntax: "<length> | <percentage>"
22934 },
22935 "-webkit-gradient-type": {
22936 comment: "first Apple proposal gradient syntax https://webkit.org/blog/175/introducing-css-gradients/",
22937 syntax: "linear | radial"
22938 },
22939 "-webkit-mask-box-repeat": {
22940 comment: "missed; https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-box-image",
22941 syntax: "repeat | stretch | round"
22942 },
22943 "-webkit-mask-clip-style": {
22944 comment: "missed; there is no enough information about `-webkit-mask-clip` property, but looks like all those keywords are working",
22945 syntax: "border | border-box | padding | padding-box | content | content-box | text"
22946 },
22947 "-ms-filter-function-list": {
22948 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22949 syntax: "<-ms-filter-function>+"
22950 },
22951 "-ms-filter-function": {
22952 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22953 syntax: "<-ms-filter-function-progid> | <-ms-filter-function-legacy>"
22954 },
22955 "-ms-filter-function-progid": {
22956 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22957 syntax: "'progid:' [ <ident-token> '.' ]* [ <ident-token> | <function-token> <any-value>? ) ]"
22958 },
22959 "-ms-filter-function-legacy": {
22960 comment: "https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter",
22961 syntax: "<ident-token> | <function-token> <any-value>? )"
22962 },
22963 "-ms-filter": {
22964 syntax: "<string>"
22965 },
22966 age: {
22967 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22968 syntax: "child | young | old"
22969 },
22970 "attr-name": {
22971 syntax: "<wq-name>"
22972 },
22973 "attr-fallback": {
22974 syntax: "<any-value>"
22975 },
22976 "border-radius": {
22977 comment: "missed, https://drafts.csswg.org/css-backgrounds-3/#the-border-radius",
22978 syntax: "<length-percentage>{1,2}"
22979 },
22980 bottom: {
22981 comment: "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect",
22982 syntax: "<length> | auto"
22983 },
22984 "content-list": {
22985 comment: "missed -> https://drafts.csswg.org/css-content/#typedef-content-list (document-url, <target> and leader() is omitted util stabilization)",
22986 syntax: "[ <string> | contents | <image> | <quote> | <target> | <leader()> | <attr()> | counter( <ident>, <'list-style-type'>? ) ]+"
22987 },
22988 "element()": {
22989 comment: "https://drafts.csswg.org/css-gcpm/#element-syntax & https://drafts.csswg.org/css-images-4/#element-notation",
22990 syntax: "element( <custom-ident> , [ first | start | last | first-except ]? ) | element( <id-selector> )"
22991 },
22992 "generic-voice": {
22993 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22994 syntax: "[ <age>? <gender> <integer>? ]"
22995 },
22996 gender: {
22997 comment: "https://www.w3.org/TR/css3-speech/#voice-family",
22998 syntax: "male | female | neutral"
22999 },
23000 "generic-family": {
23001 comment: "added -apple-system",
23002 references: [
23003 "https://webkit.org/blog/3709/using-the-system-font-in-web-content/"
23004 ],
23005 syntax: "| -apple-system"
23006 },
23007 gradient: {
23008 comment: "added legacy syntaxes support",
23009 syntax: "| <-legacy-gradient>"
23010 },
23011 left: {
23012 comment: "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect",
23013 syntax: "<length> | auto"
23014 },
23015 "mask-image": {
23016 comment: "missed; https://drafts.fxtf.org/css-masking-1/#the-mask-image",
23017 syntax: "<mask-reference>#"
23018 },
23019 "name-repeat": {
23020 comment: "missed, and looks like obsolete, keep it as is since other property syntaxes should be changed too; https://www.w3.org/TR/2015/WD-css-grid-1-20150917/#typedef-name-repeat",
23021 syntax: "repeat( [ <positive-integer> | auto-fill ], <line-names>+)"
23022 },
23023 "named-color": {
23024 comment: "added non standard color names",
23025 syntax: "| <-non-standard-color>"
23026 },
23027 paint: {
23028 comment: "used by SVG https://www.w3.org/TR/SVG/painting.html#SpecifyingPaint",
23029 syntax: "none | <color> | <url> [ none | <color> ]? | context-fill | context-stroke"
23030 },
23031 "page-size": {
23032 comment: "https://www.w3.org/TR/css-page-3/#typedef-page-size-page-size",
23033 syntax: "A5 | A4 | A3 | B5 | B4 | JIS-B5 | JIS-B4 | letter | legal | ledger"
23034 },
23035 ratio: {
23036 comment: "missed, https://drafts.csswg.org/mediaqueries-4/#typedef-ratio",
23037 syntax: "<integer> / <integer>"
23038 },
23039 right: {
23040 comment: "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect",
23041 syntax: "<length> | auto"
23042 },
23043 shape: {
23044 comment: "missed spaces in function body and add backwards compatible syntax",
23045 syntax: "rect( <top>, <right>, <bottom>, <left> ) | rect( <top> <right> <bottom> <left> )"
23046 },
23047 "svg-length": {
23048 comment: "All coordinates and lengths in SVG can be specified with or without a unit identifier",
23049 references: [
23050 "https://www.w3.org/TR/SVG11/coords.html#Units"
23051 ],
23052 syntax: "<percentage> | <length> | <number>"
23053 },
23054 "svg-writing-mode": {
23055 comment: "SVG specific keywords (deprecated for CSS)",
23056 references: [
23057 "https://developer.mozilla.org/en/docs/Web/CSS/writing-mode",
23058 "https://www.w3.org/TR/SVG/text.html#WritingModeProperty"
23059 ],
23060 syntax: "lr-tb | rl-tb | tb-rl | lr | rl | tb"
23061 },
23062 top: {
23063 comment: "missed; not sure we should add it, but no others except `shape` is using it so it's ok for now; https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect",
23064 syntax: "<length> | auto"
23065 },
23066 "track-group": {
23067 comment: "used by old grid-columns and grid-rows syntax v0",
23068 syntax: "'(' [ <string>* <track-minmax> <string>* ]+ ')' [ '[' <positive-integer> ']' ]? | <track-minmax>"
23069 },
23070 "track-list-v0": {
23071 comment: "used by old grid-columns and grid-rows syntax v0",
23072 syntax: "[ <string>* <track-group> <string>* ]+ | none"
23073 },
23074 "track-minmax": {
23075 comment: "used by old grid-columns and grid-rows syntax v0",
23076 syntax: "minmax( <track-breadth> , <track-breadth> ) | auto | <track-breadth> | fit-content"
23077 },
23078 x: {
23079 comment: "missed; not sure we should add it, but no others except `cursor` is using it so it's ok for now; https://drafts.csswg.org/css-ui-3/#cursor",
23080 syntax: "<number>"
23081 },
23082 y: {
23083 comment: "missed; not sure we should add it, but no others except `cursor` is using so it's ok for now; https://drafts.csswg.org/css-ui-3/#cursor",
23084 syntax: "<number>"
23085 },
23086 declaration: {
23087 comment: "missed, restored by https://drafts.csswg.org/css-syntax",
23088 syntax: "<ident-token> : <declaration-value>? [ '!' important ]?"
23089 },
23090 "declaration-list": {
23091 comment: "missed, restored by https://drafts.csswg.org/css-syntax",
23092 syntax: "[ <declaration>? ';' ]* <declaration>?"
23093 },
23094 url: {
23095 comment: "https://drafts.csswg.org/css-values-4/#urls",
23096 syntax: "url( <string> <url-modifier>* ) | <url-token>"
23097 },
23098 "url-modifier": {
23099 comment: "https://drafts.csswg.org/css-values-4/#typedef-url-modifier",
23100 syntax: "<ident> | <function-token> <any-value> )"
23101 },
23102 "number-zero-one": {
23103 syntax: "<number [0,1]>"
23104 },
23105 "number-one-or-greater": {
23106 syntax: "<number [1,∞]>"
23107 },
23108 "positive-integer": {
23109 syntax: "<integer [0,∞]>"
23110 },
23111 "-non-standard-display": {
23112 syntax: "-ms-inline-flexbox | -ms-grid | -ms-inline-grid | -webkit-flex | -webkit-inline-flex | -webkit-box | -webkit-inline-box | -moz-inline-stack | -moz-box | -moz-inline-box"
23113 }
23114};
23115var require$$3 = {
23116 atrules: atrules,
23117 properties: properties,
23118 syntaxes: syntaxes
23119};
23120
23121const mdnAtrules = require$$0;
23122const mdnProperties = require$$1;
23123const mdnSyntaxes = require$$2;
23124const patch = require$$3;
23125const extendSyntax = /^\s*\|\s*/;
23126
23127function preprocessAtrules(dict) {
23128 const result = Object.create(null);
23129
23130 for (const atruleName in dict) {
23131 const atrule = dict[atruleName];
23132 let descriptors = null;
23133
23134 if (atrule.descriptors) {
23135 descriptors = Object.create(null);
23136
23137 for (const descriptor in atrule.descriptors) {
23138 descriptors[descriptor] = atrule.descriptors[descriptor].syntax;
23139 }
23140 }
23141
23142 result[atruleName.substr(1)] = {
23143 prelude: atrule.syntax.trim().match(/^@\S+\s+([^;\{]*)/)[1].trim() || null,
23144 descriptors
23145 };
23146 }
23147
23148 return result;
23149}
23150
23151function patchDictionary(dict, patchDict) {
23152 const result = {};
23153
23154 // copy all syntaxes for an original dict
23155 for (const key in dict) {
23156 result[key] = dict[key].syntax || dict[key];
23157 }
23158
23159 // apply a patch
23160 for (const key in patchDict) {
23161 if (key in dict) {
23162 if (patchDict[key].syntax) {
23163 result[key] = extendSyntax.test(patchDict[key].syntax)
23164 ? result[key] + ' ' + patchDict[key].syntax.trim()
23165 : patchDict[key].syntax;
23166 } else {
23167 delete result[key];
23168 }
23169 } else {
23170 if (patchDict[key].syntax) {
23171 result[key] = patchDict[key].syntax.replace(extendSyntax, '');
23172 }
23173 }
23174 }
23175
23176 return result;
23177}
23178
23179function unpackSyntaxes(dict) {
23180 const result = {};
23181
23182 for (const key in dict) {
23183 result[key] = dict[key].syntax;
23184 }
23185
23186 return result;
23187}
23188
23189function patchAtrules(dict, patchDict) {
23190 const result = {};
23191
23192 // copy all syntaxes for an original dict
23193 for (const key in dict) {
23194 const patchDescriptors = (patchDict[key] && patchDict[key].descriptors) || null;
23195
23196 result[key] = {
23197 prelude: key in patchDict && 'prelude' in patchDict[key]
23198 ? patchDict[key].prelude
23199 : dict[key].prelude || null,
23200 descriptors: dict[key].descriptors
23201 ? patchDictionary(dict[key].descriptors, patchDescriptors || {})
23202 : patchDescriptors && unpackSyntaxes(patchDescriptors)
23203 };
23204 }
23205
23206 // apply a patch
23207 for (const key in patchDict) {
23208 if (!hasOwnProperty.call(dict, key)) {
23209 result[key] = {
23210 prelude: patchDict[key].prelude || null,
23211 descriptors: patchDict[key].descriptors && unpackSyntaxes(patchDict[key].descriptors)
23212 };
23213 }
23214 }
23215
23216 return result;
23217}
23218
23219var data$1 = {
23220 types: patchDictionary(mdnSyntaxes, patch.syntaxes),
23221 atrules: patchAtrules(preprocessAtrules(mdnAtrules), patch.atrules),
23222 properties: patchDictionary(mdnProperties, patch.properties)
23223};
23224
23225var cmpChar$2 = tokenizer$3.cmpChar;
23226var isDigit$1 = tokenizer$3.isDigit;
23227var TYPE$y = tokenizer$3.TYPE;
23228
23229var WHITESPACE$8 = TYPE$y.WhiteSpace;
23230var COMMENT$6 = TYPE$y.Comment;
23231var IDENT$f = TYPE$y.Ident;
23232var NUMBER$6 = TYPE$y.Number;
23233var DIMENSION$5 = TYPE$y.Dimension;
23234var PLUSSIGN$5 = 0x002B; // U+002B PLUS SIGN (+)
23235var HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)
23236var N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
23237var DISALLOW_SIGN = true;
23238var ALLOW_SIGN = false;
23239
23240function checkInteger(offset, disallowSign) {
23241 var pos = this.scanner.tokenStart + offset;
23242 var code = this.scanner.source.charCodeAt(pos);
23243
23244 if (code === PLUSSIGN$5 || code === HYPHENMINUS$2) {
23245 if (disallowSign) {
23246 this.error('Number sign is not allowed');
23247 }
23248 pos++;
23249 }
23250
23251 for (; pos < this.scanner.tokenEnd; pos++) {
23252 if (!isDigit$1(this.scanner.source.charCodeAt(pos))) {
23253 this.error('Integer is expected', pos);
23254 }
23255 }
23256}
23257
23258function checkTokenIsInteger(disallowSign) {
23259 return checkInteger.call(this, 0, disallowSign);
23260}
23261
23262function expectCharCode(offset, code) {
23263 if (!cmpChar$2(this.scanner.source, this.scanner.tokenStart + offset, code)) {
23264 var msg = '';
23265
23266 switch (code) {
23267 case N:
23268 msg = 'N is expected';
23269 break;
23270 case HYPHENMINUS$2:
23271 msg = 'HyphenMinus is expected';
23272 break;
23273 }
23274
23275 this.error(msg, this.scanner.tokenStart + offset);
23276 }
23277}
23278
23279// ... <signed-integer>
23280// ... ['+' | '-'] <signless-integer>
23281function consumeB() {
23282 var offset = 0;
23283 var sign = 0;
23284 var type = this.scanner.tokenType;
23285
23286 while (type === WHITESPACE$8 || type === COMMENT$6) {
23287 type = this.scanner.lookupType(++offset);
23288 }
23289
23290 if (type !== NUMBER$6) {
23291 if (this.scanner.isDelim(PLUSSIGN$5, offset) ||
23292 this.scanner.isDelim(HYPHENMINUS$2, offset)) {
23293 sign = this.scanner.isDelim(PLUSSIGN$5, offset) ? PLUSSIGN$5 : HYPHENMINUS$2;
23294
23295 do {
23296 type = this.scanner.lookupType(++offset);
23297 } while (type === WHITESPACE$8 || type === COMMENT$6);
23298
23299 if (type !== NUMBER$6) {
23300 this.scanner.skip(offset);
23301 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23302 }
23303 } else {
23304 return null;
23305 }
23306 }
23307
23308 if (offset > 0) {
23309 this.scanner.skip(offset);
23310 }
23311
23312 if (sign === 0) {
23313 type = this.scanner.source.charCodeAt(this.scanner.tokenStart);
23314 if (type !== PLUSSIGN$5 && type !== HYPHENMINUS$2) {
23315 this.error('Number sign is expected');
23316 }
23317 }
23318
23319 checkTokenIsInteger.call(this, sign !== 0);
23320 return sign === HYPHENMINUS$2 ? '-' + this.consume(NUMBER$6) : this.consume(NUMBER$6);
23321}
23322
23323// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
23324var AnPlusB = {
23325 name: 'AnPlusB',
23326 structure: {
23327 a: [String, null],
23328 b: [String, null]
23329 },
23330 parse: function() {
23331 /* eslint-disable brace-style*/
23332 var start = this.scanner.tokenStart;
23333 var a = null;
23334 var b = null;
23335
23336 // <integer>
23337 if (this.scanner.tokenType === NUMBER$6) {
23338 checkTokenIsInteger.call(this, ALLOW_SIGN);
23339 b = this.consume(NUMBER$6);
23340 }
23341
23342 // -n
23343 // -n <signed-integer>
23344 // -n ['+' | '-'] <signless-integer>
23345 // -n- <signless-integer>
23346 // <dashndashdigit-ident>
23347 else if (this.scanner.tokenType === IDENT$f && cmpChar$2(this.scanner.source, this.scanner.tokenStart, HYPHENMINUS$2)) {
23348 a = '-1';
23349
23350 expectCharCode.call(this, 1, N);
23351
23352 switch (this.scanner.getTokenLength()) {
23353 // -n
23354 // -n <signed-integer>
23355 // -n ['+' | '-'] <signless-integer>
23356 case 2:
23357 this.scanner.next();
23358 b = consumeB.call(this);
23359 break;
23360
23361 // -n- <signless-integer>
23362 case 3:
23363 expectCharCode.call(this, 2, HYPHENMINUS$2);
23364
23365 this.scanner.next();
23366 this.scanner.skipSC();
23367
23368 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23369
23370 b = '-' + this.consume(NUMBER$6);
23371 break;
23372
23373 // <dashndashdigit-ident>
23374 default:
23375 expectCharCode.call(this, 2, HYPHENMINUS$2);
23376 checkInteger.call(this, 3, DISALLOW_SIGN);
23377 this.scanner.next();
23378
23379 b = this.scanner.substrToCursor(start + 2);
23380 }
23381 }
23382
23383 // '+'? n
23384 // '+'? n <signed-integer>
23385 // '+'? n ['+' | '-'] <signless-integer>
23386 // '+'? n- <signless-integer>
23387 // '+'? <ndashdigit-ident>
23388 else if (this.scanner.tokenType === IDENT$f || (this.scanner.isDelim(PLUSSIGN$5) && this.scanner.lookupType(1) === IDENT$f)) {
23389 var sign = 0;
23390 a = '1';
23391
23392 // just ignore a plus
23393 if (this.scanner.isDelim(PLUSSIGN$5)) {
23394 sign = 1;
23395 this.scanner.next();
23396 }
23397
23398 expectCharCode.call(this, 0, N);
23399
23400 switch (this.scanner.getTokenLength()) {
23401 // '+'? n
23402 // '+'? n <signed-integer>
23403 // '+'? n ['+' | '-'] <signless-integer>
23404 case 1:
23405 this.scanner.next();
23406 b = consumeB.call(this);
23407 break;
23408
23409 // '+'? n- <signless-integer>
23410 case 2:
23411 expectCharCode.call(this, 1, HYPHENMINUS$2);
23412
23413 this.scanner.next();
23414 this.scanner.skipSC();
23415
23416 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23417
23418 b = '-' + this.consume(NUMBER$6);
23419 break;
23420
23421 // '+'? <ndashdigit-ident>
23422 default:
23423 expectCharCode.call(this, 1, HYPHENMINUS$2);
23424 checkInteger.call(this, 2, DISALLOW_SIGN);
23425 this.scanner.next();
23426
23427 b = this.scanner.substrToCursor(start + sign + 1);
23428 }
23429 }
23430
23431 // <ndashdigit-dimension>
23432 // <ndash-dimension> <signless-integer>
23433 // <n-dimension>
23434 // <n-dimension> <signed-integer>
23435 // <n-dimension> ['+' | '-'] <signless-integer>
23436 else if (this.scanner.tokenType === DIMENSION$5) {
23437 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
23438 var sign = code === PLUSSIGN$5 || code === HYPHENMINUS$2;
23439
23440 for (var i = this.scanner.tokenStart + sign; i < this.scanner.tokenEnd; i++) {
23441 if (!isDigit$1(this.scanner.source.charCodeAt(i))) {
23442 break;
23443 }
23444 }
23445
23446 if (i === this.scanner.tokenStart + sign) {
23447 this.error('Integer is expected', this.scanner.tokenStart + sign);
23448 }
23449
23450 expectCharCode.call(this, i - this.scanner.tokenStart, N);
23451 a = this.scanner.source.substring(start, i);
23452
23453 // <n-dimension>
23454 // <n-dimension> <signed-integer>
23455 // <n-dimension> ['+' | '-'] <signless-integer>
23456 if (i + 1 === this.scanner.tokenEnd) {
23457 this.scanner.next();
23458 b = consumeB.call(this);
23459 } else {
23460 expectCharCode.call(this, i - this.scanner.tokenStart + 1, HYPHENMINUS$2);
23461
23462 // <ndash-dimension> <signless-integer>
23463 if (i + 2 === this.scanner.tokenEnd) {
23464 this.scanner.next();
23465 this.scanner.skipSC();
23466 checkTokenIsInteger.call(this, DISALLOW_SIGN);
23467 b = '-' + this.consume(NUMBER$6);
23468 }
23469 // <ndashdigit-dimension>
23470 else {
23471 checkInteger.call(this, i - this.scanner.tokenStart + 2, DISALLOW_SIGN);
23472 this.scanner.next();
23473 b = this.scanner.substrToCursor(i + 1);
23474 }
23475 }
23476 } else {
23477 this.error();
23478 }
23479
23480 if (a !== null && a.charCodeAt(0) === PLUSSIGN$5) {
23481 a = a.substr(1);
23482 }
23483
23484 if (b !== null && b.charCodeAt(0) === PLUSSIGN$5) {
23485 b = b.substr(1);
23486 }
23487
23488 return {
23489 type: 'AnPlusB',
23490 loc: this.getLocation(start, this.scanner.tokenStart),
23491 a: a,
23492 b: b
23493 };
23494 },
23495 generate: function(node) {
23496 var a = node.a !== null && node.a !== undefined;
23497 var b = node.b !== null && node.b !== undefined;
23498
23499 if (a) {
23500 this.chunk(
23501 node.a === '+1' ? '+n' : // eslint-disable-line operator-linebreak, indent
23502 node.a === '1' ? 'n' : // eslint-disable-line operator-linebreak, indent
23503 node.a === '-1' ? '-n' : // eslint-disable-line operator-linebreak, indent
23504 node.a + 'n' // eslint-disable-line operator-linebreak, indent
23505 );
23506
23507 if (b) {
23508 b = String(node.b);
23509 if (b.charAt(0) === '-' || b.charAt(0) === '+') {
23510 this.chunk(b.charAt(0));
23511 this.chunk(b.substr(1));
23512 } else {
23513 this.chunk('+');
23514 this.chunk(b);
23515 }
23516 }
23517 } else {
23518 this.chunk(String(node.b));
23519 }
23520 }
23521};
23522
23523var tokenizer = tokenizer$3;
23524var TYPE$x = tokenizer.TYPE;
23525
23526var WhiteSpace$1 = TYPE$x.WhiteSpace;
23527var Semicolon = TYPE$x.Semicolon;
23528var LeftCurlyBracket = TYPE$x.LeftCurlyBracket;
23529var Delim = TYPE$x.Delim;
23530var EXCLAMATIONMARK$2 = 0x0021; // U+0021 EXCLAMATION MARK (!)
23531
23532function getOffsetExcludeWS() {
23533 if (this.scanner.tokenIndex > 0) {
23534 if (this.scanner.lookupType(-1) === WhiteSpace$1) {
23535 return this.scanner.tokenIndex > 1
23536 ? this.scanner.getTokenStart(this.scanner.tokenIndex - 1)
23537 : this.scanner.firstCharOffset;
23538 }
23539 }
23540
23541 return this.scanner.tokenStart;
23542}
23543
23544// 0, 0, false
23545function balanceEnd() {
23546 return 0;
23547}
23548
23549// LEFTCURLYBRACKET, 0, false
23550function leftCurlyBracket(tokenType) {
23551 return tokenType === LeftCurlyBracket ? 1 : 0;
23552}
23553
23554// LEFTCURLYBRACKET, SEMICOLON, false
23555function leftCurlyBracketOrSemicolon(tokenType) {
23556 return tokenType === LeftCurlyBracket || tokenType === Semicolon ? 1 : 0;
23557}
23558
23559// EXCLAMATIONMARK, SEMICOLON, false
23560function exclamationMarkOrSemicolon(tokenType, source, offset) {
23561 if (tokenType === Delim && source.charCodeAt(offset) === EXCLAMATIONMARK$2) {
23562 return 1;
23563 }
23564
23565 return tokenType === Semicolon ? 1 : 0;
23566}
23567
23568// 0, SEMICOLON, true
23569function semicolonIncluded(tokenType) {
23570 return tokenType === Semicolon ? 2 : 0;
23571}
23572
23573var Raw = {
23574 name: 'Raw',
23575 structure: {
23576 value: String
23577 },
23578 parse: function(startToken, mode, excludeWhiteSpace) {
23579 var startOffset = this.scanner.getTokenStart(startToken);
23580 var endOffset;
23581
23582 this.scanner.skip(
23583 this.scanner.getRawLength(startToken, mode || balanceEnd)
23584 );
23585
23586 if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
23587 endOffset = getOffsetExcludeWS.call(this);
23588 } else {
23589 endOffset = this.scanner.tokenStart;
23590 }
23591
23592 return {
23593 type: 'Raw',
23594 loc: this.getLocation(startOffset, endOffset),
23595 value: this.scanner.source.substring(startOffset, endOffset)
23596 };
23597 },
23598 generate: function(node) {
23599 this.chunk(node.value);
23600 },
23601
23602 mode: {
23603 default: balanceEnd,
23604 leftCurlyBracket: leftCurlyBracket,
23605 leftCurlyBracketOrSemicolon: leftCurlyBracketOrSemicolon,
23606 exclamationMarkOrSemicolon: exclamationMarkOrSemicolon,
23607 semicolonIncluded: semicolonIncluded
23608 }
23609};
23610
23611var TYPE$w = tokenizer$3.TYPE;
23612var rawMode$5 = Raw.mode;
23613
23614var ATKEYWORD$2 = TYPE$w.AtKeyword;
23615var SEMICOLON$4 = TYPE$w.Semicolon;
23616var LEFTCURLYBRACKET$3 = TYPE$w.LeftCurlyBracket;
23617var RIGHTCURLYBRACKET$1 = TYPE$w.RightCurlyBracket;
23618
23619function consumeRaw$5(startToken) {
23620 return this.Raw(startToken, rawMode$5.leftCurlyBracketOrSemicolon, true);
23621}
23622
23623function isDeclarationBlockAtrule() {
23624 for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
23625 if (type === RIGHTCURLYBRACKET$1) {
23626 return true;
23627 }
23628
23629 if (type === LEFTCURLYBRACKET$3 ||
23630 type === ATKEYWORD$2) {
23631 return false;
23632 }
23633 }
23634
23635 return false;
23636}
23637
23638var Atrule = {
23639 name: 'Atrule',
23640 structure: {
23641 name: String,
23642 prelude: ['AtrulePrelude', 'Raw', null],
23643 block: ['Block', null]
23644 },
23645 parse: function() {
23646 var start = this.scanner.tokenStart;
23647 var name;
23648 var nameLowerCase;
23649 var prelude = null;
23650 var block = null;
23651
23652 this.eat(ATKEYWORD$2);
23653
23654 name = this.scanner.substrToCursor(start + 1);
23655 nameLowerCase = name.toLowerCase();
23656 this.scanner.skipSC();
23657
23658 // parse prelude
23659 if (this.scanner.eof === false &&
23660 this.scanner.tokenType !== LEFTCURLYBRACKET$3 &&
23661 this.scanner.tokenType !== SEMICOLON$4) {
23662 if (this.parseAtrulePrelude) {
23663 prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw$5);
23664
23665 // turn empty AtrulePrelude into null
23666 if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
23667 prelude = null;
23668 }
23669 } else {
23670 prelude = consumeRaw$5.call(this, this.scanner.tokenIndex);
23671 }
23672
23673 this.scanner.skipSC();
23674 }
23675
23676 switch (this.scanner.tokenType) {
23677 case SEMICOLON$4:
23678 this.scanner.next();
23679 break;
23680
23681 case LEFTCURLYBRACKET$3:
23682 if (this.atrule.hasOwnProperty(nameLowerCase) &&
23683 typeof this.atrule[nameLowerCase].block === 'function') {
23684 block = this.atrule[nameLowerCase].block.call(this);
23685 } else {
23686 // TODO: should consume block content as Raw?
23687 block = this.Block(isDeclarationBlockAtrule.call(this));
23688 }
23689
23690 break;
23691 }
23692
23693 return {
23694 type: 'Atrule',
23695 loc: this.getLocation(start, this.scanner.tokenStart),
23696 name: name,
23697 prelude: prelude,
23698 block: block
23699 };
23700 },
23701 generate: function(node) {
23702 this.chunk('@');
23703 this.chunk(node.name);
23704
23705 if (node.prelude !== null) {
23706 this.chunk(' ');
23707 this.node(node.prelude);
23708 }
23709
23710 if (node.block) {
23711 this.node(node.block);
23712 } else {
23713 this.chunk(';');
23714 }
23715 },
23716 walkContext: 'atrule'
23717};
23718
23719var TYPE$v = tokenizer$3.TYPE;
23720
23721var SEMICOLON$3 = TYPE$v.Semicolon;
23722var LEFTCURLYBRACKET$2 = TYPE$v.LeftCurlyBracket;
23723
23724var AtrulePrelude = {
23725 name: 'AtrulePrelude',
23726 structure: {
23727 children: [[]]
23728 },
23729 parse: function(name) {
23730 var children = null;
23731
23732 if (name !== null) {
23733 name = name.toLowerCase();
23734 }
23735
23736 this.scanner.skipSC();
23737
23738 if (this.atrule.hasOwnProperty(name) &&
23739 typeof this.atrule[name].prelude === 'function') {
23740 // custom consumer
23741 children = this.atrule[name].prelude.call(this);
23742 } else {
23743 // default consumer
23744 children = this.readSequence(this.scope.AtrulePrelude);
23745 }
23746
23747 this.scanner.skipSC();
23748
23749 if (this.scanner.eof !== true &&
23750 this.scanner.tokenType !== LEFTCURLYBRACKET$2 &&
23751 this.scanner.tokenType !== SEMICOLON$3) {
23752 this.error('Semicolon or block is expected');
23753 }
23754
23755 if (children === null) {
23756 children = this.createList();
23757 }
23758
23759 return {
23760 type: 'AtrulePrelude',
23761 loc: this.getLocationFromList(children),
23762 children: children
23763 };
23764 },
23765 generate: function(node) {
23766 this.children(node);
23767 },
23768 walkContext: 'atrulePrelude'
23769};
23770
23771var TYPE$u = tokenizer$3.TYPE;
23772
23773var IDENT$e = TYPE$u.Ident;
23774var STRING$3 = TYPE$u.String;
23775var COLON$6 = TYPE$u.Colon;
23776var LEFTSQUAREBRACKET$3 = TYPE$u.LeftSquareBracket;
23777var RIGHTSQUAREBRACKET$1 = TYPE$u.RightSquareBracket;
23778var DOLLARSIGN$1 = 0x0024; // U+0024 DOLLAR SIGN ($)
23779var ASTERISK$5 = 0x002A; // U+002A ASTERISK (*)
23780var EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
23781var CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
23782var VERTICALLINE$2 = 0x007C; // U+007C VERTICAL LINE (|)
23783var TILDE$2 = 0x007E; // U+007E TILDE (~)
23784
23785function getAttributeName() {
23786 if (this.scanner.eof) {
23787 this.error('Unexpected end of input');
23788 }
23789
23790 var start = this.scanner.tokenStart;
23791 var expectIdent = false;
23792 var checkColon = true;
23793
23794 if (this.scanner.isDelim(ASTERISK$5)) {
23795 expectIdent = true;
23796 checkColon = false;
23797 this.scanner.next();
23798 } else if (!this.scanner.isDelim(VERTICALLINE$2)) {
23799 this.eat(IDENT$e);
23800 }
23801
23802 if (this.scanner.isDelim(VERTICALLINE$2)) {
23803 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 1) !== EQUALSSIGN) {
23804 this.scanner.next();
23805 this.eat(IDENT$e);
23806 } else if (expectIdent) {
23807 this.error('Identifier is expected', this.scanner.tokenEnd);
23808 }
23809 } else if (expectIdent) {
23810 this.error('Vertical line is expected');
23811 }
23812
23813 if (checkColon && this.scanner.tokenType === COLON$6) {
23814 this.scanner.next();
23815 this.eat(IDENT$e);
23816 }
23817
23818 return {
23819 type: 'Identifier',
23820 loc: this.getLocation(start, this.scanner.tokenStart),
23821 name: this.scanner.substrToCursor(start)
23822 };
23823}
23824
23825function getOperator() {
23826 var start = this.scanner.tokenStart;
23827 var code = this.scanner.source.charCodeAt(start);
23828
23829 if (code !== EQUALSSIGN && // =
23830 code !== TILDE$2 && // ~=
23831 code !== CIRCUMFLEXACCENT && // ^=
23832 code !== DOLLARSIGN$1 && // $=
23833 code !== ASTERISK$5 && // *=
23834 code !== VERTICALLINE$2 // |=
23835 ) {
23836 this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
23837 }
23838
23839 this.scanner.next();
23840
23841 if (code !== EQUALSSIGN) {
23842 if (!this.scanner.isDelim(EQUALSSIGN)) {
23843 this.error('Equal sign is expected');
23844 }
23845
23846 this.scanner.next();
23847 }
23848
23849 return this.scanner.substrToCursor(start);
23850}
23851
23852// '[' <wq-name> ']'
23853// '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
23854var AttributeSelector = {
23855 name: 'AttributeSelector',
23856 structure: {
23857 name: 'Identifier',
23858 matcher: [String, null],
23859 value: ['String', 'Identifier', null],
23860 flags: [String, null]
23861 },
23862 parse: function() {
23863 var start = this.scanner.tokenStart;
23864 var name;
23865 var matcher = null;
23866 var value = null;
23867 var flags = null;
23868
23869 this.eat(LEFTSQUAREBRACKET$3);
23870 this.scanner.skipSC();
23871
23872 name = getAttributeName.call(this);
23873 this.scanner.skipSC();
23874
23875 if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
23876 // avoid case `[name i]`
23877 if (this.scanner.tokenType !== IDENT$e) {
23878 matcher = getOperator.call(this);
23879
23880 this.scanner.skipSC();
23881
23882 value = this.scanner.tokenType === STRING$3
23883 ? this.String()
23884 : this.Identifier();
23885
23886 this.scanner.skipSC();
23887 }
23888
23889 // attribute flags
23890 if (this.scanner.tokenType === IDENT$e) {
23891 flags = this.scanner.getTokenValue();
23892 this.scanner.next();
23893
23894 this.scanner.skipSC();
23895 }
23896 }
23897
23898 this.eat(RIGHTSQUAREBRACKET$1);
23899
23900 return {
23901 type: 'AttributeSelector',
23902 loc: this.getLocation(start, this.scanner.tokenStart),
23903 name: name,
23904 matcher: matcher,
23905 value: value,
23906 flags: flags
23907 };
23908 },
23909 generate: function(node) {
23910 var flagsPrefix = ' ';
23911
23912 this.chunk('[');
23913 this.node(node.name);
23914
23915 if (node.matcher !== null) {
23916 this.chunk(node.matcher);
23917
23918 if (node.value !== null) {
23919 this.node(node.value);
23920
23921 // space between string and flags is not required
23922 if (node.value.type === 'String') {
23923 flagsPrefix = '';
23924 }
23925 }
23926 }
23927
23928 if (node.flags !== null) {
23929 this.chunk(flagsPrefix);
23930 this.chunk(node.flags);
23931 }
23932
23933 this.chunk(']');
23934 }
23935};
23936
23937var TYPE$t = tokenizer$3.TYPE;
23938var rawMode$4 = Raw.mode;
23939
23940var WHITESPACE$7 = TYPE$t.WhiteSpace;
23941var COMMENT$5 = TYPE$t.Comment;
23942var SEMICOLON$2 = TYPE$t.Semicolon;
23943var ATKEYWORD$1 = TYPE$t.AtKeyword;
23944var LEFTCURLYBRACKET$1 = TYPE$t.LeftCurlyBracket;
23945var RIGHTCURLYBRACKET = TYPE$t.RightCurlyBracket;
23946
23947function consumeRaw$4(startToken) {
23948 return this.Raw(startToken, null, true);
23949}
23950function consumeRule() {
23951 return this.parseWithFallback(this.Rule, consumeRaw$4);
23952}
23953function consumeRawDeclaration(startToken) {
23954 return this.Raw(startToken, rawMode$4.semicolonIncluded, true);
23955}
23956function consumeDeclaration() {
23957 if (this.scanner.tokenType === SEMICOLON$2) {
23958 return consumeRawDeclaration.call(this, this.scanner.tokenIndex);
23959 }
23960
23961 var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
23962
23963 if (this.scanner.tokenType === SEMICOLON$2) {
23964 this.scanner.next();
23965 }
23966
23967 return node;
23968}
23969
23970var Block = {
23971 name: 'Block',
23972 structure: {
23973 children: [[
23974 'Atrule',
23975 'Rule',
23976 'Declaration'
23977 ]]
23978 },
23979 parse: function(isDeclaration) {
23980 var consumer = isDeclaration ? consumeDeclaration : consumeRule;
23981
23982 var start = this.scanner.tokenStart;
23983 var children = this.createList();
23984
23985 this.eat(LEFTCURLYBRACKET$1);
23986
23987 scan:
23988 while (!this.scanner.eof) {
23989 switch (this.scanner.tokenType) {
23990 case RIGHTCURLYBRACKET:
23991 break scan;
23992
23993 case WHITESPACE$7:
23994 case COMMENT$5:
23995 this.scanner.next();
23996 break;
23997
23998 case ATKEYWORD$1:
23999 children.push(this.parseWithFallback(this.Atrule, consumeRaw$4));
24000 break;
24001
24002 default:
24003 children.push(consumer.call(this));
24004 }
24005 }
24006
24007 if (!this.scanner.eof) {
24008 this.eat(RIGHTCURLYBRACKET);
24009 }
24010
24011 return {
24012 type: 'Block',
24013 loc: this.getLocation(start, this.scanner.tokenStart),
24014 children: children
24015 };
24016 },
24017 generate: function(node) {
24018 this.chunk('{');
24019 this.children(node, function(prev) {
24020 if (prev.type === 'Declaration') {
24021 this.chunk(';');
24022 }
24023 });
24024 this.chunk('}');
24025 },
24026 walkContext: 'block'
24027};
24028
24029var TYPE$s = tokenizer$3.TYPE;
24030
24031var LEFTSQUAREBRACKET$2 = TYPE$s.LeftSquareBracket;
24032var RIGHTSQUAREBRACKET = TYPE$s.RightSquareBracket;
24033
24034var Brackets = {
24035 name: 'Brackets',
24036 structure: {
24037 children: [[]]
24038 },
24039 parse: function(readSequence, recognizer) {
24040 var start = this.scanner.tokenStart;
24041 var children = null;
24042
24043 this.eat(LEFTSQUAREBRACKET$2);
24044
24045 children = readSequence.call(this, recognizer);
24046
24047 if (!this.scanner.eof) {
24048 this.eat(RIGHTSQUAREBRACKET);
24049 }
24050
24051 return {
24052 type: 'Brackets',
24053 loc: this.getLocation(start, this.scanner.tokenStart),
24054 children: children
24055 };
24056 },
24057 generate: function(node) {
24058 this.chunk('[');
24059 this.children(node);
24060 this.chunk(']');
24061 }
24062};
24063
24064var CDC$1 = tokenizer$3.TYPE.CDC;
24065
24066var CDC_1 = {
24067 name: 'CDC',
24068 structure: [],
24069 parse: function() {
24070 var start = this.scanner.tokenStart;
24071
24072 this.eat(CDC$1); // -->
24073
24074 return {
24075 type: 'CDC',
24076 loc: this.getLocation(start, this.scanner.tokenStart)
24077 };
24078 },
24079 generate: function() {
24080 this.chunk('-->');
24081 }
24082};
24083
24084var CDO$1 = tokenizer$3.TYPE.CDO;
24085
24086var CDO_1 = {
24087 name: 'CDO',
24088 structure: [],
24089 parse: function() {
24090 var start = this.scanner.tokenStart;
24091
24092 this.eat(CDO$1); // <!--
24093
24094 return {
24095 type: 'CDO',
24096 loc: this.getLocation(start, this.scanner.tokenStart)
24097 };
24098 },
24099 generate: function() {
24100 this.chunk('<!--');
24101 }
24102};
24103
24104var TYPE$r = tokenizer$3.TYPE;
24105
24106var IDENT$d = TYPE$r.Ident;
24107var FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)
24108
24109// '.' ident
24110var ClassSelector = {
24111 name: 'ClassSelector',
24112 structure: {
24113 name: String
24114 },
24115 parse: function() {
24116 if (!this.scanner.isDelim(FULLSTOP$2)) {
24117 this.error('Full stop is expected');
24118 }
24119
24120 this.scanner.next();
24121
24122 return {
24123 type: 'ClassSelector',
24124 loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
24125 name: this.consume(IDENT$d)
24126 };
24127 },
24128 generate: function(node) {
24129 this.chunk('.');
24130 this.chunk(node.name);
24131 }
24132};
24133
24134var TYPE$q = tokenizer$3.TYPE;
24135
24136var IDENT$c = TYPE$q.Ident;
24137var PLUSSIGN$4 = 0x002B; // U+002B PLUS SIGN (+)
24138var SOLIDUS$5 = 0x002F; // U+002F SOLIDUS (/)
24139var GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)
24140var TILDE$1 = 0x007E; // U+007E TILDE (~)
24141
24142// + | > | ~ | /deep/
24143var Combinator = {
24144 name: 'Combinator',
24145 structure: {
24146 name: String
24147 },
24148 parse: function() {
24149 var start = this.scanner.tokenStart;
24150 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
24151
24152 switch (code) {
24153 case GREATERTHANSIGN$1:
24154 case PLUSSIGN$4:
24155 case TILDE$1:
24156 this.scanner.next();
24157 break;
24158
24159 case SOLIDUS$5:
24160 this.scanner.next();
24161
24162 if (this.scanner.tokenType !== IDENT$c || this.scanner.lookupValue(0, 'deep') === false) {
24163 this.error('Identifier `deep` is expected');
24164 }
24165
24166 this.scanner.next();
24167
24168 if (!this.scanner.isDelim(SOLIDUS$5)) {
24169 this.error('Solidus is expected');
24170 }
24171
24172 this.scanner.next();
24173 break;
24174
24175 default:
24176 this.error('Combinator is expected');
24177 }
24178
24179 return {
24180 type: 'Combinator',
24181 loc: this.getLocation(start, this.scanner.tokenStart),
24182 name: this.scanner.substrToCursor(start)
24183 };
24184 },
24185 generate: function(node) {
24186 this.chunk(node.name);
24187 }
24188};
24189
24190var TYPE$p = tokenizer$3.TYPE;
24191
24192var COMMENT$4 = TYPE$p.Comment;
24193var ASTERISK$4 = 0x002A; // U+002A ASTERISK (*)
24194var SOLIDUS$4 = 0x002F; // U+002F SOLIDUS (/)
24195
24196// '/*' .* '*/'
24197var Comment = {
24198 name: 'Comment',
24199 structure: {
24200 value: String
24201 },
24202 parse: function() {
24203 var start = this.scanner.tokenStart;
24204 var end = this.scanner.tokenEnd;
24205
24206 this.eat(COMMENT$4);
24207
24208 if ((end - start + 2) >= 2 &&
24209 this.scanner.source.charCodeAt(end - 2) === ASTERISK$4 &&
24210 this.scanner.source.charCodeAt(end - 1) === SOLIDUS$4) {
24211 end -= 2;
24212 }
24213
24214 return {
24215 type: 'Comment',
24216 loc: this.getLocation(start, this.scanner.tokenStart),
24217 value: this.scanner.source.substring(start + 2, end)
24218 };
24219 },
24220 generate: function(node) {
24221 this.chunk('/*');
24222 this.chunk(node.value);
24223 this.chunk('*/');
24224 }
24225};
24226
24227var isCustomProperty = names$2.isCustomProperty;
24228var TYPE$o = tokenizer$3.TYPE;
24229var rawMode$3 = Raw.mode;
24230
24231var IDENT$b = TYPE$o.Ident;
24232var HASH$4 = TYPE$o.Hash;
24233var COLON$5 = TYPE$o.Colon;
24234var SEMICOLON$1 = TYPE$o.Semicolon;
24235var DELIM$4 = TYPE$o.Delim;
24236var WHITESPACE$6 = TYPE$o.WhiteSpace;
24237var EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)
24238var NUMBERSIGN$2 = 0x0023; // U+0023 NUMBER SIGN (#)
24239var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
24240var AMPERSAND = 0x0026; // U+0026 ANPERSAND (&)
24241var ASTERISK$3 = 0x002A; // U+002A ASTERISK (*)
24242var PLUSSIGN$3 = 0x002B; // U+002B PLUS SIGN (+)
24243var SOLIDUS$3 = 0x002F; // U+002F SOLIDUS (/)
24244
24245function consumeValueRaw(startToken) {
24246 return this.Raw(startToken, rawMode$3.exclamationMarkOrSemicolon, true);
24247}
24248
24249function consumeCustomPropertyRaw(startToken) {
24250 return this.Raw(startToken, rawMode$3.exclamationMarkOrSemicolon, false);
24251}
24252
24253function consumeValue() {
24254 var startValueToken = this.scanner.tokenIndex;
24255 var value = this.Value();
24256
24257 if (value.type !== 'Raw' &&
24258 this.scanner.eof === false &&
24259 this.scanner.tokenType !== SEMICOLON$1 &&
24260 this.scanner.isDelim(EXCLAMATIONMARK$1) === false &&
24261 this.scanner.isBalanceEdge(startValueToken) === false) {
24262 this.error();
24263 }
24264
24265 return value;
24266}
24267
24268var Declaration = {
24269 name: 'Declaration',
24270 structure: {
24271 important: [Boolean, String],
24272 property: String,
24273 value: ['Value', 'Raw']
24274 },
24275 parse: function() {
24276 var start = this.scanner.tokenStart;
24277 var startToken = this.scanner.tokenIndex;
24278 var property = readProperty.call(this);
24279 var customProperty = isCustomProperty(property);
24280 var parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
24281 var consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
24282 var important = false;
24283 var value;
24284
24285 this.scanner.skipSC();
24286 this.eat(COLON$5);
24287
24288 const valueStart = this.scanner.tokenIndex;
24289
24290 if (!customProperty) {
24291 this.scanner.skipSC();
24292 }
24293
24294 if (parseValue) {
24295 value = this.parseWithFallback(consumeValue, consumeRaw);
24296 } else {
24297 value = consumeRaw.call(this, this.scanner.tokenIndex);
24298 }
24299
24300 if (customProperty && value.type === 'Value' && value.children.isEmpty()) {
24301 for (let offset = valueStart - this.scanner.tokenIndex; offset <= 0; offset++) {
24302 if (this.scanner.lookupType(offset) === WHITESPACE$6) {
24303 value.children.appendData({
24304 type: 'WhiteSpace',
24305 loc: null,
24306 value: ' '
24307 });
24308 break;
24309 }
24310 }
24311 }
24312
24313 if (this.scanner.isDelim(EXCLAMATIONMARK$1)) {
24314 important = getImportant.call(this);
24315 this.scanner.skipSC();
24316 }
24317
24318 // Do not include semicolon to range per spec
24319 // https://drafts.csswg.org/css-syntax/#declaration-diagram
24320
24321 if (this.scanner.eof === false &&
24322 this.scanner.tokenType !== SEMICOLON$1 &&
24323 this.scanner.isBalanceEdge(startToken) === false) {
24324 this.error();
24325 }
24326
24327 return {
24328 type: 'Declaration',
24329 loc: this.getLocation(start, this.scanner.tokenStart),
24330 important: important,
24331 property: property,
24332 value: value
24333 };
24334 },
24335 generate: function(node) {
24336 this.chunk(node.property);
24337 this.chunk(':');
24338 this.node(node.value);
24339
24340 if (node.important) {
24341 this.chunk(node.important === true ? '!important' : '!' + node.important);
24342 }
24343 },
24344 walkContext: 'declaration'
24345};
24346
24347function readProperty() {
24348 var start = this.scanner.tokenStart;
24349
24350 // hacks
24351 if (this.scanner.tokenType === DELIM$4) {
24352 switch (this.scanner.source.charCodeAt(this.scanner.tokenStart)) {
24353 case ASTERISK$3:
24354 case DOLLARSIGN:
24355 case PLUSSIGN$3:
24356 case NUMBERSIGN$2:
24357 case AMPERSAND:
24358 this.scanner.next();
24359 break;
24360
24361 // TODO: not sure we should support this hack
24362 case SOLIDUS$3:
24363 this.scanner.next();
24364 if (this.scanner.isDelim(SOLIDUS$3)) {
24365 this.scanner.next();
24366 }
24367 break;
24368 }
24369 }
24370
24371 if (this.scanner.tokenType === HASH$4) {
24372 this.eat(HASH$4);
24373 } else {
24374 this.eat(IDENT$b);
24375 }
24376
24377 return this.scanner.substrToCursor(start);
24378}
24379
24380// ! ws* important
24381function getImportant() {
24382 this.eat(DELIM$4);
24383 this.scanner.skipSC();
24384
24385 var important = this.consume(IDENT$b);
24386
24387 // store original value in case it differ from `important`
24388 // for better original source restoring and hacks like `!ie` support
24389 return important === 'important' ? true : important;
24390}
24391
24392var TYPE$n = tokenizer$3.TYPE;
24393var rawMode$2 = Raw.mode;
24394
24395var WHITESPACE$5 = TYPE$n.WhiteSpace;
24396var COMMENT$3 = TYPE$n.Comment;
24397var SEMICOLON = TYPE$n.Semicolon;
24398
24399function consumeRaw$3(startToken) {
24400 return this.Raw(startToken, rawMode$2.semicolonIncluded, true);
24401}
24402
24403var DeclarationList = {
24404 name: 'DeclarationList',
24405 structure: {
24406 children: [[
24407 'Declaration'
24408 ]]
24409 },
24410 parse: function() {
24411 var children = this.createList();
24412
24413 while (!this.scanner.eof) {
24414 switch (this.scanner.tokenType) {
24415 case WHITESPACE$5:
24416 case COMMENT$3:
24417 case SEMICOLON:
24418 this.scanner.next();
24419 break;
24420
24421 default:
24422 children.push(this.parseWithFallback(this.Declaration, consumeRaw$3));
24423 }
24424 }
24425
24426 return {
24427 type: 'DeclarationList',
24428 loc: this.getLocationFromList(children),
24429 children: children
24430 };
24431 },
24432 generate: function(node) {
24433 this.children(node, function(prev) {
24434 if (prev.type === 'Declaration') {
24435 this.chunk(';');
24436 }
24437 });
24438 }
24439};
24440
24441var consumeNumber$2 = utils$2.consumeNumber;
24442var TYPE$m = tokenizer$3.TYPE;
24443
24444var DIMENSION$4 = TYPE$m.Dimension;
24445
24446var Dimension = {
24447 name: 'Dimension',
24448 structure: {
24449 value: String,
24450 unit: String
24451 },
24452 parse: function() {
24453 var start = this.scanner.tokenStart;
24454 var numberEnd = consumeNumber$2(this.scanner.source, start);
24455
24456 this.eat(DIMENSION$4);
24457
24458 return {
24459 type: 'Dimension',
24460 loc: this.getLocation(start, this.scanner.tokenStart),
24461 value: this.scanner.source.substring(start, numberEnd),
24462 unit: this.scanner.source.substring(numberEnd, this.scanner.tokenStart)
24463 };
24464 },
24465 generate: function(node) {
24466 this.chunk(node.value);
24467 this.chunk(node.unit);
24468 }
24469};
24470
24471var TYPE$l = tokenizer$3.TYPE;
24472
24473var RIGHTPARENTHESIS$5 = TYPE$l.RightParenthesis;
24474
24475// <function-token> <sequence> )
24476var _Function = {
24477 name: 'Function',
24478 structure: {
24479 name: String,
24480 children: [[]]
24481 },
24482 parse: function(readSequence, recognizer) {
24483 var start = this.scanner.tokenStart;
24484 var name = this.consumeFunctionName();
24485 var nameLowerCase = name.toLowerCase();
24486 var children;
24487
24488 children = recognizer.hasOwnProperty(nameLowerCase)
24489 ? recognizer[nameLowerCase].call(this, recognizer)
24490 : readSequence.call(this, recognizer);
24491
24492 if (!this.scanner.eof) {
24493 this.eat(RIGHTPARENTHESIS$5);
24494 }
24495
24496 return {
24497 type: 'Function',
24498 loc: this.getLocation(start, this.scanner.tokenStart),
24499 name: name,
24500 children: children
24501 };
24502 },
24503 generate: function(node) {
24504 this.chunk(node.name);
24505 this.chunk('(');
24506 this.children(node);
24507 this.chunk(')');
24508 },
24509 walkContext: 'function'
24510};
24511
24512var TYPE$k = tokenizer$3.TYPE;
24513
24514var HASH$3 = TYPE$k.Hash;
24515
24516// '#' ident
24517var Hash = {
24518 name: 'Hash',
24519 structure: {
24520 value: String
24521 },
24522 parse: function() {
24523 var start = this.scanner.tokenStart;
24524
24525 this.eat(HASH$3);
24526
24527 return {
24528 type: 'Hash',
24529 loc: this.getLocation(start, this.scanner.tokenStart),
24530 value: this.scanner.substrToCursor(start + 1)
24531 };
24532 },
24533 generate: function(node) {
24534 this.chunk('#');
24535 this.chunk(node.value);
24536 }
24537};
24538
24539var TYPE$j = tokenizer$3.TYPE;
24540
24541var IDENT$a = TYPE$j.Ident;
24542
24543var Identifier = {
24544 name: 'Identifier',
24545 structure: {
24546 name: String
24547 },
24548 parse: function() {
24549 return {
24550 type: 'Identifier',
24551 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
24552 name: this.consume(IDENT$a)
24553 };
24554 },
24555 generate: function(node) {
24556 this.chunk(node.name);
24557 }
24558};
24559
24560var TYPE$i = tokenizer$3.TYPE;
24561
24562var HASH$2 = TYPE$i.Hash;
24563
24564// <hash-token>
24565var IdSelector = {
24566 name: 'IdSelector',
24567 structure: {
24568 name: String
24569 },
24570 parse: function() {
24571 var start = this.scanner.tokenStart;
24572
24573 // TODO: check value is an ident
24574 this.eat(HASH$2);
24575
24576 return {
24577 type: 'IdSelector',
24578 loc: this.getLocation(start, this.scanner.tokenStart),
24579 name: this.scanner.substrToCursor(start + 1)
24580 };
24581 },
24582 generate: function(node) {
24583 this.chunk('#');
24584 this.chunk(node.name);
24585 }
24586};
24587
24588var TYPE$h = tokenizer$3.TYPE;
24589
24590var IDENT$9 = TYPE$h.Ident;
24591var NUMBER$5 = TYPE$h.Number;
24592var DIMENSION$3 = TYPE$h.Dimension;
24593var LEFTPARENTHESIS$5 = TYPE$h.LeftParenthesis;
24594var RIGHTPARENTHESIS$4 = TYPE$h.RightParenthesis;
24595var COLON$4 = TYPE$h.Colon;
24596var DELIM$3 = TYPE$h.Delim;
24597
24598var MediaFeature = {
24599 name: 'MediaFeature',
24600 structure: {
24601 name: String,
24602 value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
24603 },
24604 parse: function() {
24605 var start = this.scanner.tokenStart;
24606 var name;
24607 var value = null;
24608
24609 this.eat(LEFTPARENTHESIS$5);
24610 this.scanner.skipSC();
24611
24612 name = this.consume(IDENT$9);
24613 this.scanner.skipSC();
24614
24615 if (this.scanner.tokenType !== RIGHTPARENTHESIS$4) {
24616 this.eat(COLON$4);
24617 this.scanner.skipSC();
24618
24619 switch (this.scanner.tokenType) {
24620 case NUMBER$5:
24621 if (this.lookupNonWSType(1) === DELIM$3) {
24622 value = this.Ratio();
24623 } else {
24624 value = this.Number();
24625 }
24626
24627 break;
24628
24629 case DIMENSION$3:
24630 value = this.Dimension();
24631 break;
24632
24633 case IDENT$9:
24634 value = this.Identifier();
24635
24636 break;
24637
24638 default:
24639 this.error('Number, dimension, ratio or identifier is expected');
24640 }
24641
24642 this.scanner.skipSC();
24643 }
24644
24645 this.eat(RIGHTPARENTHESIS$4);
24646
24647 return {
24648 type: 'MediaFeature',
24649 loc: this.getLocation(start, this.scanner.tokenStart),
24650 name: name,
24651 value: value
24652 };
24653 },
24654 generate: function(node) {
24655 this.chunk('(');
24656 this.chunk(node.name);
24657 if (node.value !== null) {
24658 this.chunk(':');
24659 this.node(node.value);
24660 }
24661 this.chunk(')');
24662 }
24663};
24664
24665var TYPE$g = tokenizer$3.TYPE;
24666
24667var WHITESPACE$4 = TYPE$g.WhiteSpace;
24668var COMMENT$2 = TYPE$g.Comment;
24669var IDENT$8 = TYPE$g.Ident;
24670var LEFTPARENTHESIS$4 = TYPE$g.LeftParenthesis;
24671
24672var MediaQuery = {
24673 name: 'MediaQuery',
24674 structure: {
24675 children: [[
24676 'Identifier',
24677 'MediaFeature',
24678 'WhiteSpace'
24679 ]]
24680 },
24681 parse: function() {
24682 this.scanner.skipSC();
24683
24684 var children = this.createList();
24685 var child = null;
24686 var space = null;
24687
24688 scan:
24689 while (!this.scanner.eof) {
24690 switch (this.scanner.tokenType) {
24691 case COMMENT$2:
24692 this.scanner.next();
24693 continue;
24694
24695 case WHITESPACE$4:
24696 space = this.WhiteSpace();
24697 continue;
24698
24699 case IDENT$8:
24700 child = this.Identifier();
24701 break;
24702
24703 case LEFTPARENTHESIS$4:
24704 child = this.MediaFeature();
24705 break;
24706
24707 default:
24708 break scan;
24709 }
24710
24711 if (space !== null) {
24712 children.push(space);
24713 space = null;
24714 }
24715
24716 children.push(child);
24717 }
24718
24719 if (child === null) {
24720 this.error('Identifier or parenthesis is expected');
24721 }
24722
24723 return {
24724 type: 'MediaQuery',
24725 loc: this.getLocationFromList(children),
24726 children: children
24727 };
24728 },
24729 generate: function(node) {
24730 this.children(node);
24731 }
24732};
24733
24734var COMMA$3 = tokenizer$3.TYPE.Comma;
24735
24736var MediaQueryList = {
24737 name: 'MediaQueryList',
24738 structure: {
24739 children: [[
24740 'MediaQuery'
24741 ]]
24742 },
24743 parse: function(relative) {
24744 var children = this.createList();
24745
24746 this.scanner.skipSC();
24747
24748 while (!this.scanner.eof) {
24749 children.push(this.MediaQuery(relative));
24750
24751 if (this.scanner.tokenType !== COMMA$3) {
24752 break;
24753 }
24754
24755 this.scanner.next();
24756 }
24757
24758 return {
24759 type: 'MediaQueryList',
24760 loc: this.getLocationFromList(children),
24761 children: children
24762 };
24763 },
24764 generate: function(node) {
24765 this.children(node, function() {
24766 this.chunk(',');
24767 });
24768 }
24769};
24770
24771var Nth = {
24772 name: 'Nth',
24773 structure: {
24774 nth: ['AnPlusB', 'Identifier'],
24775 selector: ['SelectorList', null]
24776 },
24777 parse: function(allowOfClause) {
24778 this.scanner.skipSC();
24779
24780 var start = this.scanner.tokenStart;
24781 var end = start;
24782 var selector = null;
24783 var query;
24784
24785 if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
24786 query = this.Identifier();
24787 } else {
24788 query = this.AnPlusB();
24789 }
24790
24791 this.scanner.skipSC();
24792
24793 if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
24794 this.scanner.next();
24795
24796 selector = this.SelectorList();
24797
24798 if (this.needPositions) {
24799 end = this.getLastListNode(selector.children).loc.end.offset;
24800 }
24801 } else {
24802 if (this.needPositions) {
24803 end = query.loc.end.offset;
24804 }
24805 }
24806
24807 return {
24808 type: 'Nth',
24809 loc: this.getLocation(start, end),
24810 nth: query,
24811 selector: selector
24812 };
24813 },
24814 generate: function(node) {
24815 this.node(node.nth);
24816 if (node.selector !== null) {
24817 this.chunk(' of ');
24818 this.node(node.selector);
24819 }
24820 }
24821};
24822
24823var NUMBER$4 = tokenizer$3.TYPE.Number;
24824
24825var _Number = {
24826 name: 'Number',
24827 structure: {
24828 value: String
24829 },
24830 parse: function() {
24831 return {
24832 type: 'Number',
24833 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
24834 value: this.consume(NUMBER$4)
24835 };
24836 },
24837 generate: function(node) {
24838 this.chunk(node.value);
24839 }
24840};
24841
24842// '/' | '*' | ',' | ':' | '+' | '-'
24843var Operator = {
24844 name: 'Operator',
24845 structure: {
24846 value: String
24847 },
24848 parse: function() {
24849 var start = this.scanner.tokenStart;
24850
24851 this.scanner.next();
24852
24853 return {
24854 type: 'Operator',
24855 loc: this.getLocation(start, this.scanner.tokenStart),
24856 value: this.scanner.substrToCursor(start)
24857 };
24858 },
24859 generate: function(node) {
24860 this.chunk(node.value);
24861 }
24862};
24863
24864var TYPE$f = tokenizer$3.TYPE;
24865
24866var LEFTPARENTHESIS$3 = TYPE$f.LeftParenthesis;
24867var RIGHTPARENTHESIS$3 = TYPE$f.RightParenthesis;
24868
24869var Parentheses = {
24870 name: 'Parentheses',
24871 structure: {
24872 children: [[]]
24873 },
24874 parse: function(readSequence, recognizer) {
24875 var start = this.scanner.tokenStart;
24876 var children = null;
24877
24878 this.eat(LEFTPARENTHESIS$3);
24879
24880 children = readSequence.call(this, recognizer);
24881
24882 if (!this.scanner.eof) {
24883 this.eat(RIGHTPARENTHESIS$3);
24884 }
24885
24886 return {
24887 type: 'Parentheses',
24888 loc: this.getLocation(start, this.scanner.tokenStart),
24889 children: children
24890 };
24891 },
24892 generate: function(node) {
24893 this.chunk('(');
24894 this.children(node);
24895 this.chunk(')');
24896 }
24897};
24898
24899var consumeNumber$1 = utils$2.consumeNumber;
24900var TYPE$e = tokenizer$3.TYPE;
24901
24902var PERCENTAGE$2 = TYPE$e.Percentage;
24903
24904var Percentage = {
24905 name: 'Percentage',
24906 structure: {
24907 value: String
24908 },
24909 parse: function() {
24910 var start = this.scanner.tokenStart;
24911 var numberEnd = consumeNumber$1(this.scanner.source, start);
24912
24913 this.eat(PERCENTAGE$2);
24914
24915 return {
24916 type: 'Percentage',
24917 loc: this.getLocation(start, this.scanner.tokenStart),
24918 value: this.scanner.source.substring(start, numberEnd)
24919 };
24920 },
24921 generate: function(node) {
24922 this.chunk(node.value);
24923 this.chunk('%');
24924 }
24925};
24926
24927var TYPE$d = tokenizer$3.TYPE;
24928
24929var IDENT$7 = TYPE$d.Ident;
24930var FUNCTION$5 = TYPE$d.Function;
24931var COLON$3 = TYPE$d.Colon;
24932var RIGHTPARENTHESIS$2 = TYPE$d.RightParenthesis;
24933
24934// : [ <ident> | <function-token> <any-value>? ) ]
24935var PseudoClassSelector = {
24936 name: 'PseudoClassSelector',
24937 structure: {
24938 name: String,
24939 children: [['Raw'], null]
24940 },
24941 parse: function() {
24942 var start = this.scanner.tokenStart;
24943 var children = null;
24944 var name;
24945 var nameLowerCase;
24946
24947 this.eat(COLON$3);
24948
24949 if (this.scanner.tokenType === FUNCTION$5) {
24950 name = this.consumeFunctionName();
24951 nameLowerCase = name.toLowerCase();
24952
24953 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
24954 this.scanner.skipSC();
24955 children = this.pseudo[nameLowerCase].call(this);
24956 this.scanner.skipSC();
24957 } else {
24958 children = this.createList();
24959 children.push(
24960 this.Raw(this.scanner.tokenIndex, null, false)
24961 );
24962 }
24963
24964 this.eat(RIGHTPARENTHESIS$2);
24965 } else {
24966 name = this.consume(IDENT$7);
24967 }
24968
24969 return {
24970 type: 'PseudoClassSelector',
24971 loc: this.getLocation(start, this.scanner.tokenStart),
24972 name: name,
24973 children: children
24974 };
24975 },
24976 generate: function(node) {
24977 this.chunk(':');
24978 this.chunk(node.name);
24979
24980 if (node.children !== null) {
24981 this.chunk('(');
24982 this.children(node);
24983 this.chunk(')');
24984 }
24985 },
24986 walkContext: 'function'
24987};
24988
24989var TYPE$c = tokenizer$3.TYPE;
24990
24991var IDENT$6 = TYPE$c.Ident;
24992var FUNCTION$4 = TYPE$c.Function;
24993var COLON$2 = TYPE$c.Colon;
24994var RIGHTPARENTHESIS$1 = TYPE$c.RightParenthesis;
24995
24996// :: [ <ident> | <function-token> <any-value>? ) ]
24997var PseudoElementSelector = {
24998 name: 'PseudoElementSelector',
24999 structure: {
25000 name: String,
25001 children: [['Raw'], null]
25002 },
25003 parse: function() {
25004 var start = this.scanner.tokenStart;
25005 var children = null;
25006 var name;
25007 var nameLowerCase;
25008
25009 this.eat(COLON$2);
25010 this.eat(COLON$2);
25011
25012 if (this.scanner.tokenType === FUNCTION$4) {
25013 name = this.consumeFunctionName();
25014 nameLowerCase = name.toLowerCase();
25015
25016 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
25017 this.scanner.skipSC();
25018 children = this.pseudo[nameLowerCase].call(this);
25019 this.scanner.skipSC();
25020 } else {
25021 children = this.createList();
25022 children.push(
25023 this.Raw(this.scanner.tokenIndex, null, false)
25024 );
25025 }
25026
25027 this.eat(RIGHTPARENTHESIS$1);
25028 } else {
25029 name = this.consume(IDENT$6);
25030 }
25031
25032 return {
25033 type: 'PseudoElementSelector',
25034 loc: this.getLocation(start, this.scanner.tokenStart),
25035 name: name,
25036 children: children
25037 };
25038 },
25039 generate: function(node) {
25040 this.chunk('::');
25041 this.chunk(node.name);
25042
25043 if (node.children !== null) {
25044 this.chunk('(');
25045 this.children(node);
25046 this.chunk(')');
25047 }
25048 },
25049 walkContext: 'function'
25050};
25051
25052var isDigit = tokenizer$3.isDigit;
25053var TYPE$b = tokenizer$3.TYPE;
25054
25055var NUMBER$3 = TYPE$b.Number;
25056var DELIM$2 = TYPE$b.Delim;
25057var SOLIDUS$2 = 0x002F; // U+002F SOLIDUS (/)
25058var FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)
25059
25060// Terms of <ratio> should be a positive numbers (not zero or negative)
25061// (see https://drafts.csswg.org/mediaqueries-3/#values)
25062// However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
25063// and this is using by various sites. Therefore we relax checking on parse
25064// to test a term is unsigned number without an exponent part.
25065// Additional checking may be applied on lexer validation.
25066function consumeNumber() {
25067 this.scanner.skipWS();
25068
25069 var value = this.consume(NUMBER$3);
25070
25071 for (var i = 0; i < value.length; i++) {
25072 var code = value.charCodeAt(i);
25073 if (!isDigit(code) && code !== FULLSTOP$1) {
25074 this.error('Unsigned number is expected', this.scanner.tokenStart - value.length + i);
25075 }
25076 }
25077
25078 if (Number(value) === 0) {
25079 this.error('Zero number is not allowed', this.scanner.tokenStart - value.length);
25080 }
25081
25082 return value;
25083}
25084
25085// <positive-integer> S* '/' S* <positive-integer>
25086var Ratio = {
25087 name: 'Ratio',
25088 structure: {
25089 left: String,
25090 right: String
25091 },
25092 parse: function() {
25093 var start = this.scanner.tokenStart;
25094 var left = consumeNumber.call(this);
25095 var right;
25096
25097 this.scanner.skipWS();
25098
25099 if (!this.scanner.isDelim(SOLIDUS$2)) {
25100 this.error('Solidus is expected');
25101 }
25102 this.eat(DELIM$2);
25103 right = consumeNumber.call(this);
25104
25105 return {
25106 type: 'Ratio',
25107 loc: this.getLocation(start, this.scanner.tokenStart),
25108 left: left,
25109 right: right
25110 };
25111 },
25112 generate: function(node) {
25113 this.chunk(node.left);
25114 this.chunk('/');
25115 this.chunk(node.right);
25116 }
25117};
25118
25119var TYPE$a = tokenizer$3.TYPE;
25120var rawMode$1 = Raw.mode;
25121
25122var LEFTCURLYBRACKET = TYPE$a.LeftCurlyBracket;
25123
25124function consumeRaw$2(startToken) {
25125 return this.Raw(startToken, rawMode$1.leftCurlyBracket, true);
25126}
25127
25128function consumePrelude() {
25129 var prelude = this.SelectorList();
25130
25131 if (prelude.type !== 'Raw' &&
25132 this.scanner.eof === false &&
25133 this.scanner.tokenType !== LEFTCURLYBRACKET) {
25134 this.error();
25135 }
25136
25137 return prelude;
25138}
25139
25140var Rule = {
25141 name: 'Rule',
25142 structure: {
25143 prelude: ['SelectorList', 'Raw'],
25144 block: ['Block']
25145 },
25146 parse: function() {
25147 var startToken = this.scanner.tokenIndex;
25148 var startOffset = this.scanner.tokenStart;
25149 var prelude;
25150 var block;
25151
25152 if (this.parseRulePrelude) {
25153 prelude = this.parseWithFallback(consumePrelude, consumeRaw$2);
25154 } else {
25155 prelude = consumeRaw$2.call(this, startToken);
25156 }
25157
25158 block = this.Block(true);
25159
25160 return {
25161 type: 'Rule',
25162 loc: this.getLocation(startOffset, this.scanner.tokenStart),
25163 prelude: prelude,
25164 block: block
25165 };
25166 },
25167 generate: function(node) {
25168 this.node(node.prelude);
25169 this.node(node.block);
25170 },
25171 walkContext: 'rule'
25172};
25173
25174var Selector = {
25175 name: 'Selector',
25176 structure: {
25177 children: [[
25178 'TypeSelector',
25179 'IdSelector',
25180 'ClassSelector',
25181 'AttributeSelector',
25182 'PseudoClassSelector',
25183 'PseudoElementSelector',
25184 'Combinator',
25185 'WhiteSpace'
25186 ]]
25187 },
25188 parse: function() {
25189 var children = this.readSequence(this.scope.Selector);
25190
25191 // nothing were consumed
25192 if (this.getFirstListNode(children) === null) {
25193 this.error('Selector is expected');
25194 }
25195
25196 return {
25197 type: 'Selector',
25198 loc: this.getLocationFromList(children),
25199 children: children
25200 };
25201 },
25202 generate: function(node) {
25203 this.children(node);
25204 }
25205};
25206
25207var TYPE$9 = tokenizer$3.TYPE;
25208
25209var COMMA$2 = TYPE$9.Comma;
25210
25211var SelectorList = {
25212 name: 'SelectorList',
25213 structure: {
25214 children: [[
25215 'Selector',
25216 'Raw'
25217 ]]
25218 },
25219 parse: function() {
25220 var children = this.createList();
25221
25222 while (!this.scanner.eof) {
25223 children.push(this.Selector());
25224
25225 if (this.scanner.tokenType === COMMA$2) {
25226 this.scanner.next();
25227 continue;
25228 }
25229
25230 break;
25231 }
25232
25233 return {
25234 type: 'SelectorList',
25235 loc: this.getLocationFromList(children),
25236 children: children
25237 };
25238 },
25239 generate: function(node) {
25240 this.children(node, function() {
25241 this.chunk(',');
25242 });
25243 },
25244 walkContext: 'selector'
25245};
25246
25247var STRING$2 = tokenizer$3.TYPE.String;
25248
25249var _String = {
25250 name: 'String',
25251 structure: {
25252 value: String
25253 },
25254 parse: function() {
25255 return {
25256 type: 'String',
25257 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
25258 value: this.consume(STRING$2)
25259 };
25260 },
25261 generate: function(node) {
25262 this.chunk(node.value);
25263 }
25264};
25265
25266var TYPE$8 = tokenizer$3.TYPE;
25267
25268var WHITESPACE$3 = TYPE$8.WhiteSpace;
25269var COMMENT$1 = TYPE$8.Comment;
25270var ATKEYWORD = TYPE$8.AtKeyword;
25271var CDO = TYPE$8.CDO;
25272var CDC = TYPE$8.CDC;
25273var EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
25274
25275function consumeRaw$1(startToken) {
25276 return this.Raw(startToken, null, false);
25277}
25278
25279var StyleSheet = {
25280 name: 'StyleSheet',
25281 structure: {
25282 children: [[
25283 'Comment',
25284 'CDO',
25285 'CDC',
25286 'Atrule',
25287 'Rule',
25288 'Raw'
25289 ]]
25290 },
25291 parse: function() {
25292 var start = this.scanner.tokenStart;
25293 var children = this.createList();
25294 var child;
25295
25296 while (!this.scanner.eof) {
25297 switch (this.scanner.tokenType) {
25298 case WHITESPACE$3:
25299 this.scanner.next();
25300 continue;
25301
25302 case COMMENT$1:
25303 // ignore comments except exclamation comments (i.e. /*! .. */) on top level
25304 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK) {
25305 this.scanner.next();
25306 continue;
25307 }
25308
25309 child = this.Comment();
25310 break;
25311
25312 case CDO: // <!--
25313 child = this.CDO();
25314 break;
25315
25316 case CDC: // -->
25317 child = this.CDC();
25318 break;
25319
25320 // CSS Syntax Module Level 3
25321 // §2.2 Error handling
25322 // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
25323 case ATKEYWORD:
25324 child = this.parseWithFallback(this.Atrule, consumeRaw$1);
25325 break;
25326
25327 // Anything else starts a qualified rule ...
25328 default:
25329 child = this.parseWithFallback(this.Rule, consumeRaw$1);
25330 }
25331
25332 children.push(child);
25333 }
25334
25335 return {
25336 type: 'StyleSheet',
25337 loc: this.getLocation(start, this.scanner.tokenStart),
25338 children: children
25339 };
25340 },
25341 generate: function(node) {
25342 this.children(node);
25343 },
25344 walkContext: 'stylesheet'
25345};
25346
25347var TYPE$7 = tokenizer$3.TYPE;
25348
25349var IDENT$5 = TYPE$7.Ident;
25350var ASTERISK$2 = 0x002A; // U+002A ASTERISK (*)
25351var VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)
25352
25353function eatIdentifierOrAsterisk() {
25354 if (this.scanner.tokenType !== IDENT$5 &&
25355 this.scanner.isDelim(ASTERISK$2) === false) {
25356 this.error('Identifier or asterisk is expected');
25357 }
25358
25359 this.scanner.next();
25360}
25361
25362// ident
25363// ident|ident
25364// ident|*
25365// *
25366// *|ident
25367// *|*
25368// |ident
25369// |*
25370var TypeSelector = {
25371 name: 'TypeSelector',
25372 structure: {
25373 name: String
25374 },
25375 parse: function() {
25376 var start = this.scanner.tokenStart;
25377
25378 if (this.scanner.isDelim(VERTICALLINE$1)) {
25379 this.scanner.next();
25380 eatIdentifierOrAsterisk.call(this);
25381 } else {
25382 eatIdentifierOrAsterisk.call(this);
25383
25384 if (this.scanner.isDelim(VERTICALLINE$1)) {
25385 this.scanner.next();
25386 eatIdentifierOrAsterisk.call(this);
25387 }
25388 }
25389
25390 return {
25391 type: 'TypeSelector',
25392 loc: this.getLocation(start, this.scanner.tokenStart),
25393 name: this.scanner.substrToCursor(start)
25394 };
25395 },
25396 generate: function(node) {
25397 this.chunk(node.name);
25398 }
25399};
25400
25401var isHexDigit = tokenizer$3.isHexDigit;
25402var cmpChar$1 = tokenizer$3.cmpChar;
25403var TYPE$6 = tokenizer$3.TYPE;
25404var NAME = tokenizer$3.NAME;
25405
25406var IDENT$4 = TYPE$6.Ident;
25407var NUMBER$2 = TYPE$6.Number;
25408var DIMENSION$2 = TYPE$6.Dimension;
25409var PLUSSIGN$2 = 0x002B; // U+002B PLUS SIGN (+)
25410var HYPHENMINUS$1 = 0x002D; // U+002D HYPHEN-MINUS (-)
25411var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
25412var U$1 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
25413
25414function eatHexSequence(offset, allowDash) {
25415 for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
25416 var code = this.scanner.source.charCodeAt(pos);
25417
25418 if (code === HYPHENMINUS$1 && allowDash && len !== 0) {
25419 if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
25420 this.error();
25421 }
25422
25423 return -1;
25424 }
25425
25426 if (!isHexDigit(code)) {
25427 this.error(
25428 allowDash && len !== 0
25429 ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
25430 : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
25431 pos
25432 );
25433 }
25434
25435 if (++len > 6) {
25436 this.error('Too many hex digits', pos);
25437 } }
25438
25439 this.scanner.next();
25440 return len;
25441}
25442
25443function eatQuestionMarkSequence(max) {
25444 var count = 0;
25445
25446 while (this.scanner.isDelim(QUESTIONMARK)) {
25447 if (++count > max) {
25448 this.error('Too many question marks');
25449 }
25450
25451 this.scanner.next();
25452 }
25453}
25454
25455function startsWith(code) {
25456 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
25457 this.error(NAME[code] + ' is expected');
25458 }
25459}
25460
25461// https://drafts.csswg.org/css-syntax/#urange
25462// Informally, the <urange> production has three forms:
25463// U+0001
25464// Defines a range consisting of a single code point, in this case the code point "1".
25465// U+0001-00ff
25466// Defines a range of codepoints between the first and the second value, in this case
25467// the range between "1" and "ff" (255 in decimal) inclusive.
25468// U+00??
25469// Defines a range of codepoints where the "?" characters range over all hex digits,
25470// in this case defining the same as the value U+0000-00ff.
25471// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
25472//
25473// <urange> =
25474// u '+' <ident-token> '?'* |
25475// u <dimension-token> '?'* |
25476// u <number-token> '?'* |
25477// u <number-token> <dimension-token> |
25478// u <number-token> <number-token> |
25479// u '+' '?'+
25480function scanUnicodeRange() {
25481 var hexLength = 0;
25482
25483 // u '+' <ident-token> '?'*
25484 // u '+' '?'+
25485 if (this.scanner.isDelim(PLUSSIGN$2)) {
25486 this.scanner.next();
25487
25488 if (this.scanner.tokenType === IDENT$4) {
25489 hexLength = eatHexSequence.call(this, 0, true);
25490 if (hexLength > 0) {
25491 eatQuestionMarkSequence.call(this, 6 - hexLength);
25492 }
25493 return;
25494 }
25495
25496 if (this.scanner.isDelim(QUESTIONMARK)) {
25497 this.scanner.next();
25498 eatQuestionMarkSequence.call(this, 5);
25499 return;
25500 }
25501
25502 this.error('Hex digit or question mark is expected');
25503 return;
25504 }
25505
25506 // u <number-token> '?'*
25507 // u <number-token> <dimension-token>
25508 // u <number-token> <number-token>
25509 if (this.scanner.tokenType === NUMBER$2) {
25510 startsWith.call(this, PLUSSIGN$2);
25511 hexLength = eatHexSequence.call(this, 1, true);
25512
25513 if (this.scanner.isDelim(QUESTIONMARK)) {
25514 eatQuestionMarkSequence.call(this, 6 - hexLength);
25515 return;
25516 }
25517
25518 if (this.scanner.tokenType === DIMENSION$2 ||
25519 this.scanner.tokenType === NUMBER$2) {
25520 startsWith.call(this, HYPHENMINUS$1);
25521 eatHexSequence.call(this, 1, false);
25522 return;
25523 }
25524
25525 return;
25526 }
25527
25528 // u <dimension-token> '?'*
25529 if (this.scanner.tokenType === DIMENSION$2) {
25530 startsWith.call(this, PLUSSIGN$2);
25531 hexLength = eatHexSequence.call(this, 1, true);
25532
25533 if (hexLength > 0) {
25534 eatQuestionMarkSequence.call(this, 6 - hexLength);
25535 }
25536
25537 return;
25538 }
25539
25540 this.error();
25541}
25542
25543var UnicodeRange = {
25544 name: 'UnicodeRange',
25545 structure: {
25546 value: String
25547 },
25548 parse: function() {
25549 var start = this.scanner.tokenStart;
25550
25551 // U or u
25552 if (!cmpChar$1(this.scanner.source, start, U$1)) {
25553 this.error('U is expected');
25554 }
25555
25556 if (!cmpChar$1(this.scanner.source, start + 1, PLUSSIGN$2)) {
25557 this.error('Plus sign is expected');
25558 }
25559
25560 this.scanner.next();
25561 scanUnicodeRange.call(this);
25562
25563 return {
25564 type: 'UnicodeRange',
25565 loc: this.getLocation(start, this.scanner.tokenStart),
25566 value: this.scanner.substrToCursor(start)
25567 };
25568 },
25569 generate: function(node) {
25570 this.chunk(node.value);
25571 }
25572};
25573
25574var isWhiteSpace = tokenizer$3.isWhiteSpace;
25575var cmpStr$1 = tokenizer$3.cmpStr;
25576var TYPE$5 = tokenizer$3.TYPE;
25577
25578var FUNCTION$3 = TYPE$5.Function;
25579var URL$3 = TYPE$5.Url;
25580var RIGHTPARENTHESIS = TYPE$5.RightParenthesis;
25581
25582// <url-token> | <function-token> <string> )
25583var Url = {
25584 name: 'Url',
25585 structure: {
25586 value: ['String', 'Raw']
25587 },
25588 parse: function() {
25589 var start = this.scanner.tokenStart;
25590 var value;
25591
25592 switch (this.scanner.tokenType) {
25593 case URL$3:
25594 var rawStart = start + 4;
25595 var rawEnd = this.scanner.tokenEnd - 1;
25596
25597 while (rawStart < rawEnd && isWhiteSpace(this.scanner.source.charCodeAt(rawStart))) {
25598 rawStart++;
25599 }
25600
25601 while (rawStart < rawEnd && isWhiteSpace(this.scanner.source.charCodeAt(rawEnd - 1))) {
25602 rawEnd--;
25603 }
25604
25605 value = {
25606 type: 'Raw',
25607 loc: this.getLocation(rawStart, rawEnd),
25608 value: this.scanner.source.substring(rawStart, rawEnd)
25609 };
25610
25611 this.eat(URL$3);
25612 break;
25613
25614 case FUNCTION$3:
25615 if (!cmpStr$1(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')) {
25616 this.error('Function name must be `url`');
25617 }
25618
25619 this.eat(FUNCTION$3);
25620 this.scanner.skipSC();
25621 value = this.String();
25622 this.scanner.skipSC();
25623 this.eat(RIGHTPARENTHESIS);
25624 break;
25625
25626 default:
25627 this.error('Url or Function is expected');
25628 }
25629
25630 return {
25631 type: 'Url',
25632 loc: this.getLocation(start, this.scanner.tokenStart),
25633 value: value
25634 };
25635 },
25636 generate: function(node) {
25637 this.chunk('url');
25638 this.chunk('(');
25639 this.node(node.value);
25640 this.chunk(')');
25641 }
25642};
25643
25644var Value = {
25645 name: 'Value',
25646 structure: {
25647 children: [[]]
25648 },
25649 parse: function() {
25650 var start = this.scanner.tokenStart;
25651 var children = this.readSequence(this.scope.Value);
25652
25653 return {
25654 type: 'Value',
25655 loc: this.getLocation(start, this.scanner.tokenStart),
25656 children: children
25657 };
25658 },
25659 generate: function(node) {
25660 this.children(node);
25661 }
25662};
25663
25664var WHITESPACE$2 = tokenizer$3.TYPE.WhiteSpace;
25665var SPACE = Object.freeze({
25666 type: 'WhiteSpace',
25667 loc: null,
25668 value: ' '
25669});
25670
25671var WhiteSpace = {
25672 name: 'WhiteSpace',
25673 structure: {
25674 value: String
25675 },
25676 parse: function() {
25677 this.eat(WHITESPACE$2);
25678 return SPACE;
25679
25680 // return {
25681 // type: 'WhiteSpace',
25682 // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
25683 // value: this.consume(WHITESPACE)
25684 // };
25685 },
25686 generate: function(node) {
25687 this.chunk(node.value);
25688 }
25689};
25690
25691var node = {
25692 AnPlusB: AnPlusB,
25693 Atrule: Atrule,
25694 AtrulePrelude: AtrulePrelude,
25695 AttributeSelector: AttributeSelector,
25696 Block: Block,
25697 Brackets: Brackets,
25698 CDC: CDC_1,
25699 CDO: CDO_1,
25700 ClassSelector: ClassSelector,
25701 Combinator: Combinator,
25702 Comment: Comment,
25703 Declaration: Declaration,
25704 DeclarationList: DeclarationList,
25705 Dimension: Dimension,
25706 Function: _Function,
25707 Hash: Hash,
25708 Identifier: Identifier,
25709 IdSelector: IdSelector,
25710 MediaFeature: MediaFeature,
25711 MediaQuery: MediaQuery,
25712 MediaQueryList: MediaQueryList,
25713 Nth: Nth,
25714 Number: _Number,
25715 Operator: Operator,
25716 Parentheses: Parentheses,
25717 Percentage: Percentage,
25718 PseudoClassSelector: PseudoClassSelector,
25719 PseudoElementSelector: PseudoElementSelector,
25720 Ratio: Ratio,
25721 Raw: Raw,
25722 Rule: Rule,
25723 Selector: Selector,
25724 SelectorList: SelectorList,
25725 String: _String,
25726 StyleSheet: StyleSheet,
25727 TypeSelector: TypeSelector,
25728 UnicodeRange: UnicodeRange,
25729 Url: Url,
25730 Value: Value,
25731 WhiteSpace: WhiteSpace
25732};
25733
25734var data = data$1;
25735
25736var lexer = {
25737 generic: true,
25738 types: data.types,
25739 atrules: data.atrules,
25740 properties: data.properties,
25741 node: node
25742};
25743
25744var cmpChar = tokenizer$3.cmpChar;
25745var cmpStr = tokenizer$3.cmpStr;
25746var TYPE$4 = tokenizer$3.TYPE;
25747
25748var IDENT$3 = TYPE$4.Ident;
25749var STRING$1 = TYPE$4.String;
25750var NUMBER$1 = TYPE$4.Number;
25751var FUNCTION$2 = TYPE$4.Function;
25752var URL$2 = TYPE$4.Url;
25753var HASH$1 = TYPE$4.Hash;
25754var DIMENSION$1 = TYPE$4.Dimension;
25755var PERCENTAGE$1 = TYPE$4.Percentage;
25756var LEFTPARENTHESIS$2 = TYPE$4.LeftParenthesis;
25757var LEFTSQUAREBRACKET$1 = TYPE$4.LeftSquareBracket;
25758var COMMA$1 = TYPE$4.Comma;
25759var DELIM$1 = TYPE$4.Delim;
25760var NUMBERSIGN$1 = 0x0023; // U+0023 NUMBER SIGN (#)
25761var ASTERISK$1 = 0x002A; // U+002A ASTERISK (*)
25762var PLUSSIGN$1 = 0x002B; // U+002B PLUS SIGN (+)
25763var HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
25764var SOLIDUS$1 = 0x002F; // U+002F SOLIDUS (/)
25765var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
25766
25767var _default = function defaultRecognizer(context) {
25768 switch (this.scanner.tokenType) {
25769 case HASH$1:
25770 return this.Hash();
25771
25772 case COMMA$1:
25773 context.space = null;
25774 context.ignoreWSAfter = true;
25775 return this.Operator();
25776
25777 case LEFTPARENTHESIS$2:
25778 return this.Parentheses(this.readSequence, context.recognizer);
25779
25780 case LEFTSQUAREBRACKET$1:
25781 return this.Brackets(this.readSequence, context.recognizer);
25782
25783 case STRING$1:
25784 return this.String();
25785
25786 case DIMENSION$1:
25787 return this.Dimension();
25788
25789 case PERCENTAGE$1:
25790 return this.Percentage();
25791
25792 case NUMBER$1:
25793 return this.Number();
25794
25795 case FUNCTION$2:
25796 return cmpStr(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
25797 ? this.Url()
25798 : this.Function(this.readSequence, context.recognizer);
25799
25800 case URL$2:
25801 return this.Url();
25802
25803 case IDENT$3:
25804 // check for unicode range, it should start with u+ or U+
25805 if (cmpChar(this.scanner.source, this.scanner.tokenStart, U) &&
25806 cmpChar(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$1)) {
25807 return this.UnicodeRange();
25808 } else {
25809 return this.Identifier();
25810 }
25811
25812 case DELIM$1:
25813 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
25814
25815 if (code === SOLIDUS$1 ||
25816 code === ASTERISK$1 ||
25817 code === PLUSSIGN$1 ||
25818 code === HYPHENMINUS) {
25819 return this.Operator(); // TODO: replace with Delim
25820 }
25821
25822 // TODO: produce a node with Delim node type
25823
25824 if (code === NUMBERSIGN$1) {
25825 this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
25826 }
25827
25828 break;
25829 }
25830};
25831
25832var atrulePrelude = {
25833 getNode: _default
25834};
25835
25836var TYPE$3 = tokenizer$3.TYPE;
25837
25838var DELIM = TYPE$3.Delim;
25839var IDENT$2 = TYPE$3.Ident;
25840var DIMENSION = TYPE$3.Dimension;
25841var PERCENTAGE = TYPE$3.Percentage;
25842var NUMBER = TYPE$3.Number;
25843var HASH = TYPE$3.Hash;
25844var COLON$1 = TYPE$3.Colon;
25845var LEFTSQUAREBRACKET = TYPE$3.LeftSquareBracket;
25846var NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
25847var ASTERISK = 0x002A; // U+002A ASTERISK (*)
25848var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
25849var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
25850var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
25851var GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
25852var VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
25853var TILDE = 0x007E; // U+007E TILDE (~)
25854
25855function getNode(context) {
25856 switch (this.scanner.tokenType) {
25857 case LEFTSQUAREBRACKET:
25858 return this.AttributeSelector();
25859
25860 case HASH:
25861 return this.IdSelector();
25862
25863 case COLON$1:
25864 if (this.scanner.lookupType(1) === COLON$1) {
25865 return this.PseudoElementSelector();
25866 } else {
25867 return this.PseudoClassSelector();
25868 }
25869
25870 case IDENT$2:
25871 return this.TypeSelector();
25872
25873 case NUMBER:
25874 case PERCENTAGE:
25875 return this.Percentage();
25876
25877 case DIMENSION:
25878 // throws when .123ident
25879 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP) {
25880 this.error('Identifier is expected', this.scanner.tokenStart + 1);
25881 }
25882 break;
25883
25884 case DELIM:
25885 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
25886
25887 switch (code) {
25888 case PLUSSIGN:
25889 case GREATERTHANSIGN:
25890 case TILDE:
25891 context.space = null;
25892 context.ignoreWSAfter = true;
25893 return this.Combinator();
25894
25895 case SOLIDUS: // /deep/
25896 return this.Combinator();
25897
25898 case FULLSTOP:
25899 return this.ClassSelector();
25900
25901 case ASTERISK:
25902 case VERTICALLINE:
25903 return this.TypeSelector();
25904
25905 case NUMBERSIGN:
25906 return this.IdSelector();
25907 }
25908
25909 break;
25910 }
25911}
25912var selector = {
25913 getNode: getNode
25914};
25915
25916// legacy IE function
25917// expression( <any-value> )
25918var expression = function() {
25919 return this.createSingleNodeList(
25920 this.Raw(this.scanner.tokenIndex, null, false)
25921 );
25922};
25923
25924var TYPE$2 = tokenizer$3.TYPE;
25925var rawMode = Raw.mode;
25926
25927var COMMA = TYPE$2.Comma;
25928var WHITESPACE$1 = TYPE$2.WhiteSpace;
25929
25930// var( <ident> , <value>? )
25931var _var = function() {
25932 var children = this.createList();
25933
25934 this.scanner.skipSC();
25935
25936 // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
25937 children.push(this.Identifier());
25938
25939 this.scanner.skipSC();
25940
25941 if (this.scanner.tokenType === COMMA) {
25942 children.push(this.Operator());
25943
25944 const startIndex = this.scanner.tokenIndex;
25945 const value = this.parseCustomProperty
25946 ? this.Value(null)
25947 : this.Raw(this.scanner.tokenIndex, rawMode.exclamationMarkOrSemicolon, false);
25948
25949 if (value.type === 'Value' && value.children.isEmpty()) {
25950 for (let offset = startIndex - this.scanner.tokenIndex; offset <= 0; offset++) {
25951 if (this.scanner.lookupType(offset) === WHITESPACE$1) {
25952 value.children.appendData({
25953 type: 'WhiteSpace',
25954 loc: null,
25955 value: ' '
25956 });
25957 break;
25958 }
25959 }
25960 }
25961
25962 children.push(value);
25963 }
25964
25965 return children;
25966};
25967
25968var value$2 = {
25969 getNode: _default,
25970 'expression': expression,
25971 'var': _var
25972};
25973
25974var scope = {
25975 AtrulePrelude: atrulePrelude,
25976 Selector: selector,
25977 Value: value$2
25978};
25979
25980var fontFace = {
25981 parse: {
25982 prelude: null,
25983 block: function() {
25984 return this.Block(true);
25985 }
25986 }
25987};
25988
25989var TYPE$1 = tokenizer$3.TYPE;
25990
25991var STRING = TYPE$1.String;
25992var IDENT$1 = TYPE$1.Ident;
25993var URL$1 = TYPE$1.Url;
25994var FUNCTION$1 = TYPE$1.Function;
25995var LEFTPARENTHESIS$1 = TYPE$1.LeftParenthesis;
25996
25997var _import = {
25998 parse: {
25999 prelude: function() {
26000 var children = this.createList();
26001
26002 this.scanner.skipSC();
26003
26004 switch (this.scanner.tokenType) {
26005 case STRING:
26006 children.push(this.String());
26007 break;
26008
26009 case URL$1:
26010 case FUNCTION$1:
26011 children.push(this.Url());
26012 break;
26013
26014 default:
26015 this.error('String or url() is expected');
26016 }
26017
26018 if (this.lookupNonWSType(0) === IDENT$1 ||
26019 this.lookupNonWSType(0) === LEFTPARENTHESIS$1) {
26020 children.push(this.WhiteSpace());
26021 children.push(this.MediaQueryList());
26022 }
26023
26024 return children;
26025 },
26026 block: null
26027 }
26028};
26029
26030var media = {
26031 parse: {
26032 prelude: function() {
26033 return this.createSingleNodeList(
26034 this.MediaQueryList()
26035 );
26036 },
26037 block: function() {
26038 return this.Block(false);
26039 }
26040 }
26041};
26042
26043var page = {
26044 parse: {
26045 prelude: function() {
26046 return this.createSingleNodeList(
26047 this.SelectorList()
26048 );
26049 },
26050 block: function() {
26051 return this.Block(true);
26052 }
26053 }
26054};
26055
26056var TYPE = tokenizer$3.TYPE;
26057
26058var WHITESPACE = TYPE.WhiteSpace;
26059var COMMENT = TYPE.Comment;
26060var IDENT = TYPE.Ident;
26061var FUNCTION = TYPE.Function;
26062var COLON = TYPE.Colon;
26063var LEFTPARENTHESIS = TYPE.LeftParenthesis;
26064
26065function consumeRaw() {
26066 return this.createSingleNodeList(
26067 this.Raw(this.scanner.tokenIndex, null, false)
26068 );
26069}
26070
26071function parentheses() {
26072 this.scanner.skipSC();
26073
26074 if (this.scanner.tokenType === IDENT &&
26075 this.lookupNonWSType(1) === COLON) {
26076 return this.createSingleNodeList(
26077 this.Declaration()
26078 );
26079 }
26080
26081 return readSequence.call(this);
26082}
26083
26084function readSequence() {
26085 var children = this.createList();
26086 var space = null;
26087 var child;
26088
26089 this.scanner.skipSC();
26090
26091 scan:
26092 while (!this.scanner.eof) {
26093 switch (this.scanner.tokenType) {
26094 case WHITESPACE:
26095 space = this.WhiteSpace();
26096 continue;
26097
26098 case COMMENT:
26099 this.scanner.next();
26100 continue;
26101
26102 case FUNCTION:
26103 child = this.Function(consumeRaw, this.scope.AtrulePrelude);
26104 break;
26105
26106 case IDENT:
26107 child = this.Identifier();
26108 break;
26109
26110 case LEFTPARENTHESIS:
26111 child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
26112 break;
26113
26114 default:
26115 break scan;
26116 }
26117
26118 if (space !== null) {
26119 children.push(space);
26120 space = null;
26121 }
26122
26123 children.push(child);
26124 }
26125
26126 return children;
26127}
26128
26129var supports = {
26130 parse: {
26131 prelude: function() {
26132 var children = readSequence.call(this);
26133
26134 if (this.getFirstListNode(children) === null) {
26135 this.error('Condition is expected');
26136 }
26137
26138 return children;
26139 },
26140 block: function() {
26141 return this.Block(false);
26142 }
26143 }
26144};
26145
26146var atrule = {
26147 'font-face': fontFace,
26148 'import': _import,
26149 'media': media,
26150 'page': page,
26151 'supports': supports
26152};
26153
26154var dir = {
26155 parse: function() {
26156 return this.createSingleNodeList(
26157 this.Identifier()
26158 );
26159 }
26160};
26161
26162var has = {
26163 parse: function() {
26164 return this.createSingleNodeList(
26165 this.SelectorList()
26166 );
26167 }
26168};
26169
26170var lang = {
26171 parse: function() {
26172 return this.createSingleNodeList(
26173 this.Identifier()
26174 );
26175 }
26176};
26177
26178var selectorList = {
26179 parse: function selectorList() {
26180 return this.createSingleNodeList(
26181 this.SelectorList()
26182 );
26183 }
26184};
26185
26186var matches = selectorList;
26187
26188var not = selectorList;
26189
26190var ALLOW_OF_CLAUSE = true;
26191
26192var nthWithOfClause = {
26193 parse: function nthWithOfClause() {
26194 return this.createSingleNodeList(
26195 this.Nth(ALLOW_OF_CLAUSE)
26196 );
26197 }
26198};
26199
26200var nthChild = nthWithOfClause;
26201
26202var nthLastChild = nthWithOfClause;
26203
26204var DISALLOW_OF_CLAUSE = false;
26205
26206var nth = {
26207 parse: function nth() {
26208 return this.createSingleNodeList(
26209 this.Nth(DISALLOW_OF_CLAUSE)
26210 );
26211 }
26212};
26213
26214var nthLastOfType = nth;
26215
26216var nthOfType = nth;
26217
26218var slotted = {
26219 parse: function compoundSelector() {
26220 return this.createSingleNodeList(
26221 this.Selector()
26222 );
26223 }
26224};
26225
26226var pseudo = {
26227 'dir': dir,
26228 'has': has,
26229 'lang': lang,
26230 'matches': matches,
26231 'not': not,
26232 'nth-child': nthChild,
26233 'nth-last-child': nthLastChild,
26234 'nth-last-of-type': nthLastOfType,
26235 'nth-of-type': nthOfType,
26236 'slotted': slotted
26237};
26238
26239var parser = {
26240 parseContext: {
26241 default: 'StyleSheet',
26242 stylesheet: 'StyleSheet',
26243 atrule: 'Atrule',
26244 atrulePrelude: function(options) {
26245 return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
26246 },
26247 mediaQueryList: 'MediaQueryList',
26248 mediaQuery: 'MediaQuery',
26249 rule: 'Rule',
26250 selectorList: 'SelectorList',
26251 selector: 'Selector',
26252 block: function() {
26253 return this.Block(true);
26254 },
26255 declarationList: 'DeclarationList',
26256 declaration: 'Declaration',
26257 value: 'Value'
26258 },
26259 scope: scope,
26260 atrule: atrule,
26261 pseudo: pseudo,
26262 node: node
26263};
26264
26265var walker = {
26266 node: node
26267};
26268
26269var _args = [
26270 [
26271 "css-tree@1.1.3",
26272 "/home/gitlab-runner/builds/BQJy2NwB/0/pagedjs/pagedjs"
26273 ]
26274];
26275var _from = "css-tree@1.1.3";
26276var _id = "css-tree@1.1.3";
26277var _inBundle = false;
26278var _integrity = "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==";
26279var _location = "/css-tree";
26280var _phantomChildren = {
26281};
26282var _requested = {
26283 type: "version",
26284 registry: true,
26285 raw: "css-tree@1.1.3",
26286 name: "css-tree",
26287 escapedName: "css-tree",
26288 rawSpec: "1.1.3",
26289 saveSpec: null,
26290 fetchSpec: "1.1.3"
26291};
26292var _requiredBy = [
26293 "/"
26294];
26295var _resolved = "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz";
26296var _spec = "1.1.3";
26297var _where = "/home/gitlab-runner/builds/BQJy2NwB/0/pagedjs/pagedjs";
26298var author = {
26299 name: "Roman Dvornov",
26300 email: "rdvornov@gmail.com",
26301 url: "https://github.com/lahmatiy"
26302};
26303var bugs = {
26304 url: "https://github.com/csstree/csstree/issues"
26305};
26306var dependencies = {
26307 "mdn-data": "2.0.14",
26308 "source-map": "^0.6.1"
26309};
26310var description = "A tool set for CSS: fast detailed parser (CSS → AST), walker (AST traversal), generator (AST → CSS) and lexer (validation and matching) based on specs and browser implementations";
26311var devDependencies = {
26312 "@rollup/plugin-commonjs": "^11.0.2",
26313 "@rollup/plugin-json": "^4.0.2",
26314 "@rollup/plugin-node-resolve": "^7.1.1",
26315 coveralls: "^3.0.9",
26316 eslint: "^6.8.0",
26317 "json-to-ast": "^2.1.0",
26318 mocha: "^6.2.3",
26319 nyc: "^14.1.1",
26320 rollup: "^1.32.1",
26321 "rollup-plugin-terser": "^5.3.0"
26322};
26323var engines = {
26324 node: ">=8.0.0"
26325};
26326var files = [
26327 "data",
26328 "dist",
26329 "lib"
26330];
26331var homepage = "https://github.com/csstree/csstree#readme";
26332var jsdelivr = "dist/csstree.min.js";
26333var keywords = [
26334 "css",
26335 "ast",
26336 "tokenizer",
26337 "parser",
26338 "walker",
26339 "lexer",
26340 "generator",
26341 "utils",
26342 "syntax",
26343 "validation"
26344];
26345var license = "MIT";
26346var main = "lib/index.js";
26347var name = "css-tree";
26348var repository = {
26349 type: "git",
26350 url: "git+https://github.com/csstree/csstree.git"
26351};
26352var scripts = {
26353 build: "rollup --config",
26354 coverage: "nyc npm test",
26355 coveralls: "nyc report --reporter=text-lcov | coveralls",
26356 hydrogen: "node --trace-hydrogen --trace-phase=Z --trace-deopt --code-comments --hydrogen-track-positions --redirect-code-traces --redirect-code-traces-to=code.asm --trace_hydrogen_file=code.cfg --print-opt-code bin/parse --stat -o /dev/null",
26357 lint: "eslint data lib scripts test && node scripts/review-syntax-patch --lint && node scripts/update-docs --lint",
26358 "lint-and-test": "npm run lint && npm test",
26359 prepublishOnly: "npm run build",
26360 "review:syntax-patch": "node scripts/review-syntax-patch",
26361 test: "mocha --reporter progress",
26362 travis: "nyc npm run lint-and-test && npm run coveralls",
26363 "update:docs": "node scripts/update-docs"
26364};
26365var unpkg = "dist/csstree.min.js";
26366var version = "1.1.3";
26367var require$$4 = {
26368 _args: _args,
26369 _from: _from,
26370 _id: _id,
26371 _inBundle: _inBundle,
26372 _integrity: _integrity,
26373 _location: _location,
26374 _phantomChildren: _phantomChildren,
26375 _requested: _requested,
26376 _requiredBy: _requiredBy,
26377 _resolved: _resolved,
26378 _spec: _spec,
26379 _where: _where,
26380 author: author,
26381 bugs: bugs,
26382 dependencies: dependencies,
26383 description: description,
26384 devDependencies: devDependencies,
26385 engines: engines,
26386 files: files,
26387 homepage: homepage,
26388 jsdelivr: jsdelivr,
26389 keywords: keywords,
26390 license: license,
26391 main: main,
26392 name: name,
26393 repository: repository,
26394 scripts: scripts,
26395 unpkg: unpkg,
26396 version: version
26397};
26398
26399function merge() {
26400 var dest = {};
26401
26402 for (var i = 0; i < arguments.length; i++) {
26403 var src = arguments[i];
26404 for (var key in src) {
26405 dest[key] = src[key];
26406 }
26407 }
26408
26409 return dest;
26410}
26411
26412syntax.exports = create$4.create(
26413 merge(
26414 lexer,
26415 parser,
26416 walker
26417 )
26418);
26419syntax.exports.version = require$$4.version;
26420
26421var syntaxExports = syntax.exports;
26422
26423var lib = syntaxExports;
26424
26425var csstree = /*@__PURE__*/getDefaultExportFromCjs(lib);
26426
26427class Sheet {
26428 constructor(url, hooks) {
26429
26430 if (hooks) {
26431 this.hooks = hooks;
26432 } else {
26433 this.hooks = {};
26434 this.hooks.onUrl = new Hook(this);
26435 this.hooks.onAtPage = new Hook(this);
26436 this.hooks.onAtMedia = new Hook(this);
26437 this.hooks.onRule = new Hook(this);
26438 this.hooks.onDeclaration = new Hook(this);
26439 this.hooks.onSelector = new Hook(this);
26440 this.hooks.onPseudoSelector = new Hook(this);
26441
26442 this.hooks.onContent = new Hook(this);
26443 this.hooks.onImport = new Hook(this);
26444
26445 this.hooks.beforeTreeParse = new Hook(this);
26446 this.hooks.beforeTreeWalk = new Hook(this);
26447 this.hooks.afterTreeWalk = new Hook(this);
26448 }
26449
26450 try {
26451 this.url = new URL(url, window.location.href);
26452 } catch (e) {
26453 this.url = new URL(window.location.href);
26454 }
26455 }
26456
26457
26458
26459 // parse
26460 async parse(text) {
26461 this.text = text;
26462
26463 await this.hooks.beforeTreeParse.trigger(this.text, this);
26464
26465 // send to csstree
26466 this.ast = csstree.parse(this._text);
26467
26468 await this.hooks.beforeTreeWalk.trigger(this.ast);
26469
26470 // Replace urls
26471 this.replaceUrls(this.ast);
26472
26473 // Scope
26474 this.id = UUID();
26475 // this.addScope(this.ast, this.uuid);
26476
26477 // Replace IDs with data-id
26478 this.replaceIds(this.ast);
26479
26480 this.imported = [];
26481
26482 // Trigger Hooks
26483 this.urls(this.ast);
26484 this.rules(this.ast);
26485 this.atrules(this.ast);
26486
26487 await this.hooks.afterTreeWalk.trigger(this.ast, this);
26488
26489 // return ast
26490 return this.ast;
26491 }
26492
26493
26494
26495 insertRule(rule) {
26496 let inserted = this.ast.children.appendData(rule);
26497
26498 this.declarations(rule);
26499
26500 return inserted;
26501 }
26502
26503 urls(ast) {
26504 csstree.walk(ast, {
26505 visit: "Url",
26506 enter: (node, item, list) => {
26507 this.hooks.onUrl.trigger(node, item, list);
26508 }
26509 });
26510 }
26511
26512 atrules(ast) {
26513 csstree.walk(ast, {
26514 visit: "Atrule",
26515 enter: (node, item, list) => {
26516 const basename = csstree.keyword(node.name).basename;
26517
26518 if (basename === "page") {
26519 this.hooks.onAtPage.trigger(node, item, list);
26520 this.declarations(node, item, list);
26521 }
26522
26523 if (basename === "media") {
26524 this.hooks.onAtMedia.trigger(node, item, list);
26525 this.declarations(node, item, list);
26526 }
26527
26528 if (basename === "import") {
26529 this.hooks.onImport.trigger(node, item, list);
26530 this.imports(node, item, list);
26531 }
26532 }
26533 });
26534 }
26535
26536
26537 rules(ast) {
26538 csstree.walk(ast, {
26539 visit: "Rule",
26540 enter: (ruleNode, ruleItem, rulelist) => {
26541
26542 this.hooks.onRule.trigger(ruleNode, ruleItem, rulelist);
26543 this.declarations(ruleNode, ruleItem, rulelist);
26544 this.onSelector(ruleNode, ruleItem, rulelist);
26545
26546 }
26547 });
26548 }
26549
26550 declarations(ruleNode, ruleItem, rulelist) {
26551 csstree.walk(ruleNode, {
26552 visit: "Declaration",
26553 enter: (declarationNode, dItem, dList) => {
26554
26555 this.hooks.onDeclaration.trigger(declarationNode, dItem, dList, {ruleNode, ruleItem, rulelist});
26556
26557 if (declarationNode.property === "content") {
26558 csstree.walk(declarationNode, {
26559 visit: "Function",
26560 enter: (funcNode, fItem, fList) => {
26561 this.hooks.onContent.trigger(funcNode, fItem, fList, {declarationNode, dItem, dList}, {ruleNode, ruleItem, rulelist});
26562 }
26563 });
26564 }
26565
26566 }
26567 });
26568 }
26569
26570 // add pseudo elements to parser
26571 onSelector(ruleNode, ruleItem, rulelist) {
26572 csstree.walk(ruleNode, {
26573 visit: "Selector",
26574 enter: (selectNode, selectItem, selectList) => {
26575 this.hooks.onSelector.trigger(selectNode, selectItem, selectList, {ruleNode, ruleItem, rulelist});
26576
26577 if (selectNode.children.forEach(node => {if (node.type === "PseudoElementSelector") {
26578 csstree.walk(node, {
26579 visit: "PseudoElementSelector",
26580 enter: (pseudoNode, pItem, pList) => {
26581 this.hooks.onPseudoSelector.trigger(pseudoNode, pItem, pList, {selectNode, selectItem, selectList}, {ruleNode, ruleItem, rulelist});
26582 }
26583 });
26584 }}));
26585 }
26586 });
26587 }
26588
26589 replaceUrls(ast) {
26590 csstree.walk(ast, {
26591 visit: "Url",
26592 enter: (node, item, list) => {
26593 let content = node.value.value;
26594 if ((node.value.type === "Raw" && content.startsWith("data:")) || (node.value.type === "String" && (content.startsWith("\"data:") || content.startsWith("'data:")))) ; else {
26595 let href = content.replace(/["']/g, "");
26596 let url = new URL(href, this.url);
26597 node.value.value = url.toString();
26598 }
26599 }
26600 });
26601 }
26602
26603 addScope(ast, id) {
26604 // Get all selector lists
26605 // add an id
26606 csstree.walk(ast, {
26607 visit: "Selector",
26608 enter: (node, item, list) => {
26609 let children = node.children;
26610 children.prepend(children.createItem({
26611 type: "WhiteSpace",
26612 value: " "
26613 }));
26614 children.prepend(children.createItem({
26615 type: "IdSelector",
26616 name: id,
26617 loc: null,
26618 children: null
26619 }));
26620 }
26621 });
26622 }
26623
26624 getNamedPageSelectors(ast) {
26625 let namedPageSelectors = {};
26626 csstree.walk(ast, {
26627 visit: "Rule",
26628 enter: (node, item, list) => {
26629 csstree.walk(node, {
26630 visit: "Declaration",
26631 enter: (declaration, dItem, dList) => {
26632 if (declaration.property === "page") {
26633 let value = declaration.value.children.first();
26634 let name = value.name;
26635 let selector = csstree.generate(node.prelude);
26636 namedPageSelectors[name] = {
26637 name: name,
26638 selector: selector
26639 };
26640
26641 // dList.remove(dItem);
26642
26643 // Add in page break
26644 declaration.property = "break-before";
26645 value.type = "Identifier";
26646 value.name = "always";
26647
26648 }
26649 }
26650 });
26651 }
26652 });
26653 return namedPageSelectors;
26654 }
26655
26656 replaceIds(ast) {
26657 csstree.walk(ast, {
26658 visit: "Rule",
26659 enter: (node, item, list) => {
26660
26661 csstree.walk(node, {
26662 visit: "IdSelector",
26663 enter: (idNode, idItem, idList) => {
26664 let name = idNode.name;
26665 idNode.flags = null;
26666 idNode.matcher = "=";
26667 idNode.name = {type: "Identifier", loc: null, name: "data-id"};
26668 idNode.type = "AttributeSelector";
26669 idNode.value = {type: "String", loc: null, value: `"${name}"`};
26670 }
26671 });
26672 }
26673 });
26674 }
26675
26676 imports(node, item, list) {
26677 // console.log("import", node, item, list);
26678 let queries = [];
26679 csstree.walk(node, {
26680 visit: "MediaQuery",
26681 enter: (mqNode, mqItem, mqList) => {
26682 csstree.walk(mqNode, {
26683 visit: "Identifier",
26684 enter: (identNode, identItem, identList) => {
26685 queries.push(identNode.name);
26686 }
26687 });
26688 }
26689 });
26690
26691 // Just basic media query support for now
26692 let shouldNotApply = queries.some((query, index) => {
26693 let q = query;
26694 if (q === "not") {
26695 q = queries[index + 1];
26696 return !(q === "screen" || q === "speech");
26697 } else {
26698 return (q === "screen" || q === "speech");
26699 }
26700 });
26701
26702 if (shouldNotApply) {
26703 return;
26704 }
26705
26706 csstree.walk(node, {
26707 visit: "String",
26708 enter: (urlNode, urlItem, urlList) => {
26709 let href = urlNode.value.replace(/["']/g, "");
26710 let url = new URL(href, this.url);
26711 let value = url.toString();
26712
26713 this.imported.push(value);
26714
26715 // Remove the original
26716 list.remove(item);
26717 }
26718 });
26719 }
26720
26721 set text(t) {
26722 this._text = t;
26723 }
26724
26725 get text() {
26726 return this._text;
26727 }
26728
26729 // generate string
26730 toString(ast) {
26731 return csstree.generate(ast || this.ast);
26732 }
26733}
26734
26735var baseStyles = `
26736:root {
26737 --pagedjs-width: 8.5in;
26738 --pagedjs-height: 11in;
26739 --pagedjs-width-right: 8.5in;
26740 --pagedjs-height-right: 11in;
26741 --pagedjs-width-left: 8.5in;
26742 --pagedjs-height-left: 11in;
26743 --pagedjs-pagebox-width: 8.5in;
26744 --pagedjs-pagebox-height: 11in;
26745 --pagedjs-footnotes-height: 0mm;
26746 --pagedjs-margin-top: 1in;
26747 --pagedjs-margin-right: 1in;
26748 --pagedjs-margin-bottom: 1in;
26749 --pagedjs-margin-left: 1in;
26750 --pagedjs-padding-top: 0mm;
26751 --pagedjs-padding-right: 0mm;
26752 --pagedjs-padding-bottom: 0mm;
26753 --pagedjs-padding-left: 0mm;
26754 --pagedjs-border-top: 0mm;
26755 --pagedjs-border-right: 0mm;
26756 --pagedjs-border-bottom: 0mm;
26757 --pagedjs-border-left: 0mm;
26758 --pagedjs-bleed-top: 0mm;
26759 --pagedjs-bleed-right: 0mm;
26760 --pagedjs-bleed-bottom: 0mm;
26761 --pagedjs-bleed-left: 0mm;
26762 --pagedjs-bleed-right-top: 0mm;
26763 --pagedjs-bleed-right-right: 0mm;
26764 --pagedjs-bleed-right-bottom: 0mm;
26765 --pagedjs-bleed-right-left: 0mm;
26766 --pagedjs-bleed-left-top: 0mm;
26767 --pagedjs-bleed-left-right: 0mm;
26768 --pagedjs-bleed-left-bottom: 0mm;
26769 --pagedjs-bleed-left-left: 0mm;
26770 --pagedjs-crop-color: black;
26771 --pagedjs-crop-shadow: white;
26772 --pagedjs-crop-offset: 2mm;
26773 --pagedjs-crop-stroke: 1px;
26774 --pagedjs-cross-size: 5mm;
26775 --pagedjs-mark-cross-display: none;
26776 --pagedjs-mark-crop-display: none;
26777 --pagedjs-page-count: 0;
26778 --pagedjs-page-counter-increment: 1;
26779 --pagedjs-footnotes-count: 0;
26780 --pagedjs-column-gap-offset: 1000px;
26781}
26782
26783@page {
26784 size: letter;
26785 margin: 0;
26786}
26787
26788.pagedjs_sheet {
26789 box-sizing: border-box;
26790 width: var(--pagedjs-width);
26791 height: var(--pagedjs-height);
26792 overflow: hidden;
26793 position: relative;
26794 display: grid;
26795 grid-template-columns: [bleed-left] var(--pagedjs-bleed-left) [sheet-center] calc(var(--pagedjs-width) - var(--pagedjs-bleed-left) - var(--pagedjs-bleed-right)) [bleed-right] var(--pagedjs-bleed-right);
26796 grid-template-rows: [bleed-top] var(--pagedjs-bleed-top) [sheet-middle] calc(var(--pagedjs-height) - var(--pagedjs-bleed-top) - var(--pagedjs-bleed-bottom)) [bleed-bottom] var(--pagedjs-bleed-bottom);
26797}
26798
26799.pagedjs_right_page .pagedjs_sheet {
26800 width: var(--pagedjs-width-right);
26801 height: var(--pagedjs-height-right);
26802 grid-template-columns: [bleed-left] var(--pagedjs-bleed-right-left) [sheet-center] calc(var(--pagedjs-width) - var(--pagedjs-bleed-right-left) - var(--pagedjs-bleed-right-right)) [bleed-right] var(--pagedjs-bleed-right-right);
26803 grid-template-rows: [bleed-top] var(--pagedjs-bleed-right-top) [sheet-middle] calc(var(--pagedjs-height) - var(--pagedjs-bleed-right-top) - var(--pagedjs-bleed-right-bottom)) [bleed-bottom] var(--pagedjs-bleed-right-bottom);
26804}
26805
26806.pagedjs_left_page .pagedjs_sheet {
26807 width: var(--pagedjs-width-left);
26808 height: var(--pagedjs-height-left);
26809 grid-template-columns: [bleed-left] var(--pagedjs-bleed-left-left) [sheet-center] calc(var(--pagedjs-width) - var(--pagedjs-bleed-left-left) - var(--pagedjs-bleed-left-right)) [bleed-right] var(--pagedjs-bleed-left-right);
26810 grid-template-rows: [bleed-top] var(--pagedjs-bleed-left-top) [sheet-middle] calc(var(--pagedjs-height) - var(--pagedjs-bleed-left-top) - var(--pagedjs-bleed-left-bottom)) [bleed-bottom] var(--pagedjs-bleed-left-bottom);
26811}
26812
26813.pagedjs_bleed {
26814 display: flex;
26815 align-items: center;
26816 justify-content: center;
26817 flex-wrap: nowrap;
26818 overflow: hidden;
26819}
26820
26821.pagedjs_bleed-top {
26822 grid-column: bleed-left / -1;
26823 grid-row: bleed-top;
26824 flex-direction: row;
26825}
26826
26827.pagedjs_bleed-bottom {
26828 grid-column: bleed-left / -1;
26829 grid-row: bleed-bottom;
26830 flex-direction: row;
26831}
26832
26833.pagedjs_bleed-left {
26834 grid-column: bleed-left;
26835 grid-row: bleed-top / -1;
26836 flex-direction: column;
26837}
26838
26839.pagedjs_bleed-right {
26840 grid-column: bleed-right;
26841 grid-row: bleed-top / -1;
26842 flex-direction: column;
26843}
26844
26845.pagedjs_marks-crop {
26846 display: var(--pagedjs-mark-crop-display);
26847 flex-grow: 0;
26848 flex-shrink: 0;
26849 z-index: 9999999999;
26850}
26851
26852.pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
26853.pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
26854 width: calc(var(--pagedjs-bleed-left) - var(--pagedjs-crop-stroke));
26855 border-right: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26856 box-shadow: 1px 0px 0px 0px var(--pagedjs-crop-shadow);
26857}
26858
26859.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
26860.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
26861 width: calc(var(--pagedjs-bleed-right-left) - var(--pagedjs-crop-stroke));
26862}
26863
26864.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
26865.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1) {
26866 width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-stroke));
26867}
26868
26869.pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
26870.pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
26871 width: calc(var(--pagedjs-bleed-right) - var(--pagedjs-crop-stroke));
26872 border-left: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26873 box-shadow: -1px 0px 0px 0px var(--pagedjs-crop-shadow);
26874}
26875
26876.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
26877.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
26878 width: calc(var(--pagedjs-bleed-right-right) - var(--pagedjs-crop-stroke));
26879}
26880
26881.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(3),
26882.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(3) {
26883 width: calc(var(--pagedjs-bleed-left-right) - var(--pagedjs-crop-stroke));
26884}
26885
26886.pagedjs_bleed-top .pagedjs_marks-crop {
26887 align-self: flex-start;
26888 height: calc(var(--pagedjs-bleed-top) - var(--pagedjs-crop-offset));
26889}
26890
26891.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop {
26892 height: calc(var(--pagedjs-bleed-right-top) - var(--pagedjs-crop-offset));
26893}
26894
26895.pagedjs_left_page .pagedjs_bleed-top .pagedjs_marks-crop {
26896 height: calc(var(--pagedjs-bleed-left-top) - var(--pagedjs-crop-offset));
26897}
26898
26899.pagedjs_bleed-bottom .pagedjs_marks-crop {
26900 align-self: flex-end;
26901 height: calc(var(--pagedjs-bleed-bottom) - var(--pagedjs-crop-offset));
26902}
26903
26904.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop {
26905 height: calc(var(--pagedjs-bleed-right-bottom) - var(--pagedjs-crop-offset));
26906}
26907
26908.pagedjs_left_page .pagedjs_bleed-bottom .pagedjs_marks-crop {
26909 height: calc(var(--pagedjs-bleed-left-bottom) - var(--pagedjs-crop-offset));
26910}
26911
26912.pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
26913.pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
26914 height: calc(var(--pagedjs-bleed-top) - var(--pagedjs-crop-stroke));
26915 border-bottom: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26916 box-shadow: 0px 1px 0px 0px var(--pagedjs-crop-shadow);
26917}
26918
26919.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
26920.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
26921 height: calc(var(--pagedjs-bleed-right-top) - var(--pagedjs-crop-stroke));
26922}
26923
26924.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),
26925.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(1) {
26926 height: calc(var(--pagedjs-bleed-left-top) - var(--pagedjs-crop-stroke));
26927}
26928
26929.pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
26930.pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
26931 height: calc(var(--pagedjs-bleed-bottom) - var(--pagedjs-crop-stroke));
26932 border-top: var(--pagedjs-crop-stroke) solid var(--pagedjs-crop-color);
26933 box-shadow: 0px -1px 0px 0px var(--pagedjs-crop-shadow);
26934}
26935
26936.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
26937.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
26938 height: calc(var(--pagedjs-bleed-right-bottom) - var(--pagedjs-crop-stroke));
26939}
26940
26941.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3),
26942.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop:nth-child(3) {
26943 height: calc(var(--pagedjs-bleed-left-bottom) - var(--pagedjs-crop-stroke));
26944}
26945
26946.pagedjs_bleed-left .pagedjs_marks-crop {
26947 width: calc(var(--pagedjs-bleed-left) - var(--pagedjs-crop-offset));
26948 align-self: flex-start;
26949}
26950
26951.pagedjs_right_page .pagedjs_bleed-left .pagedjs_marks-crop {
26952 width: calc(var(--pagedjs-bleed-right-left) - var(--pagedjs-crop-offset));
26953}
26954
26955.pagedjs_left_page .pagedjs_bleed-left .pagedjs_marks-crop {
26956 width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-offset));
26957}
26958
26959.pagedjs_bleed-right .pagedjs_marks-crop {
26960 width: calc(var(--pagedjs-bleed-right) - var(--pagedjs-crop-offset));
26961 align-self: flex-end;
26962}
26963
26964.pagedjs_right_page .pagedjs_bleed-right .pagedjs_marks-crop {
26965 width: calc(var(--pagedjs-bleed-right-right) - var(--pagedjs-crop-offset));
26966}
26967
26968.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop {
26969 width: calc(var(--pagedjs-bleed-left-right) - var(--pagedjs-crop-offset));
26970}
26971
26972.pagedjs_marks-middle {
26973 display: flex;
26974 flex-grow: 1;
26975 flex-shrink: 0;
26976 align-items: center;
26977 justify-content: center;
26978}
26979
26980.pagedjs_marks-cross {
26981 display: var(--pagedjs-mark-cross-display);
26982 background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIzMi41MzdweCIgaGVpZ2h0PSIzMi41MzdweCIgdmlld0JveD0iMC4xMDQgMC4xMDQgMzIuNTM3IDMyLjUzNyIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwLjEwNCAwLjEwNCAzMi41MzcgMzIuNTM3IiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMy4zODkzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik0yOS45MzEsMTYuMzczYzAsNy40ODktNi4wNjgsMTMuNTYtMTMuNTU4LDEzLjU2Yy03LjQ4MywwLTEzLjU1Ny02LjA3Mi0xMy41NTctMTMuNTZjMC03LjQ4Niw2LjA3NC0xMy41NTQsMTMuNTU3LTEzLjU1NEMyMy44NjIsMi44MTksMjkuOTMxLDguODg3LDI5LjkzMSwxNi4zNzN6Ii8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjMuMzg5MyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMC4xMDQiIHkxPSIxNi4zNzMiIHgyPSIzMi42NDIiIHkyPSIxNi4zNzMiLz48bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMy4zODkzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHgxPSIxNi4zNzMiIHkxPSIwLjEwNCIgeDI9IjE2LjM3MyIgeTI9IjMyLjY0MiIvPjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIzLjM4OTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgZD0iTTI0LjUwOCwxNi4zNzNjMCw0LjQ5Ni0zLjYzOCw4LjEzNS04LjEzNSw4LjEzNWMtNC40OTEsMC04LjEzNS0zLjYzOC04LjEzNS04LjEzNWMwLTQuNDg5LDMuNjQ0LTguMTM1LDguMTM1LTguMTM1QzIwLjg2OSw4LjIzOSwyNC41MDgsMTEuODg0LDI0LjUwOCwxNi4zNzN6Ii8+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNMjkuOTMxLDE2LjM3M2MwLDcuNDg5LTYuMDY4LDEzLjU2LTEzLjU1OCwxMy41NmMtNy40ODMsMC0xMy41NTctNi4wNzItMTMuNTU3LTEzLjU2YzAtNy40ODYsNi4wNzQtMTMuNTU0LDEzLjU1Ny0xMy41NTRDMjMuODYyLDIuODE5LDI5LjkzMSw4Ljg4NywyOS45MzEsMTYuMzczeiIvPjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSIwLjY3NzgiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjAuMTA0IiB5MT0iMTYuMzczIiB4Mj0iMzIuNjQyIiB5Mj0iMTYuMzczIi8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMTYuMzczIiB5MT0iMC4xMDQiIHgyPSIxNi4zNzMiIHkyPSIzMi42NDIiLz48cGF0aCBkPSJNMjQuNTA4LDE2LjM3M2MwLDQuNDk2LTMuNjM4LDguMTM1LTguMTM1LDguMTM1Yy00LjQ5MSwwLTguMTM1LTMuNjM4LTguMTM1LTguMTM1YzAtNC40ODksMy42NDQtOC4xMzUsOC4xMzUtOC4xMzVDMjAuODY5LDguMjM5LDI0LjUwOCwxMS44ODQsMjQuNTA4LDE2LjM3MyIvPjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIwLjY3NzgiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgeDE9IjguMjM5IiB5MT0iMTYuMzczIiB4Mj0iMjQuNTA4IiB5Mj0iMTYuMzczIi8+PGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjAuNjc3OCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iMTYuMzczIiB5MT0iOC4yMzkiIHgyPSIxNi4zNzMiIHkyPSIyNC41MDgiLz48L3N2Zz4=);
26983 background-repeat: no-repeat;
26984 background-position: 50% 50%;
26985 background-size: var(--pagedjs-cross-size);
26986
26987 z-index: 2147483647;
26988 width: var(--pagedjs-cross-size);
26989 height: var(--pagedjs-cross-size);
26990}
26991
26992.pagedjs_pagebox {
26993 box-sizing: border-box;
26994 width: var(--pagedjs-pagebox-width);
26995 height: var(--pagedjs-pagebox-height);
26996 position: relative;
26997 display: grid;
26998 grid-template-columns: [left] var(--pagedjs-margin-left) [center] calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right)) [right] var(--pagedjs-margin-right);
26999 grid-template-rows: [header] var(--pagedjs-margin-top) [page] calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom)) [footer] var(--pagedjs-margin-bottom);
27000 grid-column: sheet-center;
27001 grid-row: sheet-middle;
27002}
27003
27004.pagedjs_pagebox * {
27005 box-sizing: border-box;
27006}
27007
27008.pagedjs_margin-top {
27009 width: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right));
27010 height: var(--pagedjs-margin-top);
27011 grid-column: center;
27012 grid-row: header;
27013 flex-wrap: nowrap;
27014 display: grid;
27015 grid-template-columns: repeat(3, 1fr);
27016 grid-template-rows: 100%;
27017}
27018
27019.pagedjs_margin-top-left-corner-holder {
27020 width: var(--pagedjs-margin-left);
27021 height: var(--pagedjs-margin-top);
27022 display: flex;
27023 grid-column: left;
27024 grid-row: header;
27025}
27026
27027.pagedjs_margin-top-right-corner-holder {
27028 width: var(--pagedjs-margin-right);
27029 height: var(--pagedjs-margin-top);
27030 display: flex;
27031 grid-column: right;
27032 grid-row: header;
27033}
27034
27035.pagedjs_margin-top-left-corner {
27036 width: var(--pagedjs-margin-left);
27037}
27038
27039.pagedjs_margin-top-right-corner {
27040 width: var(--pagedjs-margin-right);
27041}
27042
27043.pagedjs_margin-right {
27044 height: calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom));
27045 width: var(--pagedjs-margin-right);
27046 right: 0;
27047 grid-column: right;
27048 grid-row: page;
27049 display: grid;
27050 grid-template-rows: repeat(3, 33.3333%);
27051 grid-template-columns: 100%;
27052}
27053
27054.pagedjs_margin-bottom {
27055 width: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right));
27056 height: var(--pagedjs-margin-bottom);
27057 grid-column: center;
27058 grid-row: footer;
27059 display: grid;
27060 grid-template-columns: repeat(3, 1fr);
27061 grid-template-rows: 100%;
27062}
27063
27064.pagedjs_margin-bottom-left-corner-holder {
27065 width: var(--pagedjs-margin-left);
27066 height: var(--pagedjs-margin-bottom);
27067 display: flex;
27068 grid-column: left;
27069 grid-row: footer;
27070}
27071
27072.pagedjs_margin-bottom-right-corner-holder {
27073 width: var(--pagedjs-margin-right);
27074 height: var(--pagedjs-margin-bottom);
27075 display: flex;
27076 grid-column: right;
27077 grid-row: footer;
27078}
27079
27080.pagedjs_margin-bottom-left-corner {
27081 width: var(--pagedjs-margin-left);
27082}
27083
27084.pagedjs_margin-bottom-right-corner {
27085 width: var(--pagedjs-margin-right);
27086}
27087
27088
27089
27090.pagedjs_margin-left {
27091 height: calc(var(--pagedjs-pagebox-height) - var(--pagedjs-margin-top) - var(--pagedjs-margin-bottom));
27092 width: var(--pagedjs-margin-left);
27093 grid-column: left;
27094 grid-row: page;
27095 display: grid;
27096 grid-template-rows: repeat(3, 33.33333%);
27097 grid-template-columns: 100%;
27098}
27099
27100.pagedjs_pages .pagedjs_pagebox .pagedjs_margin:not(.hasContent) {
27101 visibility: hidden;
27102}
27103
27104.pagedjs_pagebox > .pagedjs_area {
27105 grid-column: center;
27106 grid-row: page;
27107 width: 100%;
27108 height: 100%;
27109 padding: var(--pagedjs-padding-top) var(--pagedjs-padding-right) var(--pagedjs-padding-bottom) var(--pagedjs-padding-left);
27110 border-top: var(--pagedjs-border-top);
27111 border-right: var(--pagedjs-border-right);
27112 border-bottom: var(--pagedjs-border-bottom);
27113 border-left: var(--pagedjs-border-left);
27114}
27115
27116.pagedjs_pagebox > .pagedjs_area > .pagedjs_page_content {
27117 width: 100%;
27118 height: calc(100% - var(--pagedjs-footnotes-height));
27119 position: relative;
27120 column-fill: auto;
27121}
27122
27123.pagedjs_pagebox > .pagedjs_area > .pagedjs_page_content > div {
27124 height: inherit;
27125}
27126
27127.pagedjs_pagebox > .pagedjs_area > .pagedjs_footnote_area {
27128 position: relative;
27129 overflow: hidden;
27130 height: var(--pagedjs-footnotes-height);
27131 display: flex;
27132 justify-content: flex-end;
27133 flex-flow: column;
27134}
27135
27136.pagedjs_pagebox > .pagedjs_area > .pagedjs_footnote_area > .pagedjs_footnote_content {
27137 overflow: hidden;
27138}
27139
27140.pagedjs_pagebox > .pagedjs_area > .pagedjs_footnote_area > .pagedjs_footnote_inner_content {
27141 overflow: hidden;
27142}
27143
27144.pagedjs_area [data-footnote-call] {
27145 all: unset;
27146 counter-increment: footnote;
27147}
27148
27149.pagedjs_area [data-split-from] {
27150 counter-increment: unset;
27151 counter-reset: unset;
27152}
27153
27154[data-footnote-call]::after {
27155 vertical-align: super;
27156 font-size: 65%;
27157 line-height: normal;
27158 content: counter(footnote);
27159}
27160
27161@supports ( font-variant-position: super ) {
27162 [data-footnote-call]::after {
27163 vertical-align: baseline;
27164 font-size: 100%;
27165 line-height: inherit;
27166 font-variant-position: super;
27167 }
27168}
27169
27170.pagedjs_footnote_empty {
27171 display: none;
27172}
27173
27174.pagedjs_area [data-split-from] {
27175 counter-increment: unset;
27176 counter-reset: unset;
27177}
27178
27179[data-footnote-marker] {
27180 text-indent: 0;
27181 display: list-item;
27182 list-style-position: inside;
27183}
27184
27185[data-footnote-marker][data-split-from] {
27186 list-style: none;
27187}
27188
27189[data-footnote-marker]:not([data-split-from]) {
27190 counter-increment: footnote-marker;
27191}
27192
27193[data-footnote-marker]::marker {
27194 content: counter(footnote-marker) ". ";
27195}
27196
27197[data-footnote-marker][data-split-from]::marker {
27198 content: unset;
27199}
27200
27201.pagedjs_area .pagedjs_footnote_inner_content [data-note-display="inline"] {
27202 display: inline;
27203}
27204
27205.pagedjs_page {
27206 counter-increment: page var(--pagedjs-page-counter-increment);
27207 width: var(--pagedjs-width);
27208 height: var(--pagedjs-height);
27209}
27210
27211.pagedjs_page.pagedjs_right_page {
27212 width: var(--pagedjs-width-right);
27213 height: var(--pagedjs-height-right);
27214}
27215
27216.pagedjs_page.pagedjs_left_page {
27217 width: var(--pagedjs-width-left);
27218 height: var(--pagedjs-height-left);
27219}
27220
27221.pagedjs_pages {
27222 counter-reset: pages var(--pagedjs-page-count) footnote var(--pagedjs-footnotes-count) footnote-marker var(--pagedjs-footnotes-count);
27223}
27224
27225.pagedjs_pagebox .pagedjs_margin-top-left-corner,
27226.pagedjs_pagebox .pagedjs_margin-top-right-corner,
27227.pagedjs_pagebox .pagedjs_margin-bottom-left-corner,
27228.pagedjs_pagebox .pagedjs_margin-bottom-right-corner,
27229.pagedjs_pagebox .pagedjs_margin-top-left,
27230.pagedjs_pagebox .pagedjs_margin-top-right,
27231.pagedjs_pagebox .pagedjs_margin-bottom-left,
27232.pagedjs_pagebox .pagedjs_margin-bottom-right,
27233.pagedjs_pagebox .pagedjs_margin-top-center,
27234.pagedjs_pagebox .pagedjs_margin-bottom-center,
27235.pagedjs_pagebox .pagedjs_margin-top-center,
27236.pagedjs_pagebox .pagedjs_margin-bottom-center,
27237.pagedjs_margin-right-middle,
27238.pagedjs_margin-left-middle {
27239 display: flex;
27240 align-items: center;
27241}
27242
27243.pagedjs_margin-right-top,
27244.pagedjs_margin-left-top {
27245 display: flex;
27246 align-items: flex-top;
27247}
27248
27249
27250.pagedjs_margin-right-bottom,
27251.pagedjs_margin-left-bottom {
27252 display: flex;
27253 align-items: flex-end;
27254}
27255
27256
27257
27258/*
27259.pagedjs_pagebox .pagedjs_margin-top-center,
27260.pagedjs_pagebox .pagedjs_margin-bottom-center {
27261 height: 100%;
27262 display: none;
27263 align-items: center;
27264 flex: 1 0 33%;
27265 margin: 0 auto;
27266}
27267
27268.pagedjs_pagebox .pagedjs_margin-top-left-corner,
27269.pagedjs_pagebox .pagedjs_margin-top-right-corner,
27270.pagedjs_pagebox .pagedjs_margin-bottom-right-corner,
27271.pagedjs_pagebox .pagedjs_margin-bottom-left-corner {
27272 display: none;
27273 align-items: center;
27274}
27275
27276.pagedjs_pagebox .pagedjs_margin-left-top,
27277.pagedjs_pagebox .pagedjs_margin-right-top {
27278 display: none;
27279 align-items: flex-start;
27280}
27281
27282.pagedjs_pagebox .pagedjs_margin-right-middle,
27283.pagedjs_pagebox .pagedjs_margin-left-middle {
27284 display: none;
27285 align-items: center;
27286}
27287
27288.pagedjs_pagebox .pagedjs_margin-left-bottom,
27289.pagedjs_pagebox .pagedjs_margin-right-bottom {
27290 display: none;
27291 align-items: flex-end;
27292}
27293*/
27294
27295.pagedjs_pagebox .pagedjs_margin-top-left,
27296.pagedjs_pagebox .pagedjs_margin-top-right-corner,
27297.pagedjs_pagebox .pagedjs_margin-bottom-left,
27298.pagedjs_pagebox .pagedjs_margin-bottom-right-corner { text-align: left; }
27299
27300.pagedjs_pagebox .pagedjs_margin-top-left-corner,
27301.pagedjs_pagebox .pagedjs_margin-top-right,
27302.pagedjs_pagebox .pagedjs_margin-bottom-left-corner,
27303.pagedjs_pagebox .pagedjs_margin-bottom-right { text-align: right; }
27304
27305.pagedjs_pagebox .pagedjs_margin-top-center,
27306.pagedjs_pagebox .pagedjs_margin-bottom-center,
27307.pagedjs_pagebox .pagedjs_margin-left-top,
27308.pagedjs_pagebox .pagedjs_margin-left-middle,
27309.pagedjs_pagebox .pagedjs_margin-left-bottom,
27310.pagedjs_pagebox .pagedjs_margin-right-top,
27311.pagedjs_pagebox .pagedjs_margin-right-middle,
27312.pagedjs_pagebox .pagedjs_margin-right-bottom { text-align: center; }
27313
27314.pagedjs_pages .pagedjs_margin .pagedjs_margin-content {
27315 width: 100%;
27316}
27317
27318.pagedjs_pages .pagedjs_margin-left .pagedjs_margin-content::after,
27319.pagedjs_pages .pagedjs_margin-top .pagedjs_margin-content::after,
27320.pagedjs_pages .pagedjs_margin-right .pagedjs_margin-content::after,
27321.pagedjs_pages .pagedjs_margin-bottom .pagedjs_margin-content::after {
27322 display: block;
27323}
27324
27325.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to] {
27326 margin-bottom: unset;
27327 padding-bottom: unset;
27328}
27329
27330.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from] {
27331 text-indent: unset;
27332 margin-top: unset;
27333 padding-top: unset;
27334 initial-letter: unset;
27335}
27336
27337.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from] > *::first-letter,
27338.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]::first-letter {
27339 color: unset;
27340 font-size: unset;
27341 font-weight: unset;
27342 font-family: unset;
27343 color: unset;
27344 line-height: unset;
27345 float: unset;
27346 padding: unset;
27347 margin: unset;
27348}
27349
27350.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to]:not([data-footnote-call]):after,
27351.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-to]:not([data-footnote-call])::after {
27352 content: unset;
27353}
27354
27355.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]:not([data-footnote-call]):before,
27356.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div [data-split-from]:not([data-footnote-call])::before {
27357 content: unset;
27358}
27359
27360.pagedjs_pages > .pagedjs_page > .pagedjs_sheet > .pagedjs_pagebox > .pagedjs_area > div li[data-split-from]:first-of-type {
27361 list-style: none;
27362}
27363
27364/*
27365[data-page]:not([data-split-from]),
27366[data-break-before="page"]:not([data-split-from]),
27367[data-break-before="always"]:not([data-split-from]),
27368[data-break-before="left"]:not([data-split-from]),
27369[data-break-before="right"]:not([data-split-from]),
27370[data-break-before="recto"]:not([data-split-from]),
27371[data-break-before="verso"]:not([data-split-from])
27372{
27373 break-before: column;
27374}
27375
27376[data-page]:not([data-split-to]),
27377[data-break-after="page"]:not([data-split-to]),
27378[data-break-after="always"]:not([data-split-to]),
27379[data-break-after="left"]:not([data-split-to]),
27380[data-break-after="right"]:not([data-split-to]),
27381[data-break-after="recto"]:not([data-split-to]),
27382[data-break-after="verso"]:not([data-split-to])
27383{
27384 break-after: column;
27385}
27386*/
27387
27388.pagedjs_clear-after::after {
27389 content: none !important;
27390}
27391
27392[data-align-last-split-element='justify'] {
27393 text-align-last: justify;
27394}
27395
27396
27397@media print {
27398 html {
27399 width: 100%;
27400 height: 100%;
27401 -webkit-print-color-adjust: exact;
27402 print-color-adjust: exact;
27403 }
27404 body {
27405 margin: 0;
27406 padding: 0;
27407 width: 100% !important;
27408 height: 100% !important;
27409 min-width: 100%;
27410 max-width: 100%;
27411 min-height: 100%;
27412 max-height: 100%;
27413 }
27414 .pagedjs_pages {
27415 width: auto;
27416 display: block !important;
27417 transform: none !important;
27418 height: 100% !important;
27419 min-height: 100%;
27420 max-height: 100%;
27421 overflow: visible;
27422 }
27423 .pagedjs_page {
27424 margin: 0;
27425 padding: 0;
27426 max-height: 100%;
27427 min-height: 100%;
27428 height: 100% !important;
27429 page-break-after: always;
27430 break-after: page;
27431 }
27432 .pagedjs_sheet {
27433 margin: 0;
27434 padding: 0;
27435 max-height: 100%;
27436 min-height: 100%;
27437 height: 100% !important;
27438 }
27439}
27440`;
27441
27442async function request(url, options={}) {
27443 return new Promise(function(resolve, reject) {
27444 let request = new XMLHttpRequest();
27445
27446 request.open(options.method || "get", url, true);
27447
27448 for (let i in options.headers) {
27449 request.setRequestHeader(i, options.headers[i]);
27450 }
27451
27452 request.withCredentials = options.credentials === "include";
27453
27454 request.onload = () => {
27455 // Chrome returns a status code of 0 for local files
27456 const status = request.status === 0 && url.startsWith("file://") ? 200 : request.status;
27457 resolve(new Response(request.responseText, {status}));
27458 };
27459
27460 request.onerror = reject;
27461
27462 request.send(options.body || null);
27463 });
27464}
27465
27466class Polisher {
27467 constructor(setup) {
27468 this.sheets = [];
27469 this.inserted = [];
27470
27471 this.hooks = {};
27472 this.hooks.onUrl = new Hook(this);
27473 this.hooks.onAtPage = new Hook(this);
27474 this.hooks.onAtMedia = new Hook(this);
27475 this.hooks.onRule = new Hook(this);
27476 this.hooks.onDeclaration = new Hook(this);
27477 this.hooks.onContent = new Hook(this);
27478 this.hooks.onSelector = new Hook(this);
27479 this.hooks.onPseudoSelector = new Hook(this);
27480
27481 this.hooks.onImport = new Hook(this);
27482
27483 this.hooks.beforeTreeParse = new Hook(this);
27484 this.hooks.beforeTreeWalk = new Hook(this);
27485 this.hooks.afterTreeWalk = new Hook(this);
27486
27487 if (setup !== false) {
27488 this.setup();
27489 }
27490 }
27491
27492 setup() {
27493 this.base = this.insert(baseStyles);
27494 this.styleEl = document.createElement("style");
27495 document.head.appendChild(this.styleEl);
27496 this.styleSheet = this.styleEl.sheet;
27497 return this.styleSheet;
27498 }
27499
27500 async add() {
27501 let fetched = [];
27502 let urls = [];
27503
27504 for (var i = 0; i < arguments.length; i++) {
27505 let f;
27506
27507 if (typeof arguments[i] === "object") {
27508 for (let url in arguments[i]) {
27509 let obj = arguments[i];
27510 f = new Promise(function(resolve, reject) {
27511 urls.push(url);
27512 resolve(obj[url]);
27513 });
27514 }
27515 } else {
27516 urls.push(arguments[i]);
27517 f = request(arguments[i]).then((response) => {
27518 return response.text();
27519 });
27520 }
27521
27522
27523 fetched.push(f);
27524 }
27525
27526 return await Promise.all(fetched)
27527 .then(async (originals) => {
27528 let text = "";
27529 for (let index = 0; index < originals.length; index++) {
27530 text = await this.convertViaSheet(originals[index], urls[index]);
27531 this.insert(text);
27532 }
27533 return text;
27534 });
27535 }
27536
27537 async convertViaSheet(cssStr, href) {
27538 let sheet = new Sheet(href, this.hooks);
27539 await sheet.parse(cssStr);
27540
27541 // Insert the imported sheets first
27542 for (let url of sheet.imported) {
27543 let str = await request(url).then((response) => {
27544 return response.text();
27545 });
27546 let text = await this.convertViaSheet(str, url);
27547 this.insert(text);
27548 }
27549
27550 this.sheets.push(sheet);
27551
27552 if (typeof sheet.width !== "undefined") {
27553 this.width = sheet.width;
27554 }
27555 if (typeof sheet.height !== "undefined") {
27556 this.height = sheet.height;
27557 }
27558 if (typeof sheet.orientation !== "undefined") {
27559 this.orientation = sheet.orientation;
27560 }
27561 return sheet.toString();
27562 }
27563
27564 insert(text){
27565 let head = document.querySelector("head");
27566 let style = document.createElement("style");
27567 style.setAttribute("data-pagedjs-inserted-styles", "true");
27568
27569 style.appendChild(document.createTextNode(text));
27570
27571 head.appendChild(style);
27572
27573 this.inserted.push(style);
27574 return style;
27575 }
27576
27577 destroy() {
27578 this.styleEl.remove();
27579 this.inserted.forEach((s) => {
27580 s.remove();
27581 });
27582 this.sheets = [];
27583 }
27584}
27585
27586class Handler {
27587 constructor(chunker, polisher, caller) {
27588 let hooks = Object.assign({}, chunker && chunker.hooks, polisher && polisher.hooks, caller && caller.hooks);
27589 this.chunker = chunker;
27590 this.polisher = polisher;
27591 this.caller = caller;
27592
27593 for (let name in hooks) {
27594 if (name in this) {
27595 let hook = hooks[name];
27596 hook.register(this[name].bind(this));
27597 }
27598 }
27599 }
27600}
27601
27602EventEmitter(Handler.prototype);
27603
27604// https://www.w3.org/TR/css3-page/#page-size-prop
27605
27606var pageSizes = {
27607 "A0": {
27608 width: {
27609 value: 841,
27610 unit: "mm"
27611 },
27612 height: {
27613 value: 1189,
27614 unit: "mm"
27615 }
27616 },
27617 "A1": {
27618 width: {
27619 value: 594,
27620 unit: "mm"
27621 },
27622 height: {
27623 value: 841,
27624 unit: "mm"
27625 }
27626 },
27627 "A2": {
27628 width: {
27629 value: 420,
27630 unit: "mm"
27631 },
27632 height: {
27633 value: 594,
27634 unit: "mm"
27635 }
27636 },
27637 "A3": {
27638 width: {
27639 value: 297,
27640 unit: "mm"
27641 },
27642 height: {
27643 value: 420,
27644 unit: "mm"
27645 }
27646 },
27647 "A4": {
27648 width: {
27649 value: 210,
27650 unit: "mm"
27651 },
27652 height: {
27653 value: 297,
27654 unit: "mm"
27655 }
27656 },
27657 "A5": {
27658 width: {
27659 value: 148,
27660 unit: "mm"
27661 },
27662 height: {
27663 value: 210,
27664 unit: "mm"
27665 }
27666 },
27667 "A6": {
27668 width: {
27669 value: 105,
27670 unit: "mm"
27671 },
27672 height: {
27673 value: 148,
27674 unit: "mm"
27675 }
27676 },
27677 "A7": {
27678 width: {
27679 value: 74,
27680 unit: "mm"
27681 },
27682 height: {
27683 value: 105,
27684 unit: "mm"
27685 }
27686 },
27687 "A8": {
27688 width: {
27689 value: 52,
27690 unit: "mm"
27691 },
27692 height: {
27693 value: 74,
27694 unit: "mm"
27695 }
27696 },
27697 "A9": {
27698 width: {
27699 value: 37,
27700 unit: "mm"
27701 },
27702 height: {
27703 value: 52,
27704 unit: "mm"
27705 }
27706 },
27707 "A10": {
27708 width: {
27709 value: 26,
27710 unit: "mm"
27711 },
27712 height: {
27713 value: 37,
27714 unit: "mm"
27715 }
27716 },
27717 "B4": {
27718 width: {
27719 value: 250,
27720 unit: "mm"
27721 },
27722 height: {
27723 value: 353,
27724 unit: "mm"
27725 }
27726 },
27727 "B5": {
27728 width: {
27729 value: 176,
27730 unit: "mm"
27731 },
27732 height: {
27733 value: 250,
27734 unit: "mm"
27735 }
27736 },
27737 "letter": {
27738 width: {
27739 value: 8.5,
27740 unit: "in"
27741 },
27742 height: {
27743 value: 11,
27744 unit: "in"
27745 }
27746 },
27747 "legal": {
27748 width: {
27749 value: 8.5,
27750 unit: "in"
27751 },
27752 height: {
27753 value: 14,
27754 unit: "in"
27755 }
27756 },
27757 "ledger": {
27758 width: {
27759 value: 11,
27760 unit: "in"
27761 },
27762 height: {
27763 value: 17,
27764 unit: "in"
27765 }
27766 }
27767};
27768
27769class AtPage extends Handler {
27770 constructor(chunker, polisher, caller) {
27771 super(chunker, polisher, caller);
27772
27773 this.pages = {};
27774
27775 this.width = undefined;
27776 this.height = undefined;
27777 this.orientation = undefined;
27778 this.marginalia = {};
27779 }
27780
27781 pageModel(selector) {
27782 return {
27783 selector: selector,
27784 name: undefined,
27785 psuedo: undefined,
27786 nth: undefined,
27787 marginalia: {},
27788 width: undefined,
27789 height: undefined,
27790 orientation: undefined,
27791 margin: {
27792 top: {},
27793 right: {},
27794 left: {},
27795 bottom: {}
27796 },
27797 padding: {
27798 top: {},
27799 right: {},
27800 left: {},
27801 bottom: {}
27802 },
27803 border: {
27804 top: {},
27805 right: {},
27806 left: {},
27807 bottom: {}
27808 },
27809 backgroundOrigin: undefined,
27810 block: {},
27811 marks: undefined,
27812 notes: undefined,
27813 added: false
27814 };
27815 }
27816
27817 // Find and Remove @page rules
27818 onAtPage(node, item, list) {
27819 let page, marginalia;
27820 let selector = "";
27821 let named, psuedo, nth;
27822 let needsMerge = false;
27823
27824 if (node.prelude) {
27825 named = this.getTypeSelector(node);
27826 psuedo = this.getPsuedoSelector(node);
27827 nth = this.getNthSelector(node);
27828 selector = csstree.generate(node.prelude);
27829 } else {
27830 selector = "*";
27831 }
27832
27833 if (selector in this.pages) {
27834 // this.pages[selector] = Object.assign(this.pages[selector], page);
27835 // console.log("after", selector, this.pages[selector]);
27836
27837 // this.pages[selector].added = false;
27838 page = this.pages[selector];
27839 marginalia = this.replaceMarginalia(node);
27840 needsMerge = true;
27841 // Mark page for getting classes added again
27842 page.added = false;
27843 } else {
27844 page = this.pageModel(selector);
27845 marginalia = this.replaceMarginalia(node);
27846 this.pages[selector] = page;
27847 }
27848
27849 page.name = named;
27850 page.psuedo = psuedo;
27851 page.nth = nth;
27852
27853 if (needsMerge) {
27854 page.marginalia = Object.assign(page.marginalia, marginalia);
27855 } else {
27856 page.marginalia = marginalia;
27857 }
27858
27859 let notes = this.replaceNotes(node);
27860 page.notes = notes;
27861
27862 let declarations = this.replaceDeclarations(node);
27863
27864 if (declarations.size) {
27865 page.size = declarations.size;
27866 page.width = declarations.size.width;
27867 page.height = declarations.size.height;
27868 page.orientation = declarations.size.orientation;
27869 page.format = declarations.size.format;
27870 }
27871
27872 if (declarations.bleed && declarations.bleed[0] != "auto") {
27873 switch (declarations.bleed.length) {
27874 case 4: // top right bottom left
27875 page.bleed = {
27876 top: declarations.bleed[0],
27877 right: declarations.bleed[1],
27878 bottom: declarations.bleed[2],
27879 left: declarations.bleed[3]
27880 };
27881 break;
27882 case 3: // top right bottom right
27883 page.bleed = {
27884 top: declarations.bleed[0],
27885 right: declarations.bleed[1],
27886 bottom: declarations.bleed[2],
27887 left: declarations.bleed[1]
27888 };
27889 break;
27890 case 2: // top right top right
27891 page.bleed = {
27892 top: declarations.bleed[0],
27893 right: declarations.bleed[1],
27894 bottom: declarations.bleed[0],
27895 left: declarations.bleed[1]
27896 };
27897 break;
27898 default:
27899 page.bleed = {
27900 top: declarations.bleed[0],
27901 right: declarations.bleed[0],
27902 bottom: declarations.bleed[0],
27903 left: declarations.bleed[0]
27904 };
27905 }
27906 }
27907
27908 if (declarations.marks) {
27909 if (!declarations.bleed || declarations.bleed && declarations.bleed[0] === "auto") {
27910 // Spec say 6pt, but needs more space for marks
27911 page.bleed = {
27912 top: { value: 6, unit: "mm" },
27913 right: { value: 6, unit: "mm" },
27914 bottom: { value: 6, unit: "mm" },
27915 left: { value: 6, unit: "mm" }
27916 };
27917 }
27918
27919 page.marks = declarations.marks;
27920 }
27921
27922 if (declarations.margin) {
27923 page.margin = declarations.margin;
27924 }
27925 if (declarations.padding) {
27926 page.padding = declarations.padding;
27927 }
27928
27929 if (declarations.border) {
27930 page.border = declarations.border;
27931 }
27932
27933 if (declarations.marks) {
27934 page.marks = declarations.marks;
27935 }
27936
27937 if (needsMerge) {
27938 page.block.children.appendList(node.block.children);
27939 } else {
27940 page.block = node.block;
27941 }
27942
27943 // Remove the rule
27944 list.remove(item);
27945 }
27946
27947 /* Handled in breaks */
27948 /*
27949 afterParsed(parsed) {
27950 for (let b in this.named) {
27951 // Find elements
27952 let elements = parsed.querySelectorAll(b);
27953 // Add break data
27954 for (var i = 0; i < elements.length; i++) {
27955 elements[i].setAttribute("data-page", this.named[b]);
27956 }
27957 }
27958 }
27959 */
27960
27961 afterTreeWalk(ast, sheet) {
27962 let dirtyPage = "*" in this.pages && this.pages["*"].added === false;
27963
27964 this.addPageClasses(this.pages, ast, sheet);
27965
27966 if (dirtyPage) {
27967 let width = this.pages["*"].width;
27968 let height = this.pages["*"].height;
27969 let format = this.pages["*"].format;
27970 let orientation = this.pages["*"].orientation;
27971 let bleed = this.pages["*"].bleed;
27972 let marks = this.pages["*"].marks;
27973 let bleedverso = undefined;
27974 let bleedrecto = undefined;
27975
27976 if (":left" in this.pages) {
27977 bleedverso = this.pages[":left"].bleed;
27978 }
27979
27980 if (":right" in this.pages) {
27981 bleedrecto = this.pages[":right"].bleed;
27982 }
27983
27984 if ((width && height) &&
27985 (this.width !== width || this.height !== height)) {
27986 this.width = width;
27987 this.height = height;
27988 this.format = format;
27989 this.orientation = orientation;
27990
27991 this.addRootVars(ast, width, height, orientation, bleed, bleedrecto, bleedverso, marks);
27992 this.addRootPage(ast, this.pages["*"].size, bleed, bleedrecto, bleedverso);
27993
27994 this.emit("size", { width, height, orientation, format, bleed });
27995 this.emit("atpages", this.pages);
27996 }
27997
27998 }
27999 }
28000
28001 getTypeSelector(ast) {
28002 // Find page name
28003 let name;
28004
28005 csstree.walk(ast, {
28006 visit: "TypeSelector",
28007 enter: (node, item, list) => {
28008 name = node.name;
28009 }
28010 });
28011
28012 return name;
28013 }
28014
28015 getPsuedoSelector(ast) {
28016 // Find if it has :left & :right & :black & :first
28017 let name;
28018 csstree.walk(ast, {
28019 visit: "PseudoClassSelector",
28020 enter: (node, item, list) => {
28021 if (node.name !== "nth") {
28022 name = node.name;
28023 }
28024 }
28025 });
28026
28027 return name;
28028 }
28029
28030 getNthSelector(ast) {
28031 // Find if it has :nth
28032 let nth;
28033 csstree.walk(ast, {
28034 visit: "PseudoClassSelector",
28035 enter: (node, item, list) => {
28036 if (node.name === "nth" && node.children) {
28037 let raw = node.children.first();
28038 nth = raw.value;
28039 }
28040 }
28041 });
28042
28043 return nth;
28044 }
28045
28046 replaceMarginalia(ast) {
28047 let parsed = {};
28048 const MARGINS = [
28049 "top-left-corner", "top-left", "top", "top-center", "top-right", "top-right-corner",
28050 "bottom-left-corner", "bottom-left", "bottom", "bottom-center", "bottom-right", "bottom-right-corner",
28051 "left-top", "left-middle", "left", "left-bottom", "top-right-corner",
28052 "right-top", "right-middle", "right", "right-bottom", "right-right-corner"
28053 ];
28054 csstree.walk(ast.block, {
28055 visit: "Atrule",
28056 enter: (node, item, list) => {
28057 let name = node.name;
28058 if (MARGINS.includes(name)) {
28059 if (name === "top") {
28060 name = "top-center";
28061 }
28062 if (name === "right") {
28063 name = "right-middle";
28064 }
28065 if (name === "left") {
28066 name = "left-middle";
28067 }
28068 if (name === "bottom") {
28069 name = "bottom-center";
28070 }
28071 parsed[name] = node.block;
28072 list.remove(item);
28073 }
28074 }
28075 });
28076
28077 return parsed;
28078 }
28079
28080 replaceNotes(ast) {
28081 let parsed = {};
28082
28083 csstree.walk(ast.block, {
28084 visit: "Atrule",
28085 enter: (node, item, list) => {
28086 let name = node.name;
28087 if (name === "footnote") {
28088 parsed[name] = node.block;
28089 list.remove(item);
28090 }
28091 }
28092 });
28093
28094 return parsed;
28095 }
28096
28097 replaceDeclarations(ast) {
28098 let parsed = {};
28099
28100 csstree.walk(ast.block, {
28101 visit: "Declaration",
28102 enter: (declaration, dItem, dList) => {
28103 let prop = csstree.property(declaration.property).name;
28104 // let value = declaration.value;
28105
28106 if (prop === "marks") {
28107 parsed.marks = [];
28108 csstree.walk(declaration, {
28109 visit: "Identifier",
28110 enter: (ident) => {
28111 parsed.marks.push(ident.name);
28112 }
28113 });
28114 dList.remove(dItem);
28115 } else if (prop === "margin") {
28116 parsed.margin = this.getMargins(declaration);
28117 dList.remove(dItem);
28118
28119 } else if (prop.indexOf("margin-") === 0) {
28120 let m = prop.substring("margin-".length);
28121 if (!parsed.margin) {
28122 parsed.margin = {
28123 top: {},
28124 right: {},
28125 left: {},
28126 bottom: {}
28127 };
28128 }
28129 parsed.margin[m] = declaration.value.children.first();
28130 dList.remove(dItem);
28131
28132 } else if (prop === "padding") {
28133 parsed.padding = this.getPaddings(declaration.value);
28134 dList.remove(dItem);
28135
28136 } else if (prop.indexOf("padding-") === 0) {
28137 let p = prop.substring("padding-".length);
28138 if (!parsed.padding) {
28139 parsed.padding = {
28140 top: {},
28141 right: {},
28142 left: {},
28143 bottom: {}
28144 };
28145 }
28146 parsed.padding[p] = declaration.value.children.first();
28147 dList.remove(dItem);
28148 }
28149
28150 else if (prop === "border") {
28151 if (!parsed.border) {
28152 parsed.border = {
28153 top: {},
28154 right: {},
28155 left: {},
28156 bottom: {}
28157 };
28158 }
28159 parsed.border.top = csstree.generate(declaration.value);
28160 parsed.border.right = csstree.generate(declaration.value);
28161 parsed.border.left = csstree.generate(declaration.value);
28162 parsed.border.bottom = csstree.generate(declaration.value);
28163
28164 dList.remove(dItem);
28165
28166 }
28167
28168 else if (prop.indexOf("border-") === 0) {
28169 if (!parsed.border) {
28170 parsed.border = {
28171 top: {},
28172 right: {},
28173 left: {},
28174 bottom: {}
28175 };
28176 }
28177 let p = prop.substring("border-".length);
28178
28179 parsed.border[p] = csstree.generate(declaration.value);
28180 dList.remove(dItem);
28181
28182 }
28183
28184 else if (prop === "size") {
28185 parsed.size = this.getSize(declaration);
28186 dList.remove(dItem);
28187 } else if (prop === "bleed") {
28188 parsed.bleed = [];
28189
28190 csstree.walk(declaration, {
28191 enter: (subNode) => {
28192 switch (subNode.type) {
28193 case "String": // bleed: "auto"
28194 if (subNode.value.indexOf("auto") > -1) {
28195 parsed.bleed.push("auto");
28196 }
28197 break;
28198 case "Dimension": // bleed: 1in 2in, bleed: 20px ect.
28199 parsed.bleed.push({
28200 value: subNode.value,
28201 unit: subNode.unit
28202 });
28203 break;
28204 case "Number":
28205 parsed.bleed.push({
28206 value: subNode.value,
28207 unit: "px"
28208 });
28209 break;
28210 // ignore
28211 }
28212
28213 }
28214 });
28215
28216 dList.remove(dItem);
28217 }
28218
28219 }
28220 });
28221
28222 return parsed;
28223
28224 }
28225 getSize(declaration) {
28226 let width, height, orientation, format;
28227
28228 // Get size: Xmm Ymm
28229 csstree.walk(declaration, {
28230 visit: "Dimension",
28231 enter: (node, item, list) => {
28232 let { value, unit } = node;
28233 if (typeof width === "undefined") {
28234 width = { value, unit };
28235 } else if (typeof height === "undefined") {
28236 height = { value, unit };
28237 }
28238 }
28239 });
28240
28241 // Get size: "A4"
28242 csstree.walk(declaration, {
28243 visit: "String",
28244 enter: (node, item, list) => {
28245 let name = node.value.replace(/["|']/g, "");
28246 let s = pageSizes[name];
28247 if (s) {
28248 width = s.width;
28249 height = s.height;
28250 }
28251 }
28252 });
28253
28254 // Get Format or Landscape or Portrait
28255 csstree.walk(declaration, {
28256 visit: "Identifier",
28257 enter: (node, item, list) => {
28258 let name = node.name;
28259 if (name === "landscape" || name === "portrait") {
28260 orientation = node.name;
28261 } else if (name !== "auto") {
28262 let s = pageSizes[name];
28263 if (s) {
28264 width = s.width;
28265 height = s.height;
28266 }
28267 format = name;
28268 }
28269 }
28270 });
28271
28272 return {
28273 width,
28274 height,
28275 orientation,
28276 format
28277 };
28278 }
28279
28280 getMargins(declaration) {
28281 let margins = [];
28282 let margin = {
28283 top: {},
28284 right: {},
28285 left: {},
28286 bottom: {}
28287 };
28288
28289 csstree.walk(declaration, {
28290 enter: (node) => {
28291 switch (node.type) {
28292 case "Dimension": // margin: 1in 2in, margin: 20px, etc...
28293 margins.push(node);
28294 break;
28295 case "Number": // margin: 0
28296 margins.push({value: node.value, unit: "px"});
28297 break;
28298 // ignore
28299 }
28300 }
28301 });
28302
28303 if (margins.length === 1) {
28304 for (let m in margin) {
28305 margin[m] = margins[0];
28306 }
28307 } else if (margins.length === 2) {
28308 margin.top = margins[0];
28309 margin.right = margins[1];
28310 margin.bottom = margins[0];
28311 margin.left = margins[1];
28312 } else if (margins.length === 3) {
28313 margin.top = margins[0];
28314 margin.right = margins[1];
28315 margin.bottom = margins[2];
28316 margin.left = margins[1];
28317 } else if (margins.length === 4) {
28318 margin.top = margins[0];
28319 margin.right = margins[1];
28320 margin.bottom = margins[2];
28321 margin.left = margins[3];
28322 }
28323
28324 return margin;
28325 }
28326
28327 getPaddings(declaration) {
28328 let paddings = [];
28329 let padding = {
28330 top: {},
28331 right: {},
28332 left: {},
28333 bottom: {}
28334 };
28335
28336 csstree.walk(declaration, {
28337 enter: (node) => {
28338 switch (node.type) {
28339 case "Dimension": // padding: 1in 2in, padding: 20px, etc...
28340 paddings.push(node);
28341 break;
28342 case "Number": // padding: 0
28343 paddings.push({value: node.value, unit: "px"});
28344 break;
28345 // ignore
28346 }
28347 }
28348 });
28349 if (paddings.length === 1) {
28350 for (let p in padding) {
28351 padding[p] = paddings[0];
28352 }
28353 } else if (paddings.length === 2) {
28354
28355 padding.top = paddings[0];
28356 padding.right = paddings[1];
28357 padding.bottom = paddings[0];
28358 padding.left = paddings[1];
28359 } else if (paddings.length === 3) {
28360
28361 padding.top = paddings[0];
28362 padding.right = paddings[1];
28363 padding.bottom = paddings[2];
28364 padding.left = paddings[1];
28365 } else if (paddings.length === 4) {
28366
28367 padding.top = paddings[0];
28368 padding.right = paddings[1];
28369 padding.bottom = paddings[2];
28370 padding.left = paddings[3];
28371 }
28372 return padding;
28373 }
28374
28375 // get values for the border on the @page to pass them to the element with the .pagedjs_area class
28376 getBorders(declaration) {
28377 let border = {
28378 top: {},
28379 right: {},
28380 left: {},
28381 bottom: {}
28382 };
28383
28384 if (declaration.prop == "border") {
28385 border.top = csstree.generate(declaration.value);
28386 border.right = csstree.generate(declaration.value);
28387 border.bottom = csstree.generate(declaration.value);
28388 border.left = csstree.generate(declaration.value);
28389
28390 }
28391 else if (declaration.prop == "border-top") {
28392 border.top = csstree.generate(declaration.value);
28393 }
28394 else if (declaration.prop == "border-right") {
28395 border.right = csstree.generate(declaration.value);
28396
28397 }
28398 else if (declaration.prop == "border-bottom") {
28399 border.bottom = csstree.generate(declaration.value);
28400
28401 }
28402 else if (declaration.prop == "border-left") {
28403 border.left = csstree.generate(declaration.value);
28404 }
28405
28406 return border;
28407 }
28408
28409
28410 addPageClasses(pages, ast, sheet) {
28411 // First add * page
28412 if ("*" in pages && pages["*"].added === false) {
28413 let p = this.createPage(pages["*"], ast.children, sheet);
28414 sheet.insertRule(p);
28415 pages["*"].added = true;
28416 }
28417 // Add :left & :right
28418 if (":left" in pages && pages[":left"].added === false) {
28419 let left = this.createPage(pages[":left"], ast.children, sheet);
28420 sheet.insertRule(left);
28421 pages[":left"].added = true;
28422 }
28423 if (":right" in pages && pages[":right"].added === false) {
28424 let right = this.createPage(pages[":right"], ast.children, sheet);
28425 sheet.insertRule(right);
28426 pages[":right"].added = true;
28427 }
28428 // Add :first & :blank
28429 if (":first" in pages && pages[":first"].added === false) {
28430 let first = this.createPage(pages[":first"], ast.children, sheet);
28431 sheet.insertRule(first);
28432 pages[":first"].added = true;
28433 }
28434 if (":blank" in pages && pages[":blank"].added === false) {
28435 let blank = this.createPage(pages[":blank"], ast.children, sheet);
28436 sheet.insertRule(blank);
28437 pages[":blank"].added = true;
28438 }
28439 // Add nth pages
28440 for (let pg in pages) {
28441 if (pages[pg].nth && pages[pg].added === false) {
28442 let nth = this.createPage(pages[pg], ast.children, sheet);
28443 sheet.insertRule(nth);
28444 pages[pg].added = true;
28445 }
28446 }
28447
28448 // Add named pages
28449 for (let pg in pages) {
28450 if (pages[pg].name && pages[pg].added === false) {
28451 let named = this.createPage(pages[pg], ast.children, sheet);
28452 sheet.insertRule(named);
28453 pages[pg].added = true;
28454 }
28455 }
28456
28457 }
28458
28459 createPage(page, ruleList, sheet) {
28460
28461 let selectors = this.selectorsForPage(page);
28462 let children = page.block.children.copy();
28463 let block = {
28464 type: "Block",
28465 loc: 0,
28466 children: children
28467 };
28468
28469
28470 let rule = this.createRule(selectors, block);
28471
28472 this.addMarginVars(page.margin, children, children.first());
28473 this.addPaddingVars(page.padding, children, children.first());
28474 this.addBorderVars(page.border, children, children.first());
28475
28476
28477 if (page.width) {
28478 this.addDimensions(page.width, page.height, page.orientation, children, children.first());
28479 }
28480
28481 if (page.marginalia) {
28482 this.addMarginaliaStyles(page, ruleList, rule, sheet);
28483 this.addMarginaliaContent(page, ruleList, rule, sheet);
28484 }
28485
28486 if(page.notes) {
28487 this.addNotesStyles(page.notes, page, ruleList, rule, sheet);
28488 }
28489
28490 return rule;
28491 }
28492
28493 addMarginVars(margin, list, item) {
28494 // variables for margins
28495 for (let m in margin) {
28496 if (typeof margin[m].value !== "undefined") {
28497 let value = margin[m].value + (margin[m].unit || "");
28498 let mVar = list.createItem({
28499 type: "Declaration",
28500 property: "--pagedjs-margin-" + m,
28501 value: {
28502 type: "Raw",
28503 value: value
28504 }
28505 });
28506 list.append(mVar, item);
28507
28508 }
28509 }
28510 }
28511
28512 addPaddingVars(padding, list, item) {
28513 // variables for padding
28514 for (let p in padding) {
28515
28516 if (typeof padding[p].value !== "undefined") {
28517 let value = padding[p].value + (padding[p].unit || "");
28518 let pVar = list.createItem({
28519 type: "Declaration",
28520 property: "--pagedjs-padding-" + p,
28521 value: {
28522 type: "Raw",
28523 value: value
28524 }
28525 });
28526
28527 list.append(pVar, item);
28528 }
28529
28530 }
28531 }
28532
28533 addBorderVars(border, list, item) {
28534 // variables for borders
28535 for (const name of Object.keys(border)) {
28536 const value = border[name];
28537 // value is an empty object when undefined
28538 if (typeof value === "string") {
28539 const borderItem = list.createItem({
28540 type: "Declaration",
28541 property: "--pagedjs-border-" + name,
28542 value: {
28543 type: "Raw",
28544 value: value
28545 }
28546 });
28547 list.append(borderItem, item);
28548 }
28549 }
28550 }
28551
28552 addDimensions(width, height, orientation, list, item) {
28553 let widthString, heightString;
28554
28555 widthString = CSSValueToString(width);
28556 heightString = CSSValueToString(height);
28557
28558 if (orientation && orientation !== "portrait") {
28559 // reverse for orientation
28560 [widthString, heightString] = [heightString, widthString];
28561 }
28562
28563 // width variable
28564 let wVar = this.createVariable("--pagedjs-pagebox-width", widthString);
28565 list.appendData(wVar);
28566
28567 // height variable
28568 let hVar = this.createVariable("--pagedjs-pagebox-height", heightString);
28569 list.appendData(hVar);
28570
28571 // let w = this.createDimension("width", width);
28572 // let h = this.createDimension("height", height);
28573 // list.appendData(w);
28574 // list.appendData(h);
28575 }
28576
28577 addMarginaliaStyles(page, list, item, sheet) {
28578 for (let loc in page.marginalia) {
28579 let block = csstree.clone(page.marginalia[loc]);
28580 let hasContent = false;
28581
28582 if (block.children.isEmpty()) {
28583 continue;
28584 }
28585
28586 csstree.walk(block, {
28587 visit: "Declaration",
28588 enter: (node, item, list) => {
28589 if (node.property === "content") {
28590 if (node.value.children && node.value.children.first().name === "none") {
28591 hasContent = false;
28592 } else {
28593 hasContent = true;
28594 }
28595 list.remove(item);
28596 }
28597 if (node.property === "vertical-align") {
28598 csstree.walk(node, {
28599 visit: "Identifier",
28600 enter: (identNode, identItem, identlist) => {
28601 let name = identNode.name;
28602 if (name === "top") {
28603 identNode.name = "flex-start";
28604 } else if (name === "middle") {
28605 identNode.name = "center";
28606 } else if (name === "bottom") {
28607 identNode.name = "flex-end";
28608 }
28609 }
28610 });
28611 node.property = "align-items";
28612 }
28613
28614 if (node.property === "width" &&
28615 (loc === "top-left" ||
28616 loc === "top-center" ||
28617 loc === "top-right" ||
28618 loc === "bottom-left" ||
28619 loc === "bottom-center" ||
28620 loc === "bottom-right")) {
28621 let c = csstree.clone(node);
28622 c.property = "max-width";
28623 list.appendData(c);
28624 }
28625
28626 if (node.property === "height" &&
28627 (loc === "left-top" ||
28628 loc === "left-middle" ||
28629 loc === "left-bottom" ||
28630 loc === "right-top" ||
28631 loc === "right-middle" ||
28632 loc === "right-bottom")) {
28633 let c = csstree.clone(node);
28634 c.property = "max-height";
28635 list.appendData(c);
28636 }
28637 }
28638 });
28639
28640 let marginSelectors = this.selectorsForPageMargin(page, loc);
28641 let marginRule = this.createRule(marginSelectors, block);
28642
28643 list.appendData(marginRule);
28644
28645 let sel = csstree.generate({
28646 type: "Selector",
28647 children: marginSelectors
28648 });
28649
28650 this.marginalia[sel] = {
28651 page: page,
28652 selector: sel,
28653 block: page.marginalia[loc],
28654 hasContent: hasContent
28655 };
28656
28657 }
28658 }
28659
28660 addMarginaliaContent(page, list, item, sheet) {
28661 let displayNone;
28662 // Just content
28663 for (let loc in page.marginalia) {
28664 let content = csstree.clone(page.marginalia[loc]);
28665 csstree.walk(content, {
28666 visit: "Declaration",
28667 enter: (node, item, list) => {
28668 if (node.property !== "content") {
28669 list.remove(item);
28670 }
28671
28672 if (node.value.children && node.value.children.first().name === "none") {
28673 displayNone = true;
28674 }
28675 }
28676 });
28677
28678 if (content.children.isEmpty()) {
28679 continue;
28680 }
28681
28682 let displaySelectors = this.selectorsForPageMargin(page, loc);
28683 let displayDeclaration;
28684
28685 displaySelectors.insertData({
28686 type: "Combinator",
28687 name: ">"
28688 });
28689
28690 displaySelectors.insertData({
28691 type: "ClassSelector",
28692 name: "pagedjs_margin-content"
28693 });
28694
28695 displaySelectors.insertData({
28696 type: "Combinator",
28697 name: ">"
28698 });
28699
28700 displaySelectors.insertData({
28701 type: "TypeSelector",
28702 name: "*"
28703 });
28704
28705 if (displayNone) {
28706 displayDeclaration = this.createDeclaration("display", "none");
28707 } else {
28708 displayDeclaration = this.createDeclaration("display", "block");
28709 }
28710
28711 let displayRule = this.createRule(displaySelectors, [displayDeclaration]);
28712 sheet.insertRule(displayRule);
28713
28714 // insert content rule
28715 let contentSelectors = this.selectorsForPageMargin(page, loc);
28716
28717 contentSelectors.insertData({
28718 type: "Combinator",
28719 name: ">"
28720 });
28721
28722 contentSelectors.insertData({
28723 type: "ClassSelector",
28724 name: "pagedjs_margin-content"
28725 });
28726
28727 contentSelectors.insertData({
28728 type: "PseudoElementSelector",
28729 name: "after",
28730 children: null
28731 });
28732
28733 let contentRule = this.createRule(contentSelectors, content);
28734 sheet.insertRule(contentRule);
28735 }
28736 }
28737
28738 addRootVars(ast, width, height, orientation, bleed, bleedrecto, bleedverso, marks) {
28739 let rules = [];
28740 let selectors = new csstree.List();
28741 selectors.insertData({
28742 type: "PseudoClassSelector",
28743 name: "root",
28744 children: null
28745 });
28746
28747 let widthString, heightString;
28748 let widthStringRight, heightStringRight;
28749 let widthStringLeft, heightStringLeft;
28750
28751 if (!bleed) {
28752 widthString = CSSValueToString(width);
28753 heightString = CSSValueToString(height);
28754 widthStringRight = CSSValueToString(width);
28755 heightStringRight = CSSValueToString(height);
28756 widthStringLeft = CSSValueToString(width);
28757 heightStringLeft = CSSValueToString(height);
28758 } else {
28759 widthString = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
28760 heightString = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
28761
28762 widthStringRight = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
28763 heightStringRight = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
28764
28765 widthStringLeft = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleed.left)} + ${CSSValueToString(bleed.right)} )`;
28766 heightStringLeft = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleed.top)} + ${CSSValueToString(bleed.bottom)} )`;
28767
28768 let bleedTop = this.createVariable("--pagedjs-bleed-top", CSSValueToString(bleed.top));
28769 let bleedRight = this.createVariable("--pagedjs-bleed-right", CSSValueToString(bleed.right));
28770 let bleedBottom = this.createVariable("--pagedjs-bleed-bottom", CSSValueToString(bleed.bottom));
28771 let bleedLeft = this.createVariable("--pagedjs-bleed-left", CSSValueToString(bleed.left));
28772
28773 let bleedTopRecto = this.createVariable("--pagedjs-bleed-right-top", CSSValueToString(bleed.top));
28774 let bleedRightRecto = this.createVariable("--pagedjs-bleed-right-right", CSSValueToString(bleed.right));
28775 let bleedBottomRecto = this.createVariable("--pagedjs-bleed-right-bottom", CSSValueToString(bleed.bottom));
28776 let bleedLeftRecto = this.createVariable("--pagedjs-bleed-right-left", CSSValueToString(bleed.left));
28777
28778 let bleedTopVerso = this.createVariable("--pagedjs-bleed-left-top", CSSValueToString(bleed.top));
28779 let bleedRightVerso = this.createVariable("--pagedjs-bleed-left-right", CSSValueToString(bleed.right));
28780 let bleedBottomVerso = this.createVariable("--pagedjs-bleed-left-bottom", CSSValueToString(bleed.bottom));
28781 let bleedLeftVerso = this.createVariable("--pagedjs-bleed-left-left", CSSValueToString(bleed.left));
28782
28783 if (bleedrecto) {
28784 bleedTopRecto = this.createVariable("--pagedjs-bleed-right-top", CSSValueToString(bleedrecto.top));
28785 bleedRightRecto = this.createVariable("--pagedjs-bleed-right-right", CSSValueToString(bleedrecto.right));
28786 bleedBottomRecto = this.createVariable("--pagedjs-bleed-right-bottom", CSSValueToString(bleedrecto.bottom));
28787 bleedLeftRecto = this.createVariable("--pagedjs-bleed-right-left", CSSValueToString(bleedrecto.left));
28788
28789 widthStringRight = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleedrecto.left)} + ${CSSValueToString(bleedrecto.right)} )`;
28790 heightStringRight = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleedrecto.top)} + ${CSSValueToString(bleedrecto.bottom)} )`;
28791 }
28792 if (bleedverso) {
28793 bleedTopVerso = this.createVariable("--pagedjs-bleed-left-top", CSSValueToString(bleedverso.top));
28794 bleedRightVerso = this.createVariable("--pagedjs-bleed-left-right", CSSValueToString(bleedverso.right));
28795 bleedBottomVerso = this.createVariable("--pagedjs-bleed-left-bottom", CSSValueToString(bleedverso.bottom));
28796 bleedLeftVerso = this.createVariable("--pagedjs-bleed-left-left", CSSValueToString(bleedverso.left));
28797
28798 widthStringLeft = `calc( ${CSSValueToString(width)} + ${CSSValueToString(bleedverso.left)} + ${CSSValueToString(bleedverso.right)} )`;
28799 heightStringLeft = `calc( ${CSSValueToString(height)} + ${CSSValueToString(bleedverso.top)} + ${CSSValueToString(bleedverso.bottom)} )`;
28800 }
28801
28802 let pageWidthVar = this.createVariable("--pagedjs-width", CSSValueToString(width));
28803 let pageHeightVar = this.createVariable("--pagedjs-height", CSSValueToString(height));
28804
28805 rules.push(
28806 bleedTop,
28807 bleedRight,
28808 bleedBottom,
28809 bleedLeft,
28810 bleedTopRecto,
28811 bleedRightRecto,
28812 bleedBottomRecto,
28813 bleedLeftRecto,
28814 bleedTopVerso,
28815 bleedRightVerso,
28816 bleedBottomVerso,
28817 bleedLeftVerso,
28818 pageWidthVar,
28819 pageHeightVar
28820 );
28821 }
28822
28823 if (marks) {
28824 marks.forEach((mark) => {
28825 let markDisplay = this.createVariable("--pagedjs-mark-" + mark + "-display", "block");
28826 rules.push(markDisplay);
28827 });
28828 }
28829
28830 // orientation variable
28831 if (orientation) {
28832 let oVar = this.createVariable("--pagedjs-orientation", orientation);
28833 rules.push(oVar);
28834
28835 if (orientation !== "portrait") {
28836 // reverse for orientation
28837 [widthString, heightString] = [heightString, widthString];
28838 [widthStringRight, heightStringRight] = [heightStringRight, widthStringRight];
28839 [widthStringLeft, heightStringLeft] = [heightStringLeft, widthStringLeft];
28840 }
28841 }
28842
28843 let wVar = this.createVariable("--pagedjs-width", widthString);
28844 let hVar = this.createVariable("--pagedjs-height", heightString);
28845
28846 let wVarR = this.createVariable("--pagedjs-width-right", widthStringRight);
28847 let hVarR = this.createVariable("--pagedjs-height-right", heightStringRight);
28848
28849 let wVarL = this.createVariable("--pagedjs-width-left", widthStringLeft);
28850 let hVarL = this.createVariable("--pagedjs-height-left", heightStringLeft);
28851
28852 rules.push(wVar, hVar, wVarR, hVarR, wVarL, hVarL);
28853
28854 let rule = this.createRule(selectors, rules);
28855
28856 ast.children.appendData(rule);
28857 }
28858
28859
28860 addNotesStyles(notes, page, list, item, sheet) {
28861
28862 for (const note in notes) {
28863 let selectors = this.selectorsForPage(page);
28864
28865 selectors.insertData({
28866 type: "Combinator",
28867 name: " "
28868 });
28869
28870 selectors.insertData({
28871 type: "ClassSelector",
28872 name: "pagedjs_" + note + "_content"
28873 });
28874
28875 let notesRule = this.createRule(selectors, notes[note]);
28876
28877 list.appendData(notesRule);
28878 }
28879
28880 }
28881
28882 /*
28883 @page {
28884 size: var(--pagedjs-width) var(--pagedjs-height);
28885 margin: 0;
28886 padding: 0;
28887 }
28888 */
28889 addRootPage(ast, size, bleed, bleedrecto, bleedverso) {
28890 let { width, height, orientation, format } = size;
28891 let children = new csstree.List();
28892 let childrenLeft = new csstree.List();
28893 let childrenRight = new csstree.List();
28894 let dimensions = new csstree.List();
28895 let dimensionsLeft = new csstree.List();
28896 let dimensionsRight = new csstree.List();
28897
28898 if (bleed) {
28899 let widthCalculations = new csstree.List();
28900 let heightCalculations = new csstree.List();
28901
28902 // width
28903 widthCalculations.appendData({
28904 type: "Dimension",
28905 unit: width.unit,
28906 value: width.value
28907 });
28908
28909 widthCalculations.appendData({
28910 type: "WhiteSpace",
28911 value: " "
28912 });
28913
28914 widthCalculations.appendData({
28915 type: "Operator",
28916 value: "+"
28917 });
28918
28919 widthCalculations.appendData({
28920 type: "WhiteSpace",
28921 value: " "
28922 });
28923
28924 widthCalculations.appendData({
28925 type: "Dimension",
28926 unit: bleed.left.unit,
28927 value: bleed.left.value
28928 });
28929
28930 widthCalculations.appendData({
28931 type: "WhiteSpace",
28932 value: " "
28933 });
28934
28935 widthCalculations.appendData({
28936 type: "Operator",
28937 value: "+"
28938 });
28939
28940 widthCalculations.appendData({
28941 type: "WhiteSpace",
28942 value: " "
28943 });
28944
28945 widthCalculations.appendData({
28946 type: "Dimension",
28947 unit: bleed.right.unit,
28948 value: bleed.right.value
28949 });
28950
28951 // height
28952 heightCalculations.appendData({
28953 type: "Dimension",
28954 unit: height.unit,
28955 value: height.value
28956 });
28957
28958 heightCalculations.appendData({
28959 type: "WhiteSpace",
28960 value: " "
28961 });
28962
28963 heightCalculations.appendData({
28964 type: "Operator",
28965 value: "+"
28966 });
28967
28968 heightCalculations.appendData({
28969 type: "WhiteSpace",
28970 value: " "
28971 });
28972
28973 heightCalculations.appendData({
28974 type: "Dimension",
28975 unit: bleed.top.unit,
28976 value: bleed.top.value
28977 });
28978
28979 heightCalculations.appendData({
28980 type: "WhiteSpace",
28981 value: " "
28982 });
28983
28984 heightCalculations.appendData({
28985 type: "Operator",
28986 value: "+"
28987 });
28988
28989 heightCalculations.appendData({
28990 type: "WhiteSpace",
28991 value: " "
28992 });
28993
28994 heightCalculations.appendData({
28995 type: "Dimension",
28996 unit: bleed.bottom.unit,
28997 value: bleed.bottom.value
28998 });
28999
29000 dimensions.appendData({
29001 type: "Function",
29002 name: "calc",
29003 children: widthCalculations
29004 });
29005
29006 dimensions.appendData({
29007 type: "WhiteSpace",
29008 value: " "
29009 });
29010
29011 dimensions.appendData({
29012 type: "Function",
29013 name: "calc",
29014 children: heightCalculations
29015 });
29016
29017 } else if (format) {
29018 dimensions.appendData({
29019 type: "Identifier",
29020 name: format
29021 });
29022
29023 if (orientation) {
29024 dimensions.appendData({
29025 type: "WhiteSpace",
29026 value: " "
29027 });
29028
29029 dimensions.appendData({
29030 type: "Identifier",
29031 name: orientation
29032 });
29033 }
29034 } else {
29035 dimensions.appendData({
29036 type: "Dimension",
29037 unit: width.unit,
29038 value: width.value
29039 });
29040
29041 dimensions.appendData({
29042 type: "WhiteSpace",
29043 value: " "
29044 });
29045
29046 dimensions.appendData({
29047 type: "Dimension",
29048 unit: height.unit,
29049 value: height.value
29050 });
29051 }
29052
29053 children.appendData({
29054 type: "Declaration",
29055 property: "size",
29056 loc: null,
29057 value: {
29058 type: "Value",
29059 children: dimensions
29060 }
29061 });
29062
29063 children.appendData({
29064 type: "Declaration",
29065 property: "margin",
29066 loc: null,
29067 value: {
29068 type: "Value",
29069 children: [{
29070 type: "Dimension",
29071 unit: "px",
29072 value: 0
29073 }]
29074 }
29075 });
29076
29077 children.appendData({
29078 type: "Declaration",
29079 property: "padding",
29080 loc: null,
29081 value: {
29082 type: "Value",
29083 children: [{
29084 type: "Dimension",
29085 unit: "px",
29086 value: 0
29087 }]
29088 }
29089 });
29090
29091 children.appendData({
29092 type: "Declaration",
29093 property: "padding",
29094 loc: null,
29095 value: {
29096 type: "Value",
29097 children: [{
29098 type: "Dimension",
29099 unit: "px",
29100 value: 0
29101 }]
29102 }
29103 });
29104
29105 let rule = ast.children.createItem({
29106 type: "Atrule",
29107 prelude: null,
29108 name: "page",
29109 block: {
29110 type: "Block",
29111 loc: null,
29112 children: children
29113 }
29114 });
29115
29116 ast.children.append(rule);
29117
29118 if (bleedverso) {
29119 let widthCalculationsLeft = new csstree.List();
29120 let heightCalculationsLeft = new csstree.List();
29121
29122 // width
29123 widthCalculationsLeft.appendData({
29124 type: "Dimension",
29125 unit: width.unit,
29126 value: width.value
29127 });
29128
29129 widthCalculationsLeft.appendData({
29130 type: "WhiteSpace",
29131 value: " "
29132 });
29133
29134 widthCalculationsLeft.appendData({
29135 type: "Operator",
29136 value: "+"
29137 });
29138
29139 widthCalculationsLeft.appendData({
29140 type: "WhiteSpace",
29141 value: " "
29142 });
29143
29144 widthCalculationsLeft.appendData({
29145 type: "Dimension",
29146 unit: bleedverso.left.unit,
29147 value: bleedverso.left.value
29148 });
29149
29150 widthCalculationsLeft.appendData({
29151 type: "WhiteSpace",
29152 value: " "
29153 });
29154
29155 widthCalculationsLeft.appendData({
29156 type: "Operator",
29157 value: "+"
29158 });
29159
29160 widthCalculationsLeft.appendData({
29161 type: "WhiteSpace",
29162 value: " "
29163 });
29164
29165 widthCalculationsLeft.appendData({
29166 type: "Dimension",
29167 unit: bleedverso.right.unit,
29168 value: bleedverso.right.value
29169 });
29170
29171 // height
29172 heightCalculationsLeft.appendData({
29173 type: "Dimension",
29174 unit: height.unit,
29175 value: height.value
29176 });
29177
29178 heightCalculationsLeft.appendData({
29179 type: "WhiteSpace",
29180 value: " "
29181 });
29182
29183 heightCalculationsLeft.appendData({
29184 type: "Operator",
29185 value: "+"
29186 });
29187
29188 heightCalculationsLeft.appendData({
29189 type: "WhiteSpace",
29190 value: " "
29191 });
29192
29193 heightCalculationsLeft.appendData({
29194 type: "Dimension",
29195 unit: bleedverso.top.unit,
29196 value: bleedverso.top.value
29197 });
29198
29199 heightCalculationsLeft.appendData({
29200 type: "WhiteSpace",
29201 value: " "
29202 });
29203
29204 heightCalculationsLeft.appendData({
29205 type: "Operator",
29206 value: "+"
29207 });
29208
29209 heightCalculationsLeft.appendData({
29210 type: "WhiteSpace",
29211 value: " "
29212 });
29213
29214 heightCalculationsLeft.appendData({
29215 type: "Dimension",
29216 unit: bleedverso.bottom.unit,
29217 value: bleedverso.bottom.value
29218 });
29219
29220 dimensionsLeft.appendData({
29221 type: "Function",
29222 name: "calc",
29223 children: widthCalculationsLeft
29224 });
29225
29226 dimensionsLeft.appendData({
29227 type: "WhiteSpace",
29228 value: " "
29229 });
29230
29231 dimensionsLeft.appendData({
29232 type: "Function",
29233 name: "calc",
29234 children: heightCalculationsLeft
29235 });
29236
29237 childrenLeft.appendData({
29238 type: "Declaration",
29239 property: "size",
29240 loc: null,
29241 value: {
29242 type: "Value",
29243 children: dimensionsLeft
29244 }
29245 });
29246
29247 let ruleLeft = ast.children.createItem({
29248 type: "Atrule",
29249 prelude: null,
29250 name: "page :left",
29251 block: {
29252 type: "Block",
29253 loc: null,
29254 children: childrenLeft
29255 }
29256 });
29257
29258 ast.children.append(ruleLeft);
29259
29260 }
29261
29262 if (bleedrecto) {
29263 let widthCalculationsRight = new csstree.List();
29264 let heightCalculationsRight = new csstree.List();
29265
29266 // width
29267 widthCalculationsRight.appendData({
29268 type: "Dimension",
29269 unit: width.unit,
29270 value: width.value
29271 });
29272
29273 widthCalculationsRight.appendData({
29274 type: "WhiteSpace",
29275 value: " "
29276 });
29277
29278 widthCalculationsRight.appendData({
29279 type: "Operator",
29280 value: "+"
29281 });
29282
29283 widthCalculationsRight.appendData({
29284 type: "WhiteSpace",
29285 value: " "
29286 });
29287
29288 widthCalculationsRight.appendData({
29289 type: "Dimension",
29290 unit: bleedrecto.left.unit,
29291 value: bleedrecto.left.value
29292 });
29293
29294 widthCalculationsRight.appendData({
29295 type: "WhiteSpace",
29296 value: " "
29297 });
29298
29299 widthCalculationsRight.appendData({
29300 type: "Operator",
29301 value: "+"
29302 });
29303
29304 widthCalculationsRight.appendData({
29305 type: "WhiteSpace",
29306 value: " "
29307 });
29308
29309 widthCalculationsRight.appendData({
29310 type: "Dimension",
29311 unit: bleedrecto.right.unit,
29312 value: bleedrecto.right.value
29313 });
29314
29315 // height
29316 heightCalculationsRight.appendData({
29317 type: "Dimension",
29318 unit: height.unit,
29319 value: height.value
29320 });
29321
29322 heightCalculationsRight.appendData({
29323 type: "WhiteSpace",
29324 value: " "
29325 });
29326
29327 heightCalculationsRight.appendData({
29328 type: "Operator",
29329 value: "+"
29330 });
29331
29332 heightCalculationsRight.appendData({
29333 type: "WhiteSpace",
29334 value: " "
29335 });
29336
29337 heightCalculationsRight.appendData({
29338 type: "Dimension",
29339 unit: bleedrecto.top.unit,
29340 value: bleedrecto.top.value
29341 });
29342
29343 heightCalculationsRight.appendData({
29344 type: "WhiteSpace",
29345 value: " "
29346 });
29347
29348 heightCalculationsRight.appendData({
29349 type: "Operator",
29350 value: "+"
29351 });
29352
29353 heightCalculationsRight.appendData({
29354 type: "WhiteSpace",
29355 value: " "
29356 });
29357
29358 heightCalculationsRight.appendData({
29359 type: "Dimension",
29360 unit: bleedrecto.bottom.unit,
29361 value: bleedrecto.bottom.value
29362 });
29363
29364 dimensionsRight.appendData({
29365 type: "Function",
29366 name: "calc",
29367 children: widthCalculationsRight
29368 });
29369
29370 dimensionsRight.appendData({
29371 type: "WhiteSpace",
29372 value: " "
29373 });
29374
29375 dimensionsRight.appendData({
29376 type: "Function",
29377 name: "calc",
29378 children: heightCalculationsRight
29379 });
29380
29381 childrenRight.appendData({
29382 type: "Declaration",
29383 property: "size",
29384 loc: null,
29385 value: {
29386 type: "Value",
29387 children: dimensionsRight
29388 }
29389 });
29390
29391 let ruleRight = ast.children.createItem({
29392 type: "Atrule",
29393 prelude: null,
29394 name: "page :right",
29395 block: {
29396 type: "Block",
29397 loc: null,
29398 children: childrenRight
29399 }
29400 });
29401
29402 ast.children.append(ruleRight);
29403
29404 }
29405 }
29406
29407 getNth(nth) {
29408 let n = nth.indexOf("n");
29409 let plus = nth.indexOf("+");
29410 let splitN = nth.split("n");
29411 let splitP = nth.split("+");
29412 let a = null;
29413 let b = null;
29414 if (n > -1) {
29415 a = splitN[0];
29416 if (plus > -1) {
29417 b = splitP[1];
29418 }
29419 } else {
29420 b = nth;
29421 }
29422
29423 return {
29424 type: "Nth",
29425 loc: null,
29426 selector: null,
29427 nth: {
29428 type: "AnPlusB",
29429 loc: null,
29430 a: a,
29431 b: b
29432 }
29433 };
29434 }
29435
29436 addPageAttributes(page, start, pages) {
29437 let namedPages = [start.dataset.page];
29438
29439 if (namedPages && namedPages.length) {
29440 for (const named of namedPages) {
29441 if (!named) {
29442 continue;
29443 }
29444 page.name = named;
29445 page.element.classList.add("pagedjs_named_page");
29446 page.element.classList.add("pagedjs_" + named + "_page");
29447
29448 if (!start.dataset.splitFrom) {
29449 page.element.classList.add("pagedjs_" + named + "_first_page");
29450 }
29451 }
29452 }
29453 }
29454
29455 getStartElement(content, breakToken) {
29456 let node = breakToken && breakToken.node;
29457
29458 if (!content && !breakToken) {
29459 return;
29460 }
29461
29462 // No break
29463 if (!node) {
29464 return content.children[0];
29465 }
29466
29467 // Top level element
29468 if (node.nodeType === 1 && node.parentNode.nodeType === 11) {
29469 return node;
29470 }
29471
29472 // Named page
29473 if (node.nodeType === 1 && node.dataset.page) {
29474 return node;
29475 }
29476
29477 // Get top level Named parent
29478 let fragment = rebuildAncestors(node);
29479 let pages = fragment.querySelectorAll("[data-page]");
29480
29481 if (pages.length) {
29482 return pages[pages.length - 1];
29483 } else {
29484 return fragment.children[0];
29485 }
29486 }
29487
29488 beforePageLayout(page, contents, breakToken, chunker) {
29489 let start = this.getStartElement(contents, breakToken);
29490 if (start) {
29491 this.addPageAttributes(page, start, chunker.pages);
29492 }
29493 // page.element.querySelector('.paged_area').style.color = red;
29494 }
29495
29496 finalizePage(fragment, page, breakToken, chunker) {
29497 for (let m in this.marginalia) {
29498 let margin = this.marginalia[m];
29499 let sels = m.split(" ");
29500
29501 let content;
29502 if (page.element.matches(sels[0]) && margin.hasContent) {
29503 content = page.element.querySelector(sels[1]);
29504 content.classList.add("hasContent");
29505 }
29506 }
29507
29508 // check center
29509 ["top", "bottom"].forEach((loc) => {
29510 let marginGroup = page.element.querySelector(".pagedjs_margin-" + loc);
29511 let center = page.element.querySelector(".pagedjs_margin-" + loc + "-center");
29512 let left = page.element.querySelector(".pagedjs_margin-" + loc + "-left");
29513 let right = page.element.querySelector(".pagedjs_margin-" + loc + "-right");
29514
29515 let centerContent = center.classList.contains("hasContent");
29516 let leftContent = left.classList.contains("hasContent");
29517 let rightContent = right.classList.contains("hasContent");
29518 let centerWidth, leftWidth, rightWidth;
29519
29520 if (leftContent) {
29521 leftWidth = window.getComputedStyle(left)["max-width"];
29522 }
29523
29524 if (rightContent) {
29525 rightWidth = window.getComputedStyle(right)["max-width"];
29526 }
29527
29528
29529 if (centerContent) {
29530 centerWidth = window.getComputedStyle(center)["max-width"];
29531
29532 if (centerWidth === "none" || centerWidth === "auto") {
29533 if (!leftContent && !rightContent) {
29534 marginGroup.style["grid-template-columns"] = "0 1fr 0";
29535 } else if (leftContent) {
29536 if (!rightContent) {
29537 if (leftWidth !== "none" && leftWidth !== "auto") {
29538 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + leftWidth;
29539 } else {
29540 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
29541 left.style["white-space"] = "nowrap";
29542 center.style["white-space"] = "nowrap";
29543 let leftOuterWidth = left.offsetWidth;
29544 let centerOuterWidth = center.offsetWidth;
29545 let outerwidths = leftOuterWidth + centerOuterWidth;
29546 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
29547 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
29548 left.style["white-space"] = "normal";
29549 center.style["white-space"] = "normal";
29550 }
29551 } else {
29552 if (leftWidth !== "none" && leftWidth !== "auto") {
29553 if (rightWidth !== "none" && rightWidth !== "auto") {
29554 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + rightWidth;
29555 } else {
29556 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + leftWidth;
29557 }
29558 } else {
29559 if (rightWidth !== "none" && rightWidth !== "auto") {
29560 marginGroup.style["grid-template-columns"] = rightWidth + " 1fr " + rightWidth;
29561 } else {
29562 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
29563 left.style["white-space"] = "nowrap";
29564 center.style["white-space"] = "nowrap";
29565 right.style["white-space"] = "nowrap";
29566 let leftOuterWidth = left.offsetWidth;
29567 let centerOuterWidth = center.offsetWidth;
29568 let rightOuterWidth = right.offsetWidth;
29569 let outerwidths = leftOuterWidth + centerOuterWidth + rightOuterWidth;
29570 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
29571 if (newcenterWidth > 40) {
29572 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
29573 } else {
29574 marginGroup.style["grid-template-columns"] = "repeat(3, 1fr)";
29575 }
29576 left.style["white-space"] = "normal";
29577 center.style["white-space"] = "normal";
29578 right.style["white-space"] = "normal";
29579 }
29580 }
29581 }
29582 } else {
29583 if (rightWidth !== "none" && rightWidth !== "auto") {
29584 marginGroup.style["grid-template-columns"] = rightWidth + " 1fr " + rightWidth;
29585 } else {
29586 marginGroup.style["grid-template-columns"] = "auto auto 1fr";
29587 right.style["white-space"] = "nowrap";
29588 center.style["white-space"] = "nowrap";
29589 let rightOuterWidth = right.offsetWidth;
29590 let centerOuterWidth = center.offsetWidth;
29591 let outerwidths = rightOuterWidth + centerOuterWidth;
29592 let newcenterWidth = centerOuterWidth * 100 / outerwidths;
29593 marginGroup.style["grid-template-columns"] = "minmax(16.66%, 1fr) minmax(33%, " + newcenterWidth + "%) minmax(16.66%, 1fr)";
29594 right.style["white-space"] = "normal";
29595 center.style["white-space"] = "normal";
29596 }
29597 }
29598 } else if (centerWidth !== "none" && centerWidth !== "auto") {
29599 if (leftContent && leftWidth !== "none" && leftWidth !== "auto") {
29600 marginGroup.style["grid-template-columns"] = leftWidth + " " + centerWidth + " 1fr";
29601 } else if (rightContent && rightWidth !== "none" && rightWidth !== "auto") {
29602 marginGroup.style["grid-template-columns"] = "1fr " + centerWidth + " " + rightWidth;
29603 } else {
29604 marginGroup.style["grid-template-columns"] = "1fr " + centerWidth + " 1fr";
29605 }
29606
29607 }
29608
29609 } else {
29610 if (leftContent) {
29611 if (!rightContent) {
29612 marginGroup.style["grid-template-columns"] = "1fr 0 0";
29613 } else {
29614 if (leftWidth !== "none" && leftWidth !== "auto") {
29615 if (rightWidth !== "none" && rightWidth !== "auto") {
29616 marginGroup.style["grid-template-columns"] = leftWidth + " 1fr " + rightWidth;
29617 } else {
29618 marginGroup.style["grid-template-columns"] = leftWidth + " 0 1fr";
29619 }
29620 } else {
29621 if (rightWidth !== "none" && rightWidth !== "auto") {
29622 marginGroup.style["grid-template-columns"] = "1fr 0 " + rightWidth;
29623 } else {
29624 marginGroup.style["grid-template-columns"] = "auto 1fr auto";
29625 left.style["white-space"] = "nowrap";
29626 right.style["white-space"] = "nowrap";
29627 let leftOuterWidth = left.offsetWidth;
29628 let rightOuterWidth = right.offsetWidth;
29629 let outerwidths = leftOuterWidth + rightOuterWidth;
29630 let newLeftWidth = leftOuterWidth * 100 / outerwidths;
29631 marginGroup.style["grid-template-columns"] = "minmax(16.66%, " + newLeftWidth + "%) 0 1fr";
29632 left.style["white-space"] = "normal";
29633 right.style["white-space"] = "normal";
29634 }
29635 }
29636 }
29637 } else {
29638 if (rightWidth !== "none" && rightWidth !== "auto") {
29639 marginGroup.style["grid-template-columns"] = "1fr 0 " + rightWidth;
29640 } else {
29641 marginGroup.style["grid-template-columns"] = "0 0 1fr";
29642 }
29643 }
29644 }
29645 });
29646
29647 // check middle
29648 ["left", "right"].forEach((loc) => {
29649 let middle = page.element.querySelector(".pagedjs_margin-" + loc + "-middle.hasContent");
29650 let marginGroup = page.element.querySelector(".pagedjs_margin-" + loc);
29651 let top = page.element.querySelector(".pagedjs_margin-" + loc + "-top");
29652 let bottom = page.element.querySelector(".pagedjs_margin-" + loc + "-bottom");
29653 let topContent = top.classList.contains("hasContent");
29654 let bottomContent = bottom.classList.contains("hasContent");
29655 let middleHeight, topHeight, bottomHeight;
29656
29657 if (topContent) {
29658 topHeight = window.getComputedStyle(top)["max-height"];
29659 }
29660
29661 if (bottomContent) {
29662 bottomHeight = window.getComputedStyle(bottom)["max-height"];
29663 }
29664
29665 if (middle) {
29666 middleHeight = window.getComputedStyle(middle)["max-height"];
29667
29668 if (middleHeight === "none" || middleHeight === "auto") {
29669 if (!topContent && !bottomContent) {
29670 marginGroup.style["grid-template-rows"] = "0 1fr 0";
29671 } else if (topContent) {
29672 if (!bottomContent) {
29673 if (topHeight !== "none" && topHeight !== "auto") {
29674 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + "*2) " + topHeight;
29675 }
29676 } else {
29677 if (topHeight !== "none" && topHeight !== "auto") {
29678 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29679 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + " - " + bottomHeight + ") " + bottomHeight;
29680 } else {
29681 marginGroup.style["grid-template-rows"] = topHeight + " calc(100% - " + topHeight + "*2) " + topHeight;
29682 }
29683 } else {
29684 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29685 marginGroup.style["grid-template-rows"] = bottomHeight + " calc(100% - " + bottomHeight + "*2) " + bottomHeight;
29686 }
29687 }
29688 }
29689 } else {
29690 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29691 marginGroup.style["grid-template-rows"] = bottomHeight + " calc(100% - " + bottomHeight + "*2) " + bottomHeight;
29692 }
29693 }
29694 } else {
29695 if (topContent && topHeight !== "none" && topHeight !== "auto") {
29696 marginGroup.style["grid-template-rows"] = topHeight + " " + middleHeight + " calc(100% - (" + topHeight + " + " + middleHeight + "))";
29697 } else if (bottomContent && bottomHeight !== "none" && bottomHeight !== "auto") {
29698 marginGroup.style["grid-template-rows"] = "1fr " + middleHeight + " " + bottomHeight;
29699 } else {
29700 marginGroup.style["grid-template-rows"] = "calc((100% - " + middleHeight + ")/2) " + middleHeight + " calc((100% - " + middleHeight + ")/2)";
29701 }
29702
29703 }
29704
29705 } else {
29706 if (topContent) {
29707 if (!bottomContent) {
29708 marginGroup.style["grid-template-rows"] = "1fr 0 0";
29709 } else {
29710 if (topHeight !== "none" && topHeight !== "auto") {
29711 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29712 marginGroup.style["grid-template-rows"] = topHeight + " 1fr " + bottomHeight;
29713 } else {
29714 marginGroup.style["grid-template-rows"] = topHeight + " 0 1fr";
29715 }
29716 } else {
29717 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29718 marginGroup.style["grid-template-rows"] = "1fr 0 " + bottomHeight;
29719 } else {
29720 marginGroup.style["grid-template-rows"] = "1fr 0 1fr";
29721 }
29722 }
29723 }
29724 } else {
29725 if (bottomHeight !== "none" && bottomHeight !== "auto") {
29726 marginGroup.style["grid-template-rows"] = "1fr 0 " + bottomHeight;
29727 } else {
29728 marginGroup.style["grid-template-rows"] = "0 0 1fr";
29729 }
29730 }
29731 }
29732
29733
29734
29735 });
29736
29737 }
29738
29739 // CSS Tree Helpers
29740
29741 selectorsForPage(page) {
29742 let nthlist;
29743 let nth;
29744
29745 let selectors = new csstree.List();
29746
29747 selectors.insertData({
29748 type: "ClassSelector",
29749 name: "pagedjs_page"
29750 });
29751
29752 // Named page
29753 if (page.name) {
29754 selectors.insertData({
29755 type: "ClassSelector",
29756 name: "pagedjs_named_page"
29757 });
29758
29759 selectors.insertData({
29760 type: "ClassSelector",
29761 name: "pagedjs_" + page.name + "_page"
29762 });
29763 }
29764
29765 // PsuedoSelector
29766 if (page.psuedo && !(page.name && page.psuedo === "first")) {
29767 selectors.insertData({
29768 type: "ClassSelector",
29769 name: "pagedjs_" + page.psuedo + "_page"
29770 });
29771 }
29772
29773 if (page.name && page.psuedo === "first") {
29774 selectors.insertData({
29775 type: "ClassSelector",
29776 name: "pagedjs_" + page.name + "_" + page.psuedo + "_page"
29777 });
29778 }
29779
29780 // Nth
29781 if (page.nth) {
29782 nthlist = new csstree.List();
29783 nth = this.getNth(page.nth);
29784
29785 nthlist.insertData(nth);
29786
29787 selectors.insertData({
29788 type: "PseudoClassSelector",
29789 name: "nth-of-type",
29790 children: nthlist
29791 });
29792 }
29793
29794 return selectors;
29795 }
29796
29797 selectorsForPageMargin(page, margin) {
29798 let selectors = this.selectorsForPage(page);
29799
29800 selectors.insertData({
29801 type: "Combinator",
29802 name: " "
29803 });
29804
29805 selectors.insertData({
29806 type: "ClassSelector",
29807 name: "pagedjs_margin-" + margin
29808 });
29809
29810 return selectors;
29811 }
29812
29813 createDeclaration(property, value, important) {
29814 let children = new csstree.List();
29815
29816 children.insertData({
29817 type: "Identifier",
29818 loc: null,
29819 name: value
29820 });
29821
29822 return {
29823 type: "Declaration",
29824 loc: null,
29825 important: important,
29826 property: property,
29827 value: {
29828 type: "Value",
29829 loc: null,
29830 children: children
29831 }
29832 };
29833 }
29834
29835 createVariable(property, value) {
29836 return {
29837 type: "Declaration",
29838 loc: null,
29839 property: property,
29840 value: {
29841 type: "Raw",
29842 value: value
29843 }
29844 };
29845 }
29846
29847 createCalculatedDimension(property, items, important, operator = "+") {
29848 let children = new csstree.List();
29849 let calculations = new csstree.List();
29850
29851 items.forEach((item, index) => {
29852 calculations.appendData({
29853 type: "Dimension",
29854 unit: item.unit,
29855 value: item.value
29856 });
29857
29858 calculations.appendData({
29859 type: "WhiteSpace",
29860 value: " "
29861 });
29862
29863 if (index + 1 < items.length) {
29864 calculations.appendData({
29865 type: "Operator",
29866 value: operator
29867 });
29868
29869 calculations.appendData({
29870 type: "WhiteSpace",
29871 value: " "
29872 });
29873 }
29874 });
29875
29876 children.insertData({
29877 type: "Function",
29878 loc: null,
29879 name: "calc",
29880 children: calculations
29881 });
29882
29883 return {
29884 type: "Declaration",
29885 loc: null,
29886 important: important,
29887 property: property,
29888 value: {
29889 type: "Value",
29890 loc: null,
29891 children: children
29892 }
29893 };
29894 }
29895
29896 createDimension(property, cssValue, important) {
29897 let children = new csstree.List();
29898
29899 children.insertData({
29900 type: "Dimension",
29901 loc: null,
29902 value: cssValue.value,
29903 unit: cssValue.unit
29904 });
29905
29906 return {
29907 type: "Declaration",
29908 loc: null,
29909 important: important,
29910 property: property,
29911 value: {
29912 type: "Value",
29913 loc: null,
29914 children: children
29915 }
29916 };
29917 }
29918
29919 createBlock(declarations) {
29920 let block = new csstree.List();
29921
29922 declarations.forEach((declaration) => {
29923 block.insertData(declaration);
29924 });
29925
29926 return {
29927 type: "Block",
29928 loc: null,
29929 children: block
29930 };
29931 }
29932
29933 createRule(selectors, block) {
29934 let selectorList = new csstree.List();
29935 selectorList.insertData({
29936 type: "Selector",
29937 children: selectors
29938 });
29939
29940 if (Array.isArray(block)) {
29941 block = this.createBlock(block);
29942 }
29943
29944 return {
29945 type: "Rule",
29946 prelude: {
29947 type: "SelectorList",
29948 children: selectorList
29949 },
29950 block: block
29951 };
29952 }
29953
29954}
29955
29956class Breaks extends Handler {
29957 constructor(chunker, polisher, caller) {
29958 super(chunker, polisher, caller);
29959
29960 this.breaks = {};
29961 }
29962
29963 onDeclaration(declaration, dItem, dList, rule) {
29964 let property = declaration.property;
29965
29966 if (property === "page") {
29967 let children = declaration.value.children.first();
29968 let value = children.name;
29969 let selector = csstree.generate(rule.ruleNode.prelude);
29970 let name = value;
29971
29972 let breaker = {
29973 property: property,
29974 value: value,
29975 selector: selector,
29976 name: name
29977 };
29978
29979 selector.split(",").forEach((s) => {
29980 if (!this.breaks[s]) {
29981 this.breaks[s] = [breaker];
29982 } else {
29983 this.breaks[s].push(breaker);
29984 }
29985 });
29986
29987 dList.remove(dItem);
29988 }
29989
29990 if (property === "break-before" ||
29991 property === "break-after" ||
29992 property === "page-break-before" ||
29993 property === "page-break-after"
29994 ) {
29995 let child = declaration.value.children.first();
29996 let value = child.name;
29997 let selector = csstree.generate(rule.ruleNode.prelude);
29998
29999 if (property === "page-break-before") {
30000 property = "break-before";
30001 } else if (property === "page-break-after") {
30002 property = "break-after";
30003 }
30004
30005 let breaker = {
30006 property: property,
30007 value: value,
30008 selector: selector
30009 };
30010
30011 selector.split(",").forEach((s) => {
30012 if (!this.breaks[s]) {
30013 this.breaks[s] = [breaker];
30014 } else {
30015 this.breaks[s].push(breaker);
30016 }
30017 });
30018
30019 // Remove from CSS -- handle right / left in module
30020 dList.remove(dItem);
30021 }
30022 }
30023
30024 afterParsed(parsed) {
30025 this.processBreaks(parsed, this.breaks);
30026 }
30027
30028 processBreaks(parsed, breaks) {
30029 for (let b in breaks) {
30030 // Find elements
30031 let elements = parsed.querySelectorAll(b);
30032 // Add break data
30033 for (var i = 0; i < elements.length; i++) {
30034 for (let prop of breaks[b]) {
30035
30036 if (prop.property === "break-after") {
30037 let nodeAfter = displayedElementAfter(elements[i], parsed);
30038
30039 elements[i].setAttribute("data-break-after", prop.value);
30040
30041 if (nodeAfter) {
30042 nodeAfter.setAttribute("data-previous-break-after", prop.value);
30043 }
30044 } else if (prop.property === "break-before") {
30045 let nodeBefore = displayedElementBefore(elements[i], parsed);
30046
30047 // Breaks are only allowed between siblings, not between a box and its container.
30048 // If we cannot find a node before we should not break!
30049 // https://drafts.csswg.org/css-break-3/#break-propagation
30050 if (nodeBefore) {
30051 if (prop.value === "page" && needsPageBreak(elements[i], nodeBefore)) {
30052 // we ignore this explicit page break because an implicit page break is already needed
30053 continue;
30054 }
30055 elements[i].setAttribute("data-break-before", prop.value);
30056 nodeBefore.setAttribute("data-next-break-before", prop.value);
30057 }
30058 } else if (prop.property === "page") {
30059 elements[i].setAttribute("data-page", prop.value);
30060
30061 let nodeAfter = displayedElementAfter(elements[i], parsed);
30062
30063 if (nodeAfter) {
30064 nodeAfter.setAttribute("data-after-page", prop.value);
30065 }
30066 } else {
30067 elements[i].setAttribute("data-" + prop.property, prop.value);
30068 }
30069 }
30070 }
30071 }
30072 }
30073
30074 mergeBreaks(pageBreaks, newBreaks) {
30075 for (let b in newBreaks) {
30076 if (b in pageBreaks) {
30077 pageBreaks[b] = pageBreaks[b].concat(newBreaks[b]);
30078 } else {
30079 pageBreaks[b] = newBreaks[b];
30080 }
30081 }
30082 return pageBreaks;
30083 }
30084
30085 addBreakAttributes(pageElement, page) {
30086 let before = pageElement.querySelector("[data-break-before]");
30087 let after = pageElement.querySelector("[data-break-after]");
30088 let previousBreakAfter = pageElement.querySelector("[data-previous-break-after]");
30089
30090 if (before) {
30091 if (before.dataset.splitFrom) {
30092 page.splitFrom = before.dataset.splitFrom;
30093 pageElement.setAttribute("data-split-from", before.dataset.splitFrom);
30094 } else if (before.dataset.breakBefore && before.dataset.breakBefore !== "avoid") {
30095 page.breakBefore = before.dataset.breakBefore;
30096 pageElement.setAttribute("data-break-before", before.dataset.breakBefore);
30097 }
30098 }
30099
30100 if (after && after.dataset) {
30101 if (after.dataset.splitTo) {
30102 page.splitTo = after.dataset.splitTo;
30103 pageElement.setAttribute("data-split-to", after.dataset.splitTo);
30104 } else if (after.dataset.breakAfter && after.dataset.breakAfter !== "avoid") {
30105 page.breakAfter = after.dataset.breakAfter;
30106 pageElement.setAttribute("data-break-after", after.dataset.breakAfter);
30107 }
30108 }
30109
30110 if (previousBreakAfter && previousBreakAfter.dataset) {
30111 if (previousBreakAfter.dataset.previousBreakAfter && previousBreakAfter.dataset.previousBreakAfter !== "avoid") {
30112 page.previousBreakAfter = previousBreakAfter.dataset.previousBreakAfter;
30113 }
30114 }
30115 }
30116
30117 afterPageLayout(pageElement, page) {
30118 this.addBreakAttributes(pageElement, page);
30119 }
30120}
30121
30122class PrintMedia extends Handler {
30123 constructor(chunker, polisher, caller) {
30124 super(chunker, polisher, caller);
30125 }
30126
30127 onAtMedia(node, item, list) {
30128 let media = this.getMediaName(node);
30129 let rules;
30130 if (media.includes("print")) {
30131 rules = node.block.children;
30132
30133 // Append rules to the end of main rules list
30134 // TODO: this isn't working right, needs to check what is in the prelude
30135 /*
30136 rules.forEach((selectList) => {
30137 if (selectList.prelude) {
30138 selectList.prelude.children.forEach((rule) => {
30139
30140 rule.children.prependData({
30141 type: "Combinator",
30142 name: " "
30143 });
30144
30145 rule.children.prependData({
30146 type: "ClassSelector",
30147 name: "pagedjs_page"
30148 });
30149 });
30150 }
30151 });
30152
30153 list.insertList(rules, item);
30154 */
30155
30156 // Append rules to the end of main rules list
30157 list.appendList(rules);
30158
30159 // Remove rules from the @media block
30160 list.remove(item);
30161 } else if (!media.includes("all") && !media.includes("pagedjs-ignore")) {
30162 list.remove(item);
30163 }
30164
30165 }
30166
30167 getMediaName(node) {
30168 let media = [];
30169
30170 if (typeof node.prelude === "undefined" ||
30171 node.prelude.type !== "AtrulePrelude" ) {
30172 return;
30173 }
30174
30175 csstree.walk(node.prelude, {
30176 visit: "Identifier",
30177 enter: (identNode, iItem, iList) => {
30178 media.push(identNode.name);
30179 }
30180 });
30181 return media;
30182 }
30183
30184
30185}
30186
30187class Splits extends Handler {
30188 constructor(chunker, polisher, caller) {
30189 super(chunker, polisher, caller);
30190 }
30191
30192 afterPageLayout(pageElement, page, breakToken, chunker) {
30193 let splits = Array.from(pageElement.querySelectorAll("[data-split-from]"));
30194 let pages = pageElement.parentNode;
30195 let index = Array.prototype.indexOf.call(pages.children, pageElement);
30196 let prevPage;
30197
30198 if (index === 0) {
30199 return;
30200 }
30201
30202 prevPage = pages.children[index - 1];
30203
30204 let from; // Capture the last from element
30205 splits.forEach((split) => {
30206 let ref = split.dataset.ref;
30207 from = prevPage.querySelector("[data-ref='"+ ref +"']:not([data-split-to])");
30208
30209 if (from) {
30210 from.dataset.splitTo = ref;
30211
30212 if (!from.dataset.splitFrom) {
30213 from.dataset.splitOriginal = true;
30214 }
30215 }
30216 });
30217
30218 // Fix alignment on the deepest split element
30219 if (from) {
30220 this.handleAlignment(from);
30221 }
30222 }
30223
30224 handleAlignment(node) {
30225 let styles = window.getComputedStyle(node);
30226 let align = styles["text-align"];
30227 let alignLast = styles["text-align-last"];
30228 node.dataset.lastSplitElement = "true";
30229 if (align === "justify" && alignLast === "auto") {
30230 node.dataset.alignLastSplitElement = "justify";
30231 } else {
30232 node.dataset.alignLastSplitElement = alignLast;
30233 }
30234 }
30235
30236}
30237
30238class Counters extends Handler {
30239 constructor(chunker, polisher, caller) {
30240 super(chunker, polisher, caller);
30241
30242 this.styleSheet = polisher.styleSheet;
30243 this.counters = {};
30244 this.resetCountersMap = new Map();
30245 }
30246
30247 onDeclaration(declaration, dItem, dList, rule) {
30248 let property = declaration.property;
30249
30250 if (property === "counter-increment") {
30251 this.handleIncrement(declaration, rule);
30252 // clean up empty declaration
30253 let hasProperities = false;
30254 declaration.value.children.forEach((data) => {
30255 if (data.type && data.type !== "WhiteSpace") {
30256 hasProperities = true;
30257 }
30258 });
30259 if (!hasProperities) {
30260 dList.remove(dItem);
30261 }
30262 } else if (property === "counter-reset") {
30263 this.handleReset(declaration, rule);
30264 // clean up empty declaration
30265 let hasProperities = false;
30266 declaration.value.children.forEach((data) => {
30267 if (data.type && data.type !== "WhiteSpace") {
30268 hasProperities = true;
30269 }
30270 });
30271 if (!hasProperities) {
30272 dList.remove(dItem);
30273 }
30274 }
30275 }
30276
30277 afterParsed(parsed) {
30278 this.processCounters(parsed, this.counters);
30279 this.scopeCounters(this.counters);
30280 }
30281
30282 addCounter(name) {
30283 if (name in this.counters) {
30284 return this.counters[name];
30285 }
30286
30287 this.counters[name] = {
30288 name: name,
30289 increments: {},
30290 resets: {}
30291 };
30292
30293 return this.counters[name];
30294 }
30295
30296 handleIncrement(declaration, rule) {
30297 let increments = [];
30298 let children = declaration.value.children;
30299
30300 children.forEach((data, item) => {
30301 if (data.type && data.type === "Identifier") {
30302 let name = data.name;
30303
30304 if (name === "page" || name.indexOf("target-counter-") === 0) {
30305 return;
30306 }
30307
30308 let whitespace, number, value;
30309 if (item.next && item.next.data.type === "WhiteSpace") {
30310 whitespace = item.next;
30311 }
30312 if (whitespace && whitespace.next && whitespace.next.data.type === "Number") {
30313 number = whitespace.next;
30314 value = parseInt(number.data.value);
30315 }
30316
30317 let selector = csstree.generate(rule.ruleNode.prelude);
30318
30319 let counter;
30320 if (!(name in this.counters)) {
30321 counter = this.addCounter(name);
30322 } else {
30323 counter = this.counters[name];
30324 }
30325 let increment = {
30326 selector: selector,
30327 number: value || 1
30328 };
30329 counter.increments[selector] = increment;
30330 increments.push(increment);
30331
30332 // Remove the parsed resets
30333 children.remove(item);
30334 if (whitespace) {
30335 children.remove(whitespace);
30336 }
30337 if (number) {
30338 children.remove(number);
30339 }
30340 }
30341 });
30342
30343 return increments;
30344 }
30345
30346 handleReset(declaration, rule) {
30347 let children = declaration.value.children;
30348
30349 children.forEach((data, item) => {
30350 if (data.type && data.type === "Identifier") {
30351 let name = data.name;
30352 let whitespace, number, value;
30353 if (item.next && item.next.data.type === "WhiteSpace") {
30354 whitespace = item.next;
30355 }
30356 if (whitespace && whitespace.next) {
30357 if (whitespace.next.data.type === "Number") {
30358 // The counter reset value is specified using a number. E.g. counter-reset: c2 5;
30359 number = whitespace.next;
30360 value = parseInt(number.data.value);
30361 } else if (whitespace.next.data.type === "Function" && whitespace.next.data.name === "var") {
30362 // The counter reset value is specified using a CSS variable (custom property).
30363 // E.g. counter-reset: c2 var(--my-variable);
30364 // See https://developer.mozilla.org/en-US/docs/Web/CSS/var
30365 number = whitespace.next;
30366 // Use the variable name (e.g. '--my-variable') as value for now. The actual value is resolved later by the
30367 // processCounterResets function.
30368 value = whitespace.next.data.children.head.data.name;
30369 }
30370 }
30371
30372 let counter;
30373 let selector;
30374 let prelude = rule.ruleNode.prelude;
30375
30376 if (rule.ruleNode.type === "Atrule" && rule.ruleNode.name === "page") {
30377 selector = ".pagedjs_page";
30378 } else {
30379 selector = csstree.generate(prelude || rule.ruleNode);
30380 }
30381
30382 if (name === "footnote") {
30383 this.addFootnoteMarkerCounter(declaration.value.children);
30384 }
30385
30386 if (!(name in this.counters)) {
30387 counter = this.addCounter(name);
30388 } else {
30389 counter = this.counters[name];
30390 }
30391
30392 let reset = {
30393 selector: selector,
30394 number: value || 0
30395 };
30396
30397 counter.resets[selector] = reset;
30398
30399 if (selector !== ".pagedjs_page") {
30400 // Remove the parsed resets
30401 children.remove(item);
30402 if (whitespace) {
30403 children.remove(whitespace);
30404 }
30405 if (number) {
30406 children.remove(number);
30407 }
30408 }
30409 }
30410 });
30411 }
30412
30413 processCounters(parsed, counters) {
30414 let counter;
30415 for (let c in counters) {
30416 counter = this.counters[c];
30417 this.processCounterIncrements(parsed, counter);
30418 this.processCounterResets(parsed, counter);
30419 if (c !== "page") {
30420 this.addCounterValues(parsed, counter);
30421 }
30422 }
30423 }
30424
30425 scopeCounters(counters) {
30426 let countersArray = [];
30427 for (let c in counters) {
30428 if(c !== "page") {
30429 countersArray.push(`${counters[c].name} 0`);
30430 }
30431 }
30432 // Add to pages to allow cross page scope
30433 this.insertRule(`.pagedjs_pages { counter-reset: ${countersArray.join(" ")} page 0 pages var(--pagedjs-page-count) footnote var(--pagedjs-footnotes-count) footnote-marker var(--pagedjs-footnotes-count)}`);
30434 }
30435
30436 insertRule(rule) {
30437 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30438 }
30439
30440 processCounterIncrements(parsed, counter) {
30441 let increment;
30442 for (let inc in counter.increments) {
30443 increment = counter.increments[inc];
30444 // Find elements for increments
30445 let incrementElements = parsed.querySelectorAll(increment.selector);
30446 // Add counter data
30447 for (let i = 0; i < incrementElements.length; i++) {
30448 incrementElements[i].setAttribute("data-counter-"+ counter.name +"-increment", increment.number);
30449 if (incrementElements[i].getAttribute("data-counter-increment")) {
30450 incrementElements[i].setAttribute("data-counter-increment", incrementElements[i].getAttribute("data-counter-increment") + " " + counter.name);
30451 } else {
30452 incrementElements[i].setAttribute("data-counter-increment", counter.name);
30453 }
30454 }
30455 }
30456 }
30457
30458 processCounterResets(parsed, counter) {
30459 let reset;
30460 for (let r in counter.resets) {
30461 reset = counter.resets[r];
30462 // Find elements for resets
30463 let resetElements = parsed.querySelectorAll(reset.selector);
30464 // Add counter data
30465 for (var i = 0; i < resetElements.length; i++) {
30466 let value = reset.number;
30467 if (typeof value === "string" && value.startsWith("--")) {
30468 // The value is specified using a CSS variable (custom property).
30469 // FIXME: We get the variable value only from the inline style of the element because at this point the
30470 // element is detached and thus using:
30471 //
30472 // getComputedStyle(resetElements[i]).getPropertyValue(value)
30473 //
30474 // always returns an empty string. We could try to temporarily attach the element to get its computed style,
30475 // but for now using the inline style is enough for us.
30476 value = resetElements[i].style.getPropertyValue(value) || 0;
30477 }
30478 resetElements[i].setAttribute("data-counter-"+ counter.name +"-reset", value);
30479 if (resetElements[i].getAttribute("data-counter-reset")) {
30480 resetElements[i].setAttribute("data-counter-reset", resetElements[i].getAttribute("data-counter-reset") + " " + counter.name);
30481 } else {
30482 resetElements[i].setAttribute("data-counter-reset", counter.name);
30483 }
30484 }
30485 }
30486 }
30487
30488 addCounterValues(parsed, counter) {
30489 let counterName = counter.name;
30490
30491 if (counterName === "page" || counterName === "footnote") {
30492 return;
30493 }
30494
30495 let elements = parsed.querySelectorAll("[data-counter-"+ counterName +"-reset], [data-counter-"+ counterName +"-increment]");
30496
30497 let count = 0;
30498 let element;
30499 let increment, reset;
30500 let resetValue, incrementValue, resetDelta;
30501 let incrementArray;
30502
30503 for (let i = 0; i < elements.length; i++) {
30504 element = elements[i];
30505 resetDelta = 0;
30506 incrementArray = [];
30507
30508 if (element.hasAttribute("data-counter-"+ counterName +"-reset")) {
30509 reset = element.getAttribute("data-counter-"+ counterName +"-reset");
30510 resetValue = parseInt(reset);
30511
30512 // Use negative increment value inplace of reset
30513 resetDelta = resetValue - count;
30514 incrementArray.push(`${counterName} ${resetDelta}`);
30515
30516 count = resetValue;
30517 }
30518
30519 if (element.hasAttribute("data-counter-"+ counterName +"-increment")) {
30520
30521 increment = element.getAttribute("data-counter-"+ counterName +"-increment");
30522 incrementValue = parseInt(increment);
30523
30524 count += incrementValue;
30525
30526 element.setAttribute("data-counter-"+counterName+"-value", count);
30527
30528 incrementArray.push(`${counterName} ${incrementValue}`);
30529 }
30530
30531 if (incrementArray.length > 0) {
30532 this.incrementCounterForElement(element, incrementArray);
30533 }
30534
30535 }
30536 }
30537
30538 addFootnoteMarkerCounter(list) {
30539 let markers = [];
30540 csstree.walk(list, {
30541 visit: "Identifier",
30542 enter: (identNode, iItem, iList) => {
30543 markers.push(identNode.name);
30544 }
30545 });
30546
30547 // Already added
30548 if (markers.includes("footnote-maker")) {
30549 return;
30550 }
30551
30552 list.insertData({
30553 type: "WhiteSpace",
30554 value: " "
30555 });
30556
30557 list.insertData({
30558 type: "Identifier",
30559 name: "footnote-marker"
30560 });
30561
30562 list.insertData({
30563 type: "WhiteSpace",
30564 value: " "
30565 });
30566
30567 list.insertData({
30568 type: "Number",
30569 value: 0
30570 });
30571 }
30572
30573 incrementCounterForElement(element, incrementArray) {
30574 if (!element || !incrementArray || incrementArray.length === 0) return;
30575
30576 const ref = element.dataset.ref;
30577 const increments = Array.from(this.styleSheet.cssRules).filter((rule) => {
30578 return rule.selectorText === `[data-ref="${element.dataset.ref}"]:not([data-split-from])`
30579 && rule.style[0] === "counter-increment";
30580 }).map(rule => rule.style.counterIncrement);
30581
30582 // Merge the current increments by summing the values because we generate both a decrement and an increment when the
30583 // element resets and increments the counter at the same time. E.g. ['c1 -7', 'c1 1'] should lead to 'c1 -6'.
30584 increments.push(this.mergeIncrements(incrementArray,
30585 (prev, next) => (parseInt(prev) || 0) + (parseInt(next) || 0)));
30586
30587 // Keep the last value for each counter when merging with the previous increments. E.g. ['c1 -7 c2 3', 'c1 1']
30588 // should lead to 'c1 1 c2 3'.
30589 const counterIncrement = this.mergeIncrements(increments, (prev, next) => next);
30590 this.insertRule(`[data-ref="${ref}"]:not([data-split-from]) { counter-increment: ${counterIncrement} }`);
30591 }
30592
30593 /**
30594 * Merge multiple values of a counter-increment CSS rule, using the specified operator.
30595 *
30596 * @param {Array} incrementArray the values to merge, e.g. ['c1 1', 'c1 -7 c2 1']
30597 * @param {Function} operator the function used to merge counter values (e.g. keep the last value of a counter or sum
30598 * the counter values)
30599 * @return {string} the merged value of the counter-increment CSS rule
30600 */
30601 mergeIncrements(incrementArray, operator) {
30602 const increments = {};
30603 incrementArray.forEach(increment => {
30604 let values = increment.split(" ");
30605 for (let i = 0; i < values.length; i+=2) {
30606 increments[values[i]] = operator(increments[values[i]], values[i + 1]);
30607 }
30608 });
30609
30610 return Object.entries(increments).map(([key, value]) => `${key} ${value}`).join(" ");
30611 }
30612
30613 afterPageLayout(pageElement, page) {
30614 let resets = [];
30615
30616 let pgreset = pageElement.querySelectorAll("[data-counter-page-reset]:not([data-split-from])");
30617 pgreset.forEach((reset) => {
30618 const ref = reset.dataset && reset.dataset.ref;
30619 if (ref && this.resetCountersMap.has(ref)) ; else {
30620 if (ref) {
30621 this.resetCountersMap.set(ref, "");
30622 }
30623 let value = reset.dataset.counterPageReset;
30624 resets.push(`page ${value}`);
30625 }
30626 });
30627
30628 let notereset = pageElement.querySelectorAll("[data-counter-footnote-reset]:not([data-split-from])");
30629 notereset.forEach((reset) => {
30630 let value = reset.dataset.counterFootnoteReset;
30631 resets.push(`footnote ${value}`);
30632 resets.push(`footnote-marker ${value}`);
30633 });
30634
30635 if (resets.length) {
30636 this.styleSheet.insertRule(`[data-page-number="${pageElement.dataset.pageNumber}"] { counter-increment: none; counter-reset: ${resets.join(" ")} }`, this.styleSheet.cssRules.length);
30637 }
30638 }
30639
30640}
30641
30642class Lists extends Handler {
30643 constructor(chunker, polisher, caller) {
30644 super(chunker, polisher, caller);
30645 }
30646 afterParsed(content) {
30647 const orderedLists = content.querySelectorAll("ol");
30648
30649 for (var list of orderedLists) {
30650 this.addDataNumbers(list);
30651 }
30652 }
30653
30654 afterPageLayout(pageElement, page, breakToken, chunker) {
30655 var orderedLists = pageElement.getElementsByTagName("ol");
30656 for (var list of orderedLists) {
30657 if (list.firstElementChild) {
30658 list.start = list.firstElementChild.dataset.itemNum;
30659 }
30660 }
30661 }
30662
30663 addDataNumbers(list) {
30664 let start = 1;
30665 if (list.hasAttribute("start")) {
30666 start = parseInt(list.getAttribute("start"), 10);
30667 if (isNaN(start)) {
30668 start = 1;
30669 }
30670 }
30671 let items = list.children;
30672 for (var i = 0; i < items.length; i++) {
30673 items[i].setAttribute("data-item-num", i + start);
30674 }
30675 }
30676
30677}
30678
30679class PositionFixed extends Handler {
30680 constructor(chunker, polisher, caller) {
30681 super(chunker, polisher, caller);
30682 this.styleSheet = polisher.styleSheet;
30683 this.fixedElementsSelector = [];
30684 this.fixedElements = [];
30685 }
30686
30687 onDeclaration(declaration, dItem, dList, rule) {
30688 if (declaration.property === "position" && declaration.value.children.first().name === "fixed") {
30689 let selector = csstree.generate(rule.ruleNode.prelude);
30690 this.fixedElementsSelector.push(selector);
30691 dList.remove(dItem);
30692 }
30693 }
30694
30695 afterParsed(fragment) {
30696 this.fixedElementsSelector.forEach(fixedEl => {
30697 fragment.querySelectorAll(`${fixedEl}`).forEach(el => {
30698 el.style.setProperty("position", "absolute");
30699 this.fixedElements.push(el);
30700 el.remove();
30701 });
30702 });
30703 }
30704
30705 afterPageLayout(pageElement, page, breakToken) {
30706 this.fixedElements.forEach(el => {
30707 const clone = el.cloneNode(true);
30708 pageElement.querySelector(".pagedjs_pagebox").insertAdjacentElement("afterbegin", clone);
30709 });
30710 }
30711}
30712
30713class PageCounterIncrement extends Handler {
30714 constructor(chunker, polisher, caller) {
30715 super(chunker, polisher, caller);
30716
30717 this.styleSheet = polisher.styleSheet;
30718 this.pageCounter = {
30719 name: "page",
30720 increments: {},
30721 resets: {}
30722 };
30723 }
30724
30725 onDeclaration(declaration, dItem, dList, rule) {
30726 const property = declaration.property;
30727
30728 if (property === "counter-increment") {
30729 let inc = this.handleIncrement(declaration, rule);
30730 if (inc) {
30731 dList.remove(dItem);
30732 }
30733 }
30734 }
30735
30736 afterParsed(_) {
30737 for (const inc in this.pageCounter.increments) {
30738 const increment = this.pageCounter.increments[inc];
30739 this.insertRule(`${increment.selector} { --pagedjs-page-counter-increment: ${increment.number} }`);
30740 }
30741 }
30742
30743 handleIncrement(declaration, rule) {
30744 const identifier = declaration.value.children.first();
30745 const number = declaration.value.children.getSize() > 1 ? declaration.value.children.last().value : 1;
30746 const name = identifier && identifier.name;
30747
30748 if (name && name.indexOf("target-counter-") === 0) {
30749 return;
30750 }
30751 // A counter named page is automatically created and incremented by 1 on every page of the document,
30752 // unless the counter-increment property in the page context explicitly specifies a different increment for the page counter.
30753 // https://www.w3.org/TR/css-page-3/#page-based-counters
30754 if (name !== "page") {
30755 return;
30756 }
30757 // the counter-increment property is not defined on the page context (i.e. @page rule), ignoring...
30758 if (rule.ruleNode.name === "page" && rule.ruleNode.type === "Atrule") {
30759 return;
30760 }
30761 const selector = csstree.generate(rule.ruleNode.prelude);
30762 return this.pageCounter.increments[selector] = {
30763 selector: selector,
30764 number
30765 };
30766 }
30767
30768 insertRule(rule) {
30769 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30770 }
30771}
30772
30773class NthOfType extends Handler {
30774 constructor(chunker, polisher, caller) {
30775 super(chunker, polisher, caller);
30776
30777 this.styleSheet = polisher.styleSheet;
30778 this.selectors = {};
30779 }
30780
30781 onRule(ruleNode, ruleItem, rulelist) {
30782 let selector = csstree.generate(ruleNode.prelude);
30783 if (selector.match(/:(first|last|nth)-of-type/)) {
30784
30785 let declarations = csstree.generate(ruleNode.block);
30786 declarations = declarations.replace(/[{}]/g,"");
30787
30788 let uuid = "nth-of-type-" + UUID();
30789
30790 selector.split(",").forEach((s) => {
30791 if (!this.selectors[s]) {
30792 this.selectors[s] = [uuid, declarations];
30793 } else {
30794 this.selectors[s][1] = `${this.selectors[s][1]};${declarations}` ;
30795 }
30796 });
30797
30798 rulelist.remove(ruleItem);
30799 }
30800 }
30801
30802 afterParsed(parsed) {
30803 this.processSelectors(parsed, this.selectors);
30804 }
30805
30806 processSelectors(parsed, selectors) {
30807 // add the new attributes to matching elements
30808 for (let s in selectors) {
30809 let elements = parsed.querySelectorAll(s);
30810
30811 for (var i = 0; i < elements.length; i++) {
30812 let dataNthOfType = elements[i].getAttribute("data-nth-of-type");
30813
30814 if (dataNthOfType && dataNthOfType != "") {
30815 dataNthOfType = `${dataNthOfType},${selectors[s][0]}`;
30816 elements[i].setAttribute("data-nth-of-type", dataNthOfType);
30817 } else {
30818 elements[i].setAttribute("data-nth-of-type", selectors[s][0]);
30819 }
30820 }
30821
30822 let rule = `*[data-nth-of-type*='${selectors[s][0]}'] { ${selectors[s][1]}; }`;
30823 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30824 }
30825 }
30826}
30827
30828class Following extends Handler {
30829 constructor(chunker, polisher, caller) {
30830 super(chunker, polisher, caller);
30831
30832 this.styleSheet = polisher.styleSheet;
30833 this.selectors = {};
30834 }
30835
30836 onRule(ruleNode, ruleItem, rulelist) {
30837 let selector = csstree.generate(ruleNode.prelude);
30838 if (selector.match(/\+/)) {
30839
30840 let declarations = csstree.generate(ruleNode.block);
30841 declarations = declarations.replace(/[{}]/g,"");
30842
30843 let uuid = "following-" + UUID();
30844
30845 selector.split(",").forEach((s) => {
30846 if (!this.selectors[s]) {
30847 this.selectors[s] = [uuid, declarations];
30848 } else {
30849 this.selectors[s][1] = `${this.selectors[s][1]};${declarations}` ;
30850 }
30851 });
30852
30853 rulelist.remove(ruleItem);
30854 }
30855 }
30856
30857 afterParsed(parsed) {
30858 this.processSelectors(parsed, this.selectors);
30859 }
30860
30861 processSelectors(parsed, selectors) {
30862 // add the new attributes to matching elements
30863 for (let s in selectors) {
30864 let elements = parsed.querySelectorAll(s);
30865
30866 for (var i = 0; i < elements.length; i++) {
30867 let dataFollowing = elements[i].getAttribute("data-following");
30868
30869 if (dataFollowing && dataFollowing != "") {
30870 dataFollowing = `${dataFollowing},${selectors[s][0]}`;
30871 elements[i].setAttribute("data-following", dataFollowing);
30872 } else {
30873 elements[i].setAttribute("data-following", selectors[s][0]);
30874 }
30875 }
30876
30877 let rule = `*[data-following*='${selectors[s][0]}'] { ${selectors[s][1]}; }`;
30878 this.styleSheet.insertRule(rule, this.styleSheet.cssRules.length);
30879 }
30880 }
30881}
30882
30883class Footnotes extends Handler {
30884 constructor(chunker, polisher, caller) {
30885 super(chunker, polisher, caller);
30886
30887 this.footnotes = {};
30888 this.needsLayout = [];
30889 }
30890
30891 onDeclaration(declaration, dItem, dList, rule) {
30892 let property = declaration.property;
30893 if (property === "float") {
30894 let identifier = declaration.value.children && declaration.value.children.first();
30895 let location = identifier && identifier.name;
30896 if (location === "footnote") {
30897 let selector = csstree.generate(rule.ruleNode.prelude);
30898 this.footnotes[selector] = {
30899 selector: selector,
30900 policy: "auto",
30901 display: "block"
30902 };
30903 dList.remove(dItem);
30904 }
30905 }
30906 if (property === "footnote-policy") {
30907 let identifier = declaration.value.children && declaration.value.children.first();
30908 let policy = identifier && identifier.name;
30909 if (policy) {
30910 let selector = csstree.generate(rule.ruleNode.prelude);
30911 let note = this.footnotes[selector];
30912 if (note) {
30913 note.policy = policy;
30914 }
30915 }
30916 }
30917 if (property === "footnote-display") {
30918 let identifier = declaration.value.children && declaration.value.children.first();
30919 let display = identifier && identifier.name;
30920 let selector = csstree.generate(rule.ruleNode.prelude);
30921 if (display && this.footnotes[selector]) {
30922 let note = this.footnotes[selector];
30923 if (note) {
30924 note.display = display;
30925 }
30926 }
30927 }
30928 }
30929
30930 onPseudoSelector(pseudoNode, pItem, pList, selector, rule) {
30931 let name = pseudoNode.name;
30932 if (name === "footnote-marker") {
30933 // switch ::footnote-marker to [data-footnote-marker]::before
30934 let prelude = rule.ruleNode.prelude;
30935 let newPrelude = new csstree.List();
30936
30937 // Can't get remove to work, so just copying everything else
30938 prelude.children.first().children.each((node) => {
30939 if (node.type !== "PseudoElementSelector") {
30940 newPrelude.appendData(node);
30941 }
30942 });
30943
30944 // Add our data call
30945 newPrelude.appendData({
30946 type: "AttributeSelector",
30947 name: {
30948 type: "Identifier",
30949 name: "data-footnote-marker",
30950 },
30951 flags: null,
30952 loc: null,
30953 matcher: null,
30954 value: null
30955 });
30956
30957 // Add new pseudo element
30958 newPrelude.appendData({
30959 type: "PseudoElementSelector",
30960 name: "marker",
30961 loc: null,
30962 children: null
30963 });
30964
30965 prelude.children.first().children = newPrelude;
30966 }
30967
30968 if (name === "footnote-call") {
30969 // switch ::footnote-call to [data-footnote-call]::after
30970
30971 let prelude = rule.ruleNode.prelude;
30972 let newPrelude = new csstree.List();
30973
30974 // Can't get remove to work, so just copying everything else
30975 prelude.children.first().children.each((node) => {
30976 if (node.type !== "PseudoElementSelector") {
30977 newPrelude.appendData(node);
30978 }
30979 });
30980
30981 // Add our data call
30982 newPrelude.appendData({
30983 type: "AttributeSelector",
30984 name: {
30985 type: "Identifier",
30986 name: "data-footnote-call",
30987 },
30988 flags: null,
30989 loc: null,
30990 matcher: null,
30991 value: null
30992 });
30993
30994 // Add new pseudo element
30995 newPrelude.appendData({
30996 type: "PseudoElementSelector",
30997 name: "after",
30998 loc: null,
30999 children: null
31000 });
31001
31002 prelude.children.first().children = newPrelude;
31003 }
31004 }
31005
31006 afterParsed(parsed) {
31007 this.processFootnotes(parsed, this.footnotes);
31008 }
31009
31010 processFootnotes(parsed, notes) {
31011 for (let n in notes) {
31012 // Find elements
31013 let elements = parsed.querySelectorAll(n);
31014 let element;
31015 let note = notes[n];
31016 for (var i = 0; i < elements.length; i++) {
31017 element = elements[i];
31018 // Add note type
31019 element.setAttribute("data-note", "footnote");
31020 element.setAttribute("data-break-before", "avoid");
31021 element.setAttribute("data-note-policy", note.policy || "auto");
31022 element.setAttribute("data-note-display", note.display || "block");
31023 // Mark all parents
31024 this.processFootnoteContainer(element);
31025 }
31026 }
31027 }
31028
31029 processFootnoteContainer(node) {
31030 // Find the container
31031 let element = node.parentElement;
31032 let prevElement = element;
31033 // Walk up the dom until we find a container element
31034 while (element) {
31035 if (isContainer(element)) {
31036 // Add flag to the previous non-container element that will render with children
31037 prevElement.setAttribute("data-has-notes", "true");
31038 break;
31039 }
31040
31041 prevElement = element;
31042 element = element.parentElement;
31043
31044 // If no containers were found and there are no further parents flag the last element
31045 if (!element) {
31046 prevElement.setAttribute("data-has-notes", "true");
31047 }
31048 }
31049 }
31050
31051 renderNode(node) {
31052 if (node.nodeType == 1) {
31053 // Get all notes
31054 let notes;
31055
31056 // Ingnore html element nodes, like mathml
31057 if (!node.dataset) {
31058 return;
31059 }
31060
31061 if (node.dataset.note === "footnote") {
31062 notes = [node];
31063 } else if (node.dataset.hasNotes || node.querySelectorAll("[data-note='footnote']")) {
31064 notes = node.querySelectorAll("[data-note='footnote']");
31065 }
31066
31067 if (notes && notes.length) {
31068 this.findVisibleFootnotes(notes, node);
31069 }
31070 }
31071 }
31072
31073 findVisibleFootnotes(notes, node) {
31074 let area, size, right;
31075 area = node.closest(".pagedjs_page_content");
31076 size = area.getBoundingClientRect();
31077 right = size.left + size.width;
31078
31079 for (let i = 0; i < notes.length; ++i) {
31080 let currentNote = notes[i];
31081 let bounds = currentNote.getBoundingClientRect();
31082 let left = bounds.left;
31083
31084 if (left < right) {
31085 // Add call for the note
31086 this.moveFootnote(currentNote, node.closest(".pagedjs_area"), true);
31087 }
31088 }
31089 }
31090
31091 moveFootnote(node, pageArea, needsNoteCall) {
31092 // let pageArea = node.closest(".pagedjs_area");
31093 let noteArea = pageArea.querySelector(".pagedjs_footnote_area");
31094 let noteContent = noteArea.querySelector(".pagedjs_footnote_content");
31095 let noteInnerContent = noteContent.querySelector(".pagedjs_footnote_inner_content");
31096
31097 if (!isElement(node)) {
31098 return;
31099 }
31100
31101 // Add call for the note
31102 let noteCall;
31103 if (needsNoteCall) {
31104 noteCall = this.createFootnoteCall(node);
31105 }
31106
31107 // Remove the break before attribute for future layout
31108 node.removeAttribute("data-break-before");
31109
31110 // Check if note already exists for overflow
31111 let existing = noteInnerContent.querySelector(`[data-ref="${node.dataset.ref}"]`);
31112 if (existing) {
31113 // Remove the note from the flow but no need to render it again
31114 node.remove();
31115 return;
31116 }
31117
31118 // Add the note node
31119 noteInnerContent.appendChild(node);
31120
31121 // Remove empty class
31122 if (noteContent.classList.contains("pagedjs_footnote_empty")) {
31123 noteContent.classList.remove("pagedjs_footnote_empty");
31124 }
31125
31126 // Add marker
31127 node.dataset.footnoteMarker = node.dataset.ref;
31128
31129 // Add Id
31130 node.id = `note-${node.dataset.ref}`;
31131
31132 // Get note content size
31133 let height = noteContent.scrollHeight;
31134
31135 // Check the noteCall is still on screen
31136 let area = pageArea.querySelector(".pagedjs_page_content");
31137 let size = area.getBoundingClientRect();
31138 let right = size.left + size.width;
31139
31140 // TODO: add a max height in CSS
31141
31142 // Check element sizes
31143 let noteCallBounds = noteCall && noteCall.getBoundingClientRect();
31144 let noteAreaBounds = noteArea.getBoundingClientRect();
31145
31146 // Get the @footnote margins
31147 let noteContentMargins = this.marginsHeight(noteContent);
31148 let noteContentPadding = this.paddingHeight(noteContent);
31149 let noteContentBorders = this.borderHeight(noteContent);
31150 let total = noteContentMargins + noteContentPadding + noteContentBorders;
31151
31152 // Get the top of the @footnote area
31153 let notAreaTop = Math.floor(noteAreaBounds.top);
31154 // If the height isn't set yet, remove the margins from the top
31155 if (noteAreaBounds.height === 0) {
31156 notAreaTop -= this.marginsHeight(noteContent, false);
31157 notAreaTop -= this.paddingHeight(noteContent, false);
31158 notAreaTop -= this.borderHeight(noteContent, false);
31159 }
31160 // Determine the note call position and offset per policy
31161 let notePolicy = node.dataset.notePolicy;
31162 let noteCallPosition = 0;
31163 let noteCallOffset = 0;
31164 if (noteCall) {
31165 // Get the correct line bottom for super or sub styled callouts
31166 let prevSibling = noteCall.previousSibling;
31167 let range = new Range();
31168 if (prevSibling) {
31169 range.setStartBefore(prevSibling);
31170 } else {
31171 range.setStartBefore(noteCall);
31172 }
31173 range.setEndAfter(noteCall);
31174 let rangeBounds = range.getBoundingClientRect();
31175 noteCallPosition = rangeBounds.bottom;
31176 if (!notePolicy || notePolicy === "auto") {
31177 noteCallOffset = Math.ceil(rangeBounds.bottom);
31178 } else if (notePolicy === "line") {
31179 noteCallOffset = Math.ceil(rangeBounds.top);
31180 } else if (notePolicy === "block") {
31181 // Check that there is a previous element on the page
31182 let parentParagraph = noteCall.closest("p").previousElementSibling;
31183 if (parentParagraph) {
31184 noteCallOffset = Math.ceil(
31185 parentParagraph.getBoundingClientRect().bottom
31186 );
31187 } else {
31188 noteCallOffset = Math.ceil(rangeBounds.bottom);
31189 }
31190 }
31191 }
31192
31193 let contentDelta = height + total - noteAreaBounds.height;
31194 // Space between the top of the footnotes area and the bottom of the footnote call
31195 let noteDelta = noteCallPosition ? notAreaTop - noteCallPosition : 0;
31196 // Space needed for the force a break for the policy of the footnote
31197 let notePolicyDelta = noteCallPosition ? Math.floor(noteAreaBounds.top) - noteCallOffset : 0;
31198 let hasNotes = noteArea.querySelector("[data-note='footnote']");
31199 if (needsNoteCall && noteCallBounds.left > right) {
31200 // Note is offscreen and will be chunked to the next page on overflow
31201 node.remove();
31202 } else if (!hasNotes && needsNoteCall && total > noteDelta) {
31203 // No space to add even the footnote area
31204 pageArea.style.setProperty("--pagedjs-footnotes-height", "0px");
31205 // Add a wrapper as this div is removed later
31206 let wrapperDiv = document.createElement("div");
31207 wrapperDiv.appendChild(node);
31208 // Push to the layout queue for the next page
31209 this.needsLayout.push(wrapperDiv);
31210 } else if (!needsNoteCall) {
31211 // Call was previously added, force adding footnote
31212 pageArea.style.setProperty(
31213 "--pagedjs-footnotes-height",
31214 `${height + total}px`
31215 );
31216 } else if (noteCallPosition < noteAreaBounds.top - contentDelta) {
31217 // the current note content will fit without pushing the call to the next page
31218 pageArea.style.setProperty(
31219 "--pagedjs-footnotes-height",
31220 `${height + noteContentMargins + noteContentBorders}px`
31221 );
31222 } else {
31223 // set height to just before note call
31224 pageArea.style.setProperty(
31225 "--pagedjs-footnotes-height",
31226 `${noteAreaBounds.height + notePolicyDelta}px`
31227 );
31228 noteInnerContent.style.height =
31229 noteAreaBounds.height + notePolicyDelta - total + "px";
31230 }
31231 }
31232
31233 createFootnoteCall(node) {
31234 let parentElement = node.parentElement;
31235 let footnoteCall = document.createElement("a");
31236 for (const className of node.classList) {
31237 footnoteCall.classList.add(`${className}`);
31238 }
31239
31240 footnoteCall.dataset.footnoteCall = node.dataset.ref;
31241 footnoteCall.dataset.ref = node.dataset.ref;
31242
31243 // Increment for counters
31244 footnoteCall.dataset.dataCounterFootnoteIncrement = 1;
31245
31246 // Add link
31247 footnoteCall.href = `#note-${node.dataset.ref}`;
31248
31249 parentElement.insertBefore(footnoteCall, node);
31250
31251 return footnoteCall;
31252 }
31253
31254 afterPageLayout(pageElement, page, breakToken, chunker) {
31255 let pageArea = pageElement.querySelector(".pagedjs_area");
31256 let noteArea = page.footnotesArea;
31257 let noteContent = noteArea.querySelector(".pagedjs_footnote_content");
31258 let noteInnerContent = noteArea.querySelector(".pagedjs_footnote_inner_content");
31259
31260 let noteContentBounds = noteContent.getBoundingClientRect();
31261 let { width } = noteContentBounds;
31262
31263 noteInnerContent.style.columnWidth = Math.round(width) + "px";
31264 noteInnerContent.style.columnGap = "calc(var(--pagedjs-margin-right) + var(--pagedjs-margin-left))";
31265
31266 // Get overflow
31267 let layout = new Layout(noteArea, undefined, chunker.settings);
31268 let overflow = layout.findOverflow(noteInnerContent, noteContentBounds);
31269
31270 if (overflow) {
31271 let { startContainer, startOffset } = overflow;
31272 let startIsNode;
31273 if (isElement(startContainer)) {
31274 let start = startContainer.childNodes[startOffset];
31275 startIsNode = isElement(start) && start.hasAttribute("data-footnote-marker");
31276 }
31277
31278 let extracted = overflow.extractContents();
31279
31280 if (!startIsNode) {
31281 let splitChild = extracted.firstElementChild;
31282 splitChild.dataset.splitFrom = splitChild.dataset.ref;
31283
31284 this.handleAlignment(noteInnerContent.lastElementChild);
31285 }
31286
31287 this.needsLayout.push(extracted);
31288
31289 noteContent.style.removeProperty("height");
31290 noteInnerContent.style.removeProperty("height");
31291
31292 let noteInnerContentBounds = noteInnerContent.getBoundingClientRect();
31293 let { height } = noteInnerContentBounds;
31294
31295 // Get the @footnote margins
31296 let noteContentMargins = this.marginsHeight(noteContent);
31297 let noteContentPadding = this.paddingHeight(noteContent);
31298 let noteContentBorders = this.borderHeight(noteContent);
31299 pageArea.style.setProperty(
31300 "--pagedjs-footnotes-height",
31301 `${height + noteContentMargins + noteContentBorders + noteContentPadding}px`
31302 );
31303
31304 // Hide footnote content if empty
31305 if (noteInnerContent.childNodes.length === 0) {
31306 noteContent.classList.add("pagedjs_footnote_empty");
31307 }
31308
31309 if (!breakToken) {
31310 chunker.clonePage(page);
31311 } else {
31312 let breakBefore, previousBreakAfter;
31313 if (
31314 breakToken.node &&
31315 typeof breakToken.node.dataset !== "undefined" &&
31316 typeof breakToken.node.dataset.previousBreakAfter !== "undefined"
31317 ) {
31318 previousBreakAfter = breakToken.node.dataset.previousBreakAfter;
31319 }
31320
31321 if (
31322 breakToken.node &&
31323 typeof breakToken.node.dataset !== "undefined" &&
31324 typeof breakToken.node.dataset.breakBefore !== "undefined"
31325 ) {
31326 breakBefore = breakToken.node.dataset.breakBefore;
31327 }
31328
31329 if (breakBefore || previousBreakAfter) {
31330 chunker.clonePage(page);
31331 }
31332 }
31333 }
31334 noteInnerContent.style.height = "auto";
31335 }
31336
31337 handleAlignment(node) {
31338 let styles = window.getComputedStyle(node);
31339 let alignLast = styles["text-align-last"];
31340 node.dataset.lastSplitElement = "true";
31341 if (alignLast === "auto") {
31342 node.dataset.alignLastSplitElement = "justify";
31343 } else {
31344 node.dataset.alignLastSplitElement = alignLast;
31345 }
31346 }
31347
31348 beforePageLayout(page) {
31349 while (this.needsLayout.length) {
31350 let fragment = this.needsLayout.shift();
31351
31352 Array.from(fragment.childNodes).forEach((node) => {
31353 this.moveFootnote(
31354 node,
31355 page.element.querySelector(".pagedjs_area"),
31356 false
31357 );
31358 });
31359 }
31360 }
31361
31362 afterOverflowRemoved(removed, rendered) {
31363 // Find the page area
31364 let area = rendered.closest(".pagedjs_area");
31365 // Get any rendered footnotes
31366 let notes = area.querySelectorAll(".pagedjs_footnote_area [data-note='footnote']");
31367 for (let n = 0; n < notes.length; n++) {
31368 const note = notes[n];
31369 // Check if the call for that footnote has been removed with the overflow
31370 let call = removed.querySelector(`[data-footnote-call="${note.dataset.ref}"]`);
31371 if (call) {
31372 note.remove();
31373 }
31374 }
31375 // Hide footnote content if empty
31376 let noteInnerContent = area.querySelector(".pagedjs_footnote_inner_content");
31377 if (noteInnerContent && noteInnerContent.childNodes.length === 0) {
31378 noteInnerContent.parentElement.classList.add("pagedjs_footnote_empty");
31379 }
31380 }
31381
31382 marginsHeight(element, total=true) {
31383 let styles = window.getComputedStyle(element);
31384 let marginTop = parseInt(styles.marginTop);
31385 let marginBottom = parseInt(styles.marginBottom);
31386 let margin = 0;
31387 if (marginTop) {
31388 margin += marginTop;
31389 }
31390 if (marginBottom && total) {
31391 margin += marginBottom;
31392 }
31393 return margin;
31394 }
31395
31396 paddingHeight(element, total=true) {
31397 let styles = window.getComputedStyle(element);
31398 let paddingTop = parseInt(styles.paddingTop);
31399 let paddingBottom = parseInt(styles.paddingBottom);
31400 let padding = 0;
31401 if (paddingTop) {
31402 padding += paddingTop;
31403 }
31404 if (paddingBottom && total) {
31405 padding += paddingBottom;
31406 }
31407 return padding;
31408 }
31409
31410 borderHeight(element, total=true) {
31411 let styles = window.getComputedStyle(element);
31412 let borderTop = parseInt(styles.borderTop);
31413 let borderBottom = parseInt(styles.borderBottom);
31414 let borders = 0;
31415 if (borderTop) {
31416 borders += borderTop;
31417 }
31418 if (borderBottom && total) {
31419 borders += borderBottom;
31420 }
31421 return borders;
31422 }
31423}
31424
31425var pagedMediaHandlers = [
31426 PrintMedia,
31427 AtPage,
31428 Breaks,
31429 Splits,
31430 Counters,
31431 Lists,
31432 PositionFixed,
31433 PageCounterIncrement,
31434 NthOfType,
31435 Following,
31436 Footnotes
31437];
31438
31439class RunningHeaders extends Handler {
31440 constructor(chunker, polisher, caller) {
31441 super(chunker, polisher, caller);
31442
31443 this.runningSelectors = {};
31444 this.elements = {};
31445 }
31446
31447 onDeclaration(declaration, dItem, dList, rule) {
31448 if (declaration.property === "position") {
31449 let selector = csstree.generate(rule.ruleNode.prelude);
31450 let identifier = declaration.value.children.first().name;
31451
31452 if (identifier === "running") {
31453 let value;
31454 csstree.walk(declaration, {
31455 visit: "Function",
31456 enter: (node, item, list) => {
31457 value = node.children.first().name;
31458 }
31459 });
31460
31461 this.runningSelectors[value] = {
31462 identifier: identifier,
31463 value: value,
31464 selector: selector
31465 };
31466 }
31467 }
31468
31469 if (declaration.property === "content") {
31470
31471 csstree.walk(declaration, {
31472 visit: "Function",
31473 enter: (funcNode, fItem, fList) => {
31474
31475 if (funcNode.name.indexOf("element") > -1) {
31476
31477 let selector = csstree.generate(rule.ruleNode.prelude);
31478
31479 let func = funcNode.name;
31480
31481 let value = funcNode.children.first().name;
31482
31483 let args = [value];
31484
31485 // we only handle first for now
31486 let style = "first";
31487
31488 selector.split(",").forEach((s) => {
31489 // remove before / after
31490 s = s.replace(/::after|::before/, "");
31491
31492 this.elements[s] = {
31493 func: func,
31494 args: args,
31495 value: value,
31496 style: style ,
31497 selector: s,
31498 fullSelector: selector
31499 };
31500 });
31501 }
31502
31503 }
31504 });
31505 }
31506 }
31507
31508 afterParsed(fragment) {
31509 for (let name of Object.keys(this.runningSelectors)) {
31510 let set = this.runningSelectors[name];
31511 let selected = Array.from(fragment.querySelectorAll(set.selector));
31512
31513 if (set.identifier === "running") {
31514 for (let header of selected) {
31515 header.style.display = "none";
31516 }
31517 }
31518
31519 }
31520 }
31521
31522 afterPageLayout(fragment) {
31523 for (let name of Object.keys(this.runningSelectors)) {
31524 let set = this.runningSelectors[name];
31525 let selected = fragment.querySelector(set.selector);
31526 if (selected) {
31527 // let cssVar;
31528 if (set.identifier === "running") {
31529 // cssVar = selected.textContent.replace(/\\([\s\S])|(["|'])/g,"\\$1$2");
31530 // this.styleSheet.insertRule(`:root { --string-${name}: "${cssVar}"; }`, this.styleSheet.cssRules.length);
31531 // fragment.style.setProperty(`--string-${name}`, `"${cssVar}"`);
31532 set.first = selected;
31533 } else {
31534 console.warn(set.value + "needs css replacement");
31535 }
31536 }
31537 }
31538
31539 // move elements
31540 if (!this.orderedSelectors) {
31541 this.orderedSelectors = this.orderSelectors(this.elements);
31542 }
31543
31544 for (let selector of this.orderedSelectors) {
31545 if (selector) {
31546
31547 let el = this.elements[selector];
31548 let selected = fragment.querySelector(selector);
31549 if (selected) {
31550 let running = this.runningSelectors[el.args[0]];
31551 if (running && running.first) {
31552 selected.innerHTML = ""; // Clear node
31553 // selected.classList.add("pagedjs_clear-after"); // Clear ::after
31554 let clone = running.first.cloneNode(true);
31555 clone.style.display = null;
31556 selected.appendChild(clone);
31557 }
31558 }
31559 }
31560 }
31561 }
31562
31563 /**
31564 * Assign a weight to @page selector classes
31565 * 1) page
31566 * 2) left & right
31567 * 3) blank
31568 * 4) first & nth
31569 * 5) named page
31570 * 6) named left & right
31571 * 7) named first & nth
31572 * @param {string} [s] selector string
31573 * @return {int} weight
31574 */
31575 pageWeight(s) {
31576 let weight = 1;
31577 let selector = s.split(" ");
31578 let parts = selector.length && selector[0].split(".");
31579
31580 parts.shift(); // remove empty first part
31581
31582 switch (parts.length) {
31583 case 4:
31584 if (/^pagedjs_[\w-]+_first_page$/.test(parts[3])) {
31585 weight = 7;
31586 } else if (parts[3] === "pagedjs_left_page" || parts[3] === "pagedjs_right_page") {
31587 weight = 6;
31588 }
31589 break;
31590 case 3:
31591 if (parts[1] === "pagedjs_named_page") {
31592 if (parts[2].indexOf(":nth-of-type") > -1) {
31593 weight = 7;
31594 } else {
31595 weight = 5;
31596 }
31597 }
31598 break;
31599 case 2:
31600 if (parts[1] === "pagedjs_first_page") {
31601 weight = 4;
31602 } else if (parts[1] === "pagedjs_blank_page") {
31603 weight = 3;
31604 } else if (parts[1] === "pagedjs_left_page" || parts[1] === "pagedjs_right_page") {
31605 weight = 2;
31606 }
31607 break;
31608 default:
31609 if (parts[0].indexOf(":nth-of-type") > -1) {
31610 weight = 4;
31611 } else {
31612 weight = 1;
31613 }
31614 }
31615
31616 return weight;
31617 }
31618
31619 /**
31620 * Orders the selectors based on weight
31621 *
31622 * Does not try to deduplicate base on specifity of the selector
31623 * Previous matched selector will just be overwritten
31624 * @param {obj} [obj] selectors object
31625 * @return {Array} orderedSelectors
31626 */
31627 orderSelectors(obj) {
31628 let selectors = Object.keys(obj);
31629 let weighted = {
31630 1: [],
31631 2: [],
31632 3: [],
31633 4: [],
31634 5: [],
31635 6: [],
31636 7: []
31637 };
31638
31639 let orderedSelectors = [];
31640
31641 for (let s of selectors) {
31642 let w = this.pageWeight(s);
31643 weighted[w].unshift(s);
31644 }
31645
31646 for (var i = 1; i <= 7; i++) {
31647 orderedSelectors = orderedSelectors.concat(weighted[i]);
31648 }
31649
31650 return orderedSelectors;
31651 }
31652
31653 beforeTreeParse(text, sheet) {
31654 // element(x) is parsed as image element selector, so update element to element-ident
31655 sheet.text = text.replace(/element[\s]*\(([^|^#)]*)\)/g, "element-ident($1)");
31656 }
31657}
31658
31659function cleanPseudoContent(el, trim = "\"' ") {
31660 if(el == null) return;
31661 return el
31662 .replace(new RegExp(`^[${trim}]+`), "")
31663 .replace(new RegExp(`[${trim}]+$`), "")
31664 .replace(/["']/g, match => {
31665 return "\\" + match;
31666 })
31667 .replace(/[\n]/g, match => {
31668 return "\\00000A";
31669 });
31670}
31671
31672function cleanSelector(el) {
31673 if(el == null) return;
31674 return el
31675 .replace(new RegExp("::footnote-call", "g"), "")
31676 .replace(new RegExp("::footnote-marker", "g"), "");
31677}
31678
31679class StringSets extends Handler {
31680 constructor(chunker, polisher, caller) {
31681 super(chunker, polisher, caller);
31682
31683 this.stringSetSelectors = {};
31684 this.type;
31685 // pageLastString = last string variable defined on the page
31686 this.pageLastString;
31687
31688 }
31689
31690 onDeclaration(declaration, dItem, dList, rule) {
31691 if (declaration.property === "string-set") {
31692 let selector = csstree.generate(rule.ruleNode.prelude);
31693
31694 let identifiers = [];
31695 let functions = [];
31696 let values = [];
31697
31698 declaration.value.children.forEach((child) => {
31699 if (child.type === "Identifier") {
31700 identifiers.push(child.name);
31701 }
31702 if (child.type === "Function") {
31703 functions.push(child.name);
31704 child.children.forEach((subchild) => {
31705 if (subchild.type === "Identifier") {
31706 values.push(subchild.name);
31707 }
31708 });
31709 }
31710 });
31711
31712 identifiers.forEach((identifier, index) => {
31713 let func = functions[index];
31714 let value = values[index];
31715 this.stringSetSelectors[identifier] = {
31716 identifier,
31717 func,
31718 value,
31719 selector
31720 };
31721 });
31722
31723 }
31724 }
31725
31726 onContent(funcNode, fItem, fList, declaration, rule) {
31727
31728 if (funcNode.name === "string") {
31729 let identifier = funcNode.children && funcNode.children.first().name;
31730 this.type = funcNode.children.last().name;
31731 funcNode.name = "var";
31732 funcNode.children = new csstree.List();
31733
31734
31735 if(this.type === "first" || this.type === "last" || this.type === "start" || this.type === "first-except"){
31736 funcNode.children.append(
31737 funcNode.children.createItem({
31738 type: "Identifier",
31739 loc: null,
31740 name: "--pagedjs-string-" + this.type + "-" + identifier
31741 })
31742 );
31743 }else {
31744 funcNode.children.append(
31745 funcNode.children.createItem({
31746 type: "Identifier",
31747 loc: null,
31748 name: "--pagedjs-string-first-" + identifier
31749 })
31750 );
31751 }
31752 }
31753 }
31754
31755 afterPageLayout(fragment) {
31756
31757
31758 if ( this.pageLastString === undefined )
31759 {
31760 this.pageLastString = {};
31761 }
31762
31763
31764 for (let name of Object.keys(this.stringSetSelectors)) {
31765
31766 let set = this.stringSetSelectors[name];
31767 let value = set.value;
31768 let func = set.func;
31769 let selected = fragment.querySelectorAll(set.selector);
31770
31771 // Get the last found string for the current identifier
31772 let stringPrevPage = ( name in this.pageLastString ) ? this.pageLastString[name] : "";
31773
31774 let varFirst, varLast, varStart, varFirstExcept;
31775
31776 if(selected.length == 0){
31777 // if there is no sel. on the page
31778 varFirst = stringPrevPage;
31779 varLast = stringPrevPage;
31780 varStart = stringPrevPage;
31781 varFirstExcept = stringPrevPage;
31782 }else {
31783
31784 selected.forEach((sel) => {
31785 // push each content into the array to define in the variable the first and the last element of the page.
31786 if (func === "content") {
31787 this.pageLastString[name] = selected[selected.length - 1].textContent;
31788 }
31789
31790 if (func === "attr") {
31791 this.pageLastString[name] = selected[selected.length - 1].getAttribute(value) || "";
31792 }
31793
31794 });
31795
31796 /* FIRST */
31797
31798 if (func === "content") {
31799 varFirst = selected[0].textContent;
31800 }
31801
31802 if (func === "attr") {
31803 varFirst = selected[0].getAttribute(value) || "";
31804 }
31805
31806
31807 /* LAST */
31808
31809 if (func === "content") {
31810 varLast = selected[selected.length - 1].textContent;
31811 }
31812
31813 if (func === "attr") {
31814 varLast = selected[selected.length - 1].getAttribute(value) || "";
31815 }
31816
31817
31818 /* START */
31819
31820 // Hack to find if the sel. is the first elem of the page / find a better way
31821 let selTop = selected[0].getBoundingClientRect().top;
31822 let pageContent = selected[0].closest(".pagedjs_page_content");
31823 let pageContentTop = pageContent.getBoundingClientRect().top;
31824
31825 if(selTop == pageContentTop){
31826 varStart = varFirst;
31827 }else {
31828 varStart = stringPrevPage;
31829 }
31830
31831 /* FIRST EXCEPT */
31832
31833 varFirstExcept = "";
31834
31835 }
31836
31837 fragment.style.setProperty(`--pagedjs-string-first-${name}`, `"${cleanPseudoContent(varFirst)}`);
31838 fragment.style.setProperty(`--pagedjs-string-last-${name}`, `"${cleanPseudoContent(varLast)}`);
31839 fragment.style.setProperty(`--pagedjs-string-start-${name}`, `"${cleanPseudoContent(varStart)}`);
31840 fragment.style.setProperty(`--pagedjs-string-first-except-${name}`, `"${cleanPseudoContent(varFirstExcept)}`);
31841
31842
31843 }
31844 }
31845
31846
31847}
31848
31849class TargetCounters extends Handler {
31850 constructor(chunker, polisher, caller) {
31851 super(chunker, polisher, caller);
31852
31853 this.styleSheet = polisher.styleSheet;
31854
31855 this.counterTargets = {};
31856 }
31857
31858 onContent(funcNode, fItem, fList, declaration, rule) {
31859 if (funcNode.name === "target-counter") {
31860 let selector = csstree.generate(rule.ruleNode.prelude);
31861
31862 let first = funcNode.children.first();
31863 let func = first.name;
31864
31865 let value = csstree.generate(funcNode);
31866
31867 let args = [];
31868
31869 first.children.forEach((child) => {
31870 if (child.type === "Identifier") {
31871
31872 args.push(child.name);
31873 }
31874 });
31875
31876 let counter;
31877 let style;
31878 let styleIdentifier;
31879
31880 funcNode.children.forEach((child) => {
31881 if (child.type === "Identifier") {
31882 if (!counter) {
31883 counter = child.name;
31884 } else if (!style) {
31885 styleIdentifier = csstree.clone(child);
31886 style = child.name;
31887 }
31888 }
31889 });
31890
31891 let variable = "target-counter-" + UUID();
31892
31893 selector.split(",").forEach((s) => {
31894 this.counterTargets[s] = {
31895 func: func,
31896 args: args,
31897 value: value,
31898 counter: counter,
31899 style: style,
31900 selector: s,
31901 fullSelector: selector,
31902 variable: variable
31903 };
31904 });
31905
31906 // Replace with counter
31907 funcNode.name = "counter";
31908 funcNode.children = new csstree.List();
31909 funcNode.children.appendData({
31910 type: "Identifier",
31911 loc: 0,
31912 name: variable
31913 });
31914
31915 if (styleIdentifier) {
31916 funcNode.children.appendData({type: "Operator", loc: null, value: ","});
31917 funcNode.children.appendData(styleIdentifier);
31918 }
31919 }
31920 }
31921
31922 afterPageLayout(fragment, page, breakToken, chunker) {
31923 Object.keys(this.counterTargets).forEach((name) => {
31924 let target = this.counterTargets[name];
31925 let split = target.selector.split(/::?/g);
31926 let query = split[0];
31927
31928 let queried = chunker.pagesArea.querySelectorAll(query + ":not([data-" + target.variable + "])");
31929
31930 queried.forEach((selected, index) => {
31931 // TODO: handle func other than attr
31932 if (target.func !== "attr") {
31933 return;
31934 }
31935 let val = attr(selected, target.args);
31936 let element = chunker.pagesArea.querySelector(querySelectorEscape(val));
31937
31938 if (element) {
31939 let selector = UUID();
31940 selected.setAttribute("data-" + target.variable, selector);
31941 // TODO: handle other counter types (by query)
31942 let pseudo = "";
31943 if (split.length > 1) {
31944 pseudo += "::" + split[1];
31945 }
31946 if (target.counter === "page") {
31947 let pages = chunker.pagesArea.querySelectorAll(".pagedjs_page");
31948 let pg = 0;
31949 for (let i = 0; i < pages.length; i++) {
31950 let page = pages[i];
31951 let styles = window.getComputedStyle(page);
31952 let reset = styles["counter-reset"].replace("page", "").trim();
31953 let increment = styles["counter-increment"].replace("page", "").trim();
31954
31955 if (reset !== "none") {
31956 pg = parseInt(reset);
31957 }
31958 if (increment !== "none") {
31959 pg += parseInt(increment);
31960 }
31961
31962 if (page.contains(element)){
31963 break;
31964 }
31965 }
31966 this.styleSheet.insertRule(`[data-${target.variable}="${selector}"]${pseudo} { counter-reset: ${target.variable} ${pg}; }`, this.styleSheet.cssRules.length);
31967 } else {
31968 let value = element.getAttribute(`data-counter-${target.counter}-value`);
31969 if (value) {
31970 this.styleSheet.insertRule(`[data-${target.variable}="${selector}"]${pseudo} { counter-reset: ${target.variable} ${target.variable} ${parseInt(value)}; }`, this.styleSheet.cssRules.length);
31971 }
31972 }
31973
31974 // force redraw
31975 let el = document.querySelector(`[data-${target.variable}="${selector}"]`);
31976 if (el) {
31977 el.style.display = "none";
31978 el.clientHeight;
31979 el.style.removeProperty("display");
31980 }
31981 }
31982 });
31983 });
31984 }
31985}
31986
31987// import { nodeAfter } from "../../utils/dom";
31988
31989class TargetText extends Handler {
31990 constructor(chunker, polisher, caller) {
31991 super(chunker, polisher, caller);
31992
31993 this.styleSheet = polisher.styleSheet;
31994 this.textTargets = {};
31995 this.beforeContent = "";
31996 this.afterContent = "";
31997 this.selector = {};
31998 }
31999
32000 onContent(funcNode, fItem, fList, declaration, rule) {
32001 if (funcNode.name === "target-text") {
32002 this.selector = csstree.generate(rule.ruleNode.prelude);
32003 let first = funcNode.children.first();
32004 let last = funcNode.children.last();
32005 let func = first.name;
32006
32007 let value = csstree.generate(funcNode);
32008
32009 let args = [];
32010
32011 first.children.forEach(child => {
32012 if (child.type === "Identifier") {
32013 args.push(child.name);
32014 }
32015 });
32016
32017 let style;
32018 if (last !== first) {
32019 style = last.name;
32020 }
32021
32022 let variable = "--pagedjs-" + UUID();
32023
32024 this.selector.split(",").forEach(s => {
32025 this.textTargets[s] = {
32026 func: func,
32027 args: args,
32028 value: value,
32029 style: style || "content",
32030 selector: s,
32031 fullSelector: this.selector,
32032 variable: variable
32033 };
32034 });
32035
32036 // Replace with variable
32037 funcNode.name = "var";
32038 funcNode.children = new csstree.List();
32039 funcNode.children.appendData({
32040 type: "Identifier",
32041 loc: 0,
32042 name: variable
32043 });
32044 }
32045 }
32046
32047 // parse this on the ONCONTENT : get all before and after and replace the value with a variable
32048 onPseudoSelector(pseudoNode, pItem, pList, selector, rule) {
32049 // console.log(pseudoNode);
32050 // console.log(rule);
32051
32052 rule.ruleNode.block.children.forEach(properties => {
32053 if (pseudoNode.name === "before" && properties.property === "content") {
32054 // let beforeVariable = "--pagedjs-" + UUID();
32055
32056 let contenu = properties.value.children;
32057 contenu.forEach(prop => {
32058 if (prop.type === "String") {
32059 this.beforeContent = prop.value;
32060 }
32061 });
32062 } else if (pseudoNode.name === "after" && properties.property === "content") {
32063 properties.value.children.forEach(prop => {
32064 if (prop.type === "String") {
32065 this.afterContent = prop.value;
32066 }
32067 });
32068 }
32069 });
32070 }
32071
32072 afterParsed(fragment) {
32073 Object.keys(this.textTargets).forEach(name => {
32074 let target = this.textTargets[name];
32075 let split = target.selector.split("::");
32076 let query = split[0];
32077 let queried = fragment.querySelectorAll(query);
32078 let textContent;
32079 queried.forEach((selected, index) => {
32080 let val = attr(selected, target.args);
32081 let element = fragment.querySelector(querySelectorEscape(val));
32082 if (element) {
32083 // content & first-letter & before & after refactorized
32084 if (target.style) {
32085 this.selector = UUID();
32086 selected.setAttribute("data-target-text", this.selector);
32087
32088 let psuedo = "";
32089 if (split.length > 1) {
32090 psuedo += "::" + split[1];
32091 }
32092
32093 if (target.style === "before" || target.style === "after") {
32094 const pseudoType = `${target.style}Content`;
32095 textContent = cleanPseudoContent(this[pseudoType]);
32096 } else {
32097 textContent = cleanPseudoContent(element.textContent, " ");
32098 }
32099 textContent = target.style === "first-letter" ? textContent.charAt(0) : textContent;
32100 this.styleSheet.insertRule(`[data-target-text="${this.selector}"]${psuedo} { ${target.variable}: "${textContent}" }`);
32101 } else {
32102 console.warn("missed target", val);
32103 }
32104 }
32105 });
32106 });
32107 }
32108}
32109
32110var generatedContentHandlers = [
32111 RunningHeaders,
32112 StringSets,
32113 TargetCounters,
32114 TargetText
32115];
32116
32117class WhiteSpaceFilter extends Handler {
32118 constructor(chunker, polisher, caller) {
32119 super(chunker, polisher, caller);
32120 }
32121
32122 filter(content) {
32123
32124 filterTree(content, (node) => {
32125 return this.filterEmpty(node);
32126 }, NodeFilter.SHOW_TEXT);
32127
32128 }
32129
32130 filterEmpty(node) {
32131 if (node.textContent.length > 1 && isIgnorable(node)) {
32132
32133 // Do not touch the content if text is pre-formatted
32134 let parent = node.parentNode;
32135 let pre = isElement(parent) && parent.closest("pre");
32136 if (pre) {
32137 return NodeFilter.FILTER_REJECT;
32138 }
32139
32140 const previousSibling = previousSignificantNode(node);
32141 const nextSibling = nextSignificantNode(node);
32142
32143 if (nextSibling === null && previousSibling === null) {
32144 // we should not remove a Node that does not have any siblings.
32145 node.textContent = " ";
32146 return NodeFilter.FILTER_REJECT;
32147 }
32148 if (nextSibling === null) {
32149 // we can safely remove this node
32150 return NodeFilter.FILTER_ACCEPT;
32151 }
32152 if (previousSibling === null) {
32153 // we can safely remove this node
32154 return NodeFilter.FILTER_ACCEPT;
32155 }
32156
32157 // replace the content with a single space
32158 node.textContent = " ";
32159
32160 // TODO: we also need to preserve sequences of white spaces when the parent has "white-space" rule:
32161 // pre
32162 // Sequences of white space are preserved. Lines are only broken at newline characters in the source and at <br> elements.
32163 //
32164 // pre-wrap
32165 // Sequences of white space are preserved. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
32166 //
32167 // pre-line
32168 // Sequences of white space are collapsed. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
32169 //
32170 // break-spaces
32171 // The behavior is identical to that of pre-wrap, except that:
32172 // - Any sequence of preserved white space always takes up space, including at the end of the line.
32173 // - A line breaking opportunity exists after every preserved white space character, including between white space characters.
32174 // - Such preserved spaces take up space and do not hang, and thus affect the box’s intrinsic sizes (min-content size and max-content size).
32175 //
32176 // See: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space#Values
32177
32178 return NodeFilter.FILTER_REJECT;
32179 } else {
32180 return NodeFilter.FILTER_REJECT;
32181 }
32182 }
32183
32184}
32185
32186class CommentsFilter extends Handler {
32187 constructor(chunker, polisher, caller) {
32188 super(chunker, polisher, caller);
32189 }
32190
32191 filter(content) {
32192 filterTree(content, null, NodeFilter.SHOW_COMMENT);
32193 }
32194
32195}
32196
32197class ScriptsFilter extends Handler {
32198 constructor(chunker, polisher, caller) {
32199 super(chunker, polisher, caller);
32200 }
32201
32202 filter(content) {
32203 content.querySelectorAll("script").forEach( script => { script.remove(); });
32204 }
32205
32206}
32207
32208var clearCut = {};
32209
32210/**
32211 * Originally ported from https://github.com/keeganstreet/specificity/blob/866bf7ab4e7f62a7179c15b13a95af4e1c7b1afa/specificity.js
32212 *
32213 * Calculates the specificity of CSS selectors
32214 * http://www.w3.org/TR/css3-selectors/#specificity
32215 *
32216 * Returns a selector integer value
32217 */
32218
32219(function (exports) {
32220 // The following regular expressions assume that selectors matching the preceding regular expressions have been removed
32221 var attributeRegex = /(\[[^\]]+\])/g;
32222 var idRegex = /(#[^\s\+>~\.\[:]+)/g;
32223 var classRegex = /(\.[^\s\+>~\.\[:]+)/g;
32224 var pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/g;
32225 var pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g;
32226 var elementRegex = /([^\s\+>~\.\[:]+)/g;
32227 var notRegex = /:not\(([^\)]*)\)/g;
32228 var ruleRegex = /\{[^]*/gm;
32229 var separatorRegex = /[\*\s\+>~]/g;
32230 var straysRegex = /[#\.]/g;
32231
32232 // Find matches for a regular expression in a string and push their details to parts
32233 // Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
32234 var findMatch = function(regex, type, types, selector) {
32235 var matches = selector.match(regex);
32236 if (matches) {
32237 for (var i = 0; i < matches.length; i++) {
32238 types[type]++;
32239 // Replace this simple selector with whitespace so it won't be counted in further simple selectors
32240 selector = selector.replace(matches[i], ' ');
32241 }
32242 }
32243
32244 return selector;
32245 };
32246
32247 // Calculate the specificity for a selector by dividing it into simple selectors and counting them
32248 var calculate = function(selector) {
32249 var commaIndex = selector.indexOf(',');
32250 if (commaIndex !== -1) {
32251 selector = selector.substring(0, commaIndex);
32252 }
32253
32254 var types = {
32255 a: 0,
32256 b: 0,
32257 c: 0
32258 };
32259
32260 // Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
32261 selector = selector.replace(notRegex, ' $1 ');
32262
32263 // Remove anything after a left brace in case a user has pasted in a rule, not just a selector
32264 selector = selector.replace(ruleRegex, ' ');
32265
32266 // Add attribute selectors to parts collection (type b)
32267 selector = findMatch(attributeRegex, 'b', types, selector);
32268
32269 // Add ID selectors to parts collection (type a)
32270 selector = findMatch(idRegex, 'a', types, selector);
32271
32272 // Add class selectors to parts collection (type b)
32273 selector = findMatch(classRegex, 'b', types, selector);
32274
32275 // Add pseudo-element selectors to parts collection (type c)
32276 selector = findMatch(pseudoElementRegex, 'c', types, selector);
32277
32278 // Add pseudo-class selectors to parts collection (type b)
32279 selector = findMatch(pseudoClassRegex, 'b', types, selector);
32280
32281 // Remove universal selector and separator characters
32282 selector = selector.replace(separatorRegex, ' ');
32283
32284 // Remove any stray dots or hashes which aren't attached to words
32285 // These may be present if the user is live-editing this selector
32286 selector = selector.replace(straysRegex, ' ');
32287
32288 // The only things left should be element selectors (type c)
32289 findMatch(elementRegex, 'c', types, selector);
32290
32291 return (types.a * 100) + (types.b * 10) + (types.c * 1);
32292 };
32293
32294 var specificityCache = {};
32295
32296 exports.calculateSpecificity = function(selector) {
32297 var specificity = specificityCache[selector];
32298 if (specificity === undefined) {
32299 specificity = calculate(selector);
32300 specificityCache[selector] = specificity;
32301 }
32302 return specificity;
32303 };
32304
32305 var validSelectorCache = {};
32306 var testSelectorElement = null;
32307
32308 exports.isSelectorValid = function(selector) {
32309 var valid = validSelectorCache[selector];
32310 if (valid === undefined) {
32311 if (testSelectorElement == null) {
32312 testSelectorElement = document.createElement('div');
32313 }
32314
32315 try {
32316 testSelectorElement.querySelector(selector);
32317 valid = true;
32318 } catch (error) {
32319 valid = false;
32320 }
32321 validSelectorCache[selector] = valid;
32322 }
32323 return valid;
32324 };
32325
32326 exports.validateSelector = function(selector) {
32327 if (!exports.isSelectorValid(selector)) {
32328 var error = new SyntaxError(selector + ' is not a valid selector');
32329 error.code = 'EBADSELECTOR';
32330 throw error;
32331 }
32332 };
32333} (clearCut));
32334
32335class UndisplayedFilter extends Handler {
32336 constructor(chunker, polisher, caller) {
32337 super(chunker, polisher, caller);
32338 this.displayRules = {};
32339 }
32340
32341 onDeclaration(declaration, dItem, dList, rule) {
32342 if (declaration.property === "display") {
32343 let selector = csstree.generate(rule.ruleNode.prelude);
32344 let value = declaration.value.children.first().name;
32345
32346 selector.split(",").forEach((s) => {
32347 this.displayRules[s] = {
32348 value: value,
32349 selector: s,
32350 specificity: clearCut.calculateSpecificity(s),
32351 important: declaration.important
32352 };
32353 });
32354 }
32355 }
32356
32357 filter(content) {
32358 let { matches, selectors } = this.sortDisplayedSelectors(content, this.displayRules);
32359
32360 // Find matching elements that have display styles
32361 for (let i = 0; i < matches.length; i++) {
32362 let element = matches[i];
32363 let selector = selectors[i];
32364 let displayValue = selector[selector.length-1].value;
32365 if(this.removable(element) && displayValue === "none") {
32366 element.dataset.undisplayed = "undisplayed";
32367 }
32368 }
32369
32370 // Find elements that have inline styles
32371 let styledElements = content.querySelectorAll("[style]");
32372 for (let i = 0; i < styledElements.length; i++) {
32373 let element = styledElements[i];
32374 if (this.removable(element)) {
32375 element.dataset.undisplayed = "undisplayed";
32376 }
32377 }
32378 }
32379
32380 sorter(a, b) {
32381 if (a.important && !b.important) {
32382 return 1;
32383 }
32384
32385 if (b.important && !a.important) {
32386 return -1;
32387 }
32388
32389 return a.specificity - b.specificity;
32390 }
32391
32392 sortDisplayedSelectors(content, displayRules=[]) {
32393 let matches = [];
32394 let selectors = [];
32395 for (let d in displayRules) {
32396 let displayItem = displayRules[d];
32397 let selector = displayItem.selector;
32398 let query = [];
32399 try {
32400 try {
32401 query = content.querySelectorAll(selector);
32402 } catch (e) {
32403 query = content.querySelectorAll(cleanSelector(selector));
32404 }
32405 } catch (e) {
32406 query = [];
32407 }
32408 let elements = Array.from(query);
32409 for (let e of elements) {
32410 if (matches.includes(e)) {
32411 let index = matches.indexOf(e);
32412 selectors[index].push(displayItem);
32413 selectors[index] = selectors[index].sort(this.sorter);
32414 } else {
32415 matches.push(e);
32416 selectors.push([displayItem]);
32417 }
32418 }
32419 }
32420
32421 return { matches, selectors };
32422 }
32423
32424 removable(element) {
32425 if (element.style &&
32426 element.style.display !== "" &&
32427 element.style.display !== "none") {
32428 return false;
32429 }
32430
32431 return true;
32432 }
32433}
32434
32435var filters = [
32436 WhiteSpaceFilter,
32437 CommentsFilter,
32438 ScriptsFilter,
32439 UndisplayedFilter
32440];
32441
32442var isImplemented$3 = function () {
32443 var from = Array.from, arr, result;
32444 if (typeof from !== "function") return false;
32445 arr = ["raz", "dwa"];
32446 result = from(arr);
32447 return Boolean(result && (result !== arr) && (result[1] === "dwa"));
32448};
32449
32450var isImplemented$2;
32451var hasRequiredIsImplemented;
32452
32453function requireIsImplemented () {
32454 if (hasRequiredIsImplemented) return isImplemented$2;
32455 hasRequiredIsImplemented = 1;
32456
32457 var validTypes = { object: true, symbol: true };
32458
32459 isImplemented$2 = function () {
32460 var symbol;
32461 if (typeof Symbol !== 'function') return false;
32462 symbol = Symbol('test symbol');
32463 try { String(symbol); } catch (e) { return false; }
32464
32465 // Return 'true' also for polyfills
32466 if (!validTypes[typeof Symbol.iterator]) return false;
32467 if (!validTypes[typeof Symbol.toPrimitive]) return false;
32468 if (!validTypes[typeof Symbol.toStringTag]) return false;
32469
32470 return true;
32471 };
32472 return isImplemented$2;
32473}
32474
32475var isSymbol;
32476var hasRequiredIsSymbol;
32477
32478function requireIsSymbol () {
32479 if (hasRequiredIsSymbol) return isSymbol;
32480 hasRequiredIsSymbol = 1;
32481
32482 isSymbol = function (x) {
32483 if (!x) return false;
32484 if (typeof x === 'symbol') return true;
32485 if (!x.constructor) return false;
32486 if (x.constructor.name !== 'Symbol') return false;
32487 return (x[x.constructor.toStringTag] === 'Symbol');
32488 };
32489 return isSymbol;
32490}
32491
32492var validateSymbol;
32493var hasRequiredValidateSymbol;
32494
32495function requireValidateSymbol () {
32496 if (hasRequiredValidateSymbol) return validateSymbol;
32497 hasRequiredValidateSymbol = 1;
32498
32499 var isSymbol = requireIsSymbol();
32500
32501 validateSymbol = function (value) {
32502 if (!isSymbol(value)) throw new TypeError(value + " is not a symbol");
32503 return value;
32504 };
32505 return validateSymbol;
32506}
32507
32508var polyfill;
32509var hasRequiredPolyfill;
32510
32511function requirePolyfill () {
32512 if (hasRequiredPolyfill) return polyfill;
32513 hasRequiredPolyfill = 1;
32514
32515 var d = dExports
32516 , validateSymbol = requireValidateSymbol()
32517
32518 , create = Object.create, defineProperties = Object.defineProperties
32519 , defineProperty = Object.defineProperty, objPrototype = Object.prototype
32520 , NativeSymbol, SymbolPolyfill, HiddenSymbol, globalSymbols = create(null)
32521 , isNativeSafe;
32522
32523 if (typeof Symbol === 'function') {
32524 NativeSymbol = Symbol;
32525 try {
32526 String(NativeSymbol());
32527 isNativeSafe = true;
32528 } catch (ignore) {}
32529 }
32530
32531 var generateName = (function () {
32532 var created = create(null);
32533 return function (desc) {
32534 var postfix = 0, name, ie11BugWorkaround;
32535 while (created[desc + (postfix || '')]) ++postfix;
32536 desc += (postfix || '');
32537 created[desc] = true;
32538 name = '@@' + desc;
32539 defineProperty(objPrototype, name, d.gs(null, function (value) {
32540 // For IE11 issue see:
32541 // https://connect.microsoft.com/IE/feedbackdetail/view/1928508/
32542 // ie11-broken-getters-on-dom-objects
32543 // https://github.com/medikoo/es6-symbol/issues/12
32544 if (ie11BugWorkaround) return;
32545 ie11BugWorkaround = true;
32546 defineProperty(this, name, d(value));
32547 ie11BugWorkaround = false;
32548 }));
32549 return name;
32550 };
32551 }());
32552
32553 // Internal constructor (not one exposed) for creating Symbol instances.
32554 // This one is used to ensure that `someSymbol instanceof Symbol` always return false
32555 HiddenSymbol = function Symbol(description) {
32556 if (this instanceof HiddenSymbol) throw new TypeError('Symbol is not a constructor');
32557 return SymbolPolyfill(description);
32558 };
32559
32560 // Exposed `Symbol` constructor
32561 // (returns instances of HiddenSymbol)
32562 polyfill = SymbolPolyfill = function Symbol(description) {
32563 var symbol;
32564 if (this instanceof Symbol) throw new TypeError('Symbol is not a constructor');
32565 if (isNativeSafe) return NativeSymbol(description);
32566 symbol = create(HiddenSymbol.prototype);
32567 description = (description === undefined ? '' : String(description));
32568 return defineProperties(symbol, {
32569 __description__: d('', description),
32570 __name__: d('', generateName(description))
32571 });
32572 };
32573 defineProperties(SymbolPolyfill, {
32574 for: d(function (key) {
32575 if (globalSymbols[key]) return globalSymbols[key];
32576 return (globalSymbols[key] = SymbolPolyfill(String(key)));
32577 }),
32578 keyFor: d(function (s) {
32579 var key;
32580 validateSymbol(s);
32581 for (key in globalSymbols) if (globalSymbols[key] === s) return key;
32582 }),
32583
32584 // To ensure proper interoperability with other native functions (e.g. Array.from)
32585 // fallback to eventual native implementation of given symbol
32586 hasInstance: d('', (NativeSymbol && NativeSymbol.hasInstance) || SymbolPolyfill('hasInstance')),
32587 isConcatSpreadable: d('', (NativeSymbol && NativeSymbol.isConcatSpreadable) ||
32588 SymbolPolyfill('isConcatSpreadable')),
32589 iterator: d('', (NativeSymbol && NativeSymbol.iterator) || SymbolPolyfill('iterator')),
32590 match: d('', (NativeSymbol && NativeSymbol.match) || SymbolPolyfill('match')),
32591 replace: d('', (NativeSymbol && NativeSymbol.replace) || SymbolPolyfill('replace')),
32592 search: d('', (NativeSymbol && NativeSymbol.search) || SymbolPolyfill('search')),
32593 species: d('', (NativeSymbol && NativeSymbol.species) || SymbolPolyfill('species')),
32594 split: d('', (NativeSymbol && NativeSymbol.split) || SymbolPolyfill('split')),
32595 toPrimitive: d('', (NativeSymbol && NativeSymbol.toPrimitive) || SymbolPolyfill('toPrimitive')),
32596 toStringTag: d('', (NativeSymbol && NativeSymbol.toStringTag) || SymbolPolyfill('toStringTag')),
32597 unscopables: d('', (NativeSymbol && NativeSymbol.unscopables) || SymbolPolyfill('unscopables'))
32598 });
32599
32600 // Internal tweaks for real symbol producer
32601 defineProperties(HiddenSymbol.prototype, {
32602 constructor: d(SymbolPolyfill),
32603 toString: d('', function () { return this.__name__; })
32604 });
32605
32606 // Proper implementation of methods exposed on Symbol.prototype
32607 // They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype
32608 defineProperties(SymbolPolyfill.prototype, {
32609 toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
32610 valueOf: d(function () { return validateSymbol(this); })
32611 });
32612 defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d('', function () {
32613 var symbol = validateSymbol(this);
32614 if (typeof symbol === 'symbol') return symbol;
32615 return symbol.toString();
32616 }));
32617 defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d('c', 'Symbol'));
32618
32619 // Proper implementaton of toPrimitive and toStringTag for returned symbol instances
32620 defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag,
32621 d('c', SymbolPolyfill.prototype[SymbolPolyfill.toStringTag]));
32622
32623 // Note: It's important to define `toPrimitive` as last one, as some implementations
32624 // implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)
32625 // And that may invoke error in definition flow:
32626 // See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149
32627 defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive,
32628 d('c', SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive]));
32629 return polyfill;
32630}
32631
32632var es6Symbol;
32633var hasRequiredEs6Symbol;
32634
32635function requireEs6Symbol () {
32636 if (hasRequiredEs6Symbol) return es6Symbol;
32637 hasRequiredEs6Symbol = 1;
32638
32639 es6Symbol = requireIsImplemented()() ? Symbol : requirePolyfill();
32640 return es6Symbol;
32641}
32642
32643var isArguments;
32644var hasRequiredIsArguments;
32645
32646function requireIsArguments () {
32647 if (hasRequiredIsArguments) return isArguments;
32648 hasRequiredIsArguments = 1;
32649
32650 var objToString = Object.prototype.toString
32651 , id = objToString.call(
32652 (function () {
32653 return arguments;
32654 })()
32655 );
32656
32657 isArguments = function (value) {
32658 return objToString.call(value) === id;
32659 };
32660 return isArguments;
32661}
32662
32663var isFunction;
32664var hasRequiredIsFunction;
32665
32666function requireIsFunction () {
32667 if (hasRequiredIsFunction) return isFunction;
32668 hasRequiredIsFunction = 1;
32669
32670 var objToString = Object.prototype.toString, id = objToString.call(noop$4);
32671
32672 isFunction = function (value) {
32673 return typeof value === "function" && objToString.call(value) === id;
32674 };
32675 return isFunction;
32676}
32677
32678var isImplemented$1 = function () {
32679 var sign = Math.sign;
32680 if (typeof sign !== "function") return false;
32681 return (sign(10) === 1) && (sign(-20) === -1);
32682};
32683
32684var shim$2;
32685var hasRequiredShim$2;
32686
32687function requireShim$2 () {
32688 if (hasRequiredShim$2) return shim$2;
32689 hasRequiredShim$2 = 1;
32690
32691 shim$2 = function (value) {
32692 value = Number(value);
32693 if (isNaN(value) || (value === 0)) return value;
32694 return value > 0 ? 1 : -1;
32695 };
32696 return shim$2;
32697}
32698
32699var sign$1 = isImplemented$1()
32700 ? Math.sign
32701 : requireShim$2();
32702
32703var sign = sign$1
32704
32705 , abs$1 = Math.abs, floor$1 = Math.floor;
32706
32707var toInteger$1 = function (value) {
32708 if (isNaN(value)) return 0;
32709 value = Number(value);
32710 if ((value === 0) || !isFinite(value)) return value;
32711 return sign(value) * floor$1(abs$1(value));
32712};
32713
32714var toInteger = toInteger$1
32715
32716 , max = Math.max;
32717
32718var toPosInteger = function (value) {
32719 return max(0, toInteger(value));
32720};
32721
32722var isString;
32723var hasRequiredIsString;
32724
32725function requireIsString () {
32726 if (hasRequiredIsString) return isString;
32727 hasRequiredIsString = 1;
32728
32729 var objToString = Object.prototype.toString, id = objToString.call("");
32730
32731 isString = function (value) {
32732 return (
32733 typeof value === "string" ||
32734 (value &&
32735 typeof value === "object" &&
32736 (value instanceof String || objToString.call(value) === id)) ||
32737 false
32738 );
32739 };
32740 return isString;
32741}
32742
32743var shim$1;
32744var hasRequiredShim$1;
32745
32746function requireShim$1 () {
32747 if (hasRequiredShim$1) return shim$1;
32748 hasRequiredShim$1 = 1;
32749
32750 var iteratorSymbol = requireEs6Symbol().iterator
32751 , isArguments = requireIsArguments()
32752 , isFunction = requireIsFunction()
32753 , toPosInt = toPosInteger
32754 , callable = validCallable
32755 , validValue$1 = validValue
32756 , isValue = isValue$3
32757 , isString = requireIsString()
32758 , isArray = Array.isArray
32759 , call = Function.prototype.call
32760 , desc = { configurable: true, enumerable: true, writable: true, value: null }
32761 , defineProperty = Object.defineProperty;
32762
32763 // eslint-disable-next-line complexity
32764 shim$1 = function (arrayLike /*, mapFn, thisArg*/) {
32765 var mapFn = arguments[1]
32766 , thisArg = arguments[2]
32767 , Context
32768 , i
32769 , j
32770 , arr
32771 , length
32772 , code
32773 , iterator
32774 , result
32775 , getIterator
32776 , value;
32777
32778 arrayLike = Object(validValue$1(arrayLike));
32779
32780 if (isValue(mapFn)) callable(mapFn);
32781 if (!this || this === Array || !isFunction(this)) {
32782 // Result: Plain array
32783 if (!mapFn) {
32784 if (isArguments(arrayLike)) {
32785 // Source: Arguments
32786 length = arrayLike.length;
32787 if (length !== 1) return Array.apply(null, arrayLike);
32788 arr = new Array(1);
32789 arr[0] = arrayLike[0];
32790 return arr;
32791 }
32792 if (isArray(arrayLike)) {
32793 // Source: Array
32794 arr = new Array(length = arrayLike.length);
32795 for (i = 0; i < length; ++i) arr[i] = arrayLike[i];
32796 return arr;
32797 }
32798 }
32799 arr = [];
32800 } else {
32801 // Result: Non plain array
32802 Context = this;
32803 }
32804
32805 if (!isArray(arrayLike)) {
32806 if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
32807 // Source: Iterator
32808 iterator = callable(getIterator).call(arrayLike);
32809 if (Context) arr = new Context();
32810 result = iterator.next();
32811 i = 0;
32812 while (!result.done) {
32813 value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
32814 if (Context) {
32815 desc.value = value;
32816 defineProperty(arr, i, desc);
32817 } else {
32818 arr[i] = value;
32819 }
32820 result = iterator.next();
32821 ++i;
32822 }
32823 length = i;
32824 } else if (isString(arrayLike)) {
32825 // Source: String
32826 length = arrayLike.length;
32827 if (Context) arr = new Context();
32828 for (i = 0, j = 0; i < length; ++i) {
32829 value = arrayLike[i];
32830 if (i + 1 < length) {
32831 code = value.charCodeAt(0);
32832 // eslint-disable-next-line max-depth
32833 if (code >= 0xd800 && code <= 0xdbff) value += arrayLike[++i];
32834 }
32835 value = mapFn ? call.call(mapFn, thisArg, value, j) : value;
32836 if (Context) {
32837 desc.value = value;
32838 defineProperty(arr, j, desc);
32839 } else {
32840 arr[j] = value;
32841 }
32842 ++j;
32843 }
32844 length = j;
32845 }
32846 }
32847 if (length === undefined) {
32848 // Source: array or array-like
32849 length = toPosInt(arrayLike.length);
32850 if (Context) arr = new Context(length);
32851 for (i = 0; i < length; ++i) {
32852 value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i];
32853 if (Context) {
32854 desc.value = value;
32855 defineProperty(arr, i, desc);
32856 } else {
32857 arr[i] = value;
32858 }
32859 }
32860 }
32861 if (Context) {
32862 desc.value = null;
32863 arr.length = length;
32864 }
32865 return arr;
32866 };
32867 return shim$1;
32868}
32869
32870var from = isImplemented$3()
32871 ? Array.from
32872 : requireShim$1();
32873
32874var isImplemented = function () {
32875 var numberIsNaN = Number.isNaN;
32876 if (typeof numberIsNaN !== "function") return false;
32877 return !numberIsNaN({}) && numberIsNaN(NaN) && !numberIsNaN(34);
32878};
32879
32880var shim;
32881var hasRequiredShim;
32882
32883function requireShim () {
32884 if (hasRequiredShim) return shim;
32885 hasRequiredShim = 1;
32886
32887 shim = function (value) {
32888 // eslint-disable-next-line no-self-compare
32889 return value !== value;
32890 };
32891 return shim;
32892}
32893
32894var isNan = isImplemented()
32895 ? Number.isNaN
32896 : requireShim();
32897
32898var numberIsNaN = isNan
32899 , toPosInt = toPosInteger
32900 , value$1 = validValue
32901 , indexOf$1 = Array.prototype.indexOf
32902 , objHasOwnProperty = Object.prototype.hasOwnProperty
32903 , abs = Math.abs
32904 , floor = Math.floor;
32905
32906var eIndexOf = function (searchElement /*, fromIndex*/) {
32907 var i, length, fromIndex, val;
32908 if (!numberIsNaN(searchElement)) return indexOf$1.apply(this, arguments);
32909
32910 length = toPosInt(value$1(this).length);
32911 fromIndex = arguments[1];
32912 if (isNaN(fromIndex)) fromIndex = 0;
32913 else if (fromIndex >= 0) fromIndex = floor(fromIndex);
32914 else fromIndex = toPosInt(this.length) - floor(abs(fromIndex));
32915
32916 for (i = fromIndex; i < length; ++i) {
32917 if (objHasOwnProperty.call(this, i)) {
32918 val = this[i];
32919 if (numberIsNaN(val)) return i; // Jslint: ignore
32920 }
32921 }
32922 return -1;
32923};
32924
32925var indexOf = eIndexOf
32926 , forEach = Array.prototype.forEach
32927 , splice = Array.prototype.splice;
32928
32929// eslint-disable-next-line no-unused-vars
32930var remove$1 = function (itemToRemove /*, …item*/) {
32931 forEach.call(
32932 arguments,
32933 function (item) {
32934 var index = indexOf.call(this, item);
32935 if (index !== -1) splice.call(this, index, 1);
32936 },
32937 this
32938 );
32939};
32940
32941var isValue = isValue$3;
32942
32943var map = { function: true, object: true };
32944
32945var isObject$1 = function (value) {
32946 return (isValue(value) && map[typeof value]) || false;
32947};
32948
32949var isObject = isObject$1;
32950
32951var validObject = function (value) {
32952 if (!isObject(value)) throw new TypeError(value + " is not an Object");
32953 return value;
32954};
32955
32956var aFrom = from
32957 , remove = remove$1
32958 , value = validObject
32959 , d = dExports
32960 , emit = eventEmitterExports.methods.emit
32961
32962 , defineProperty = Object.defineProperty
32963 , hasOwnProperty$1 = Object.prototype.hasOwnProperty
32964 , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
32965
32966var pipe = function (e1, e2/*, name*/) {
32967 var pipes, pipe, desc, name;
32968
32969 (value(e1) && value(e2));
32970 name = arguments[2];
32971 if (name === undefined) name = 'emit';
32972
32973 pipe = {
32974 close: function () { remove.call(pipes, e2); }
32975 };
32976 if (hasOwnProperty$1.call(e1, '__eePipes__')) {
32977 (pipes = e1.__eePipes__).push(e2);
32978 return pipe;
32979 }
32980 defineProperty(e1, '__eePipes__', d('c', pipes = [e2]));
32981 desc = getOwnPropertyDescriptor(e1, name);
32982 if (!desc) {
32983 desc = d('c', undefined);
32984 } else {
32985 delete desc.get;
32986 delete desc.set;
32987 }
32988 desc.value = function () {
32989 var i, emitter, data = aFrom(pipes);
32990 emit.apply(this, arguments);
32991 for (i = 0; (emitter = data[i]); ++i) emit.apply(emitter, arguments);
32992 };
32993 defineProperty(e1, name, desc);
32994 return pipe;
32995};
32996
32997var pipe$1 = /*@__PURE__*/getDefaultExportFromCjs(pipe);
32998
32999let registeredHandlers = [...pagedMediaHandlers, ...generatedContentHandlers, ...filters];
33000
33001class Handlers {
33002 constructor(chunker, polisher, caller) {
33003
33004 registeredHandlers.forEach((Handler) => {
33005 let handler = new Handler(chunker, polisher, caller);
33006 pipe$1(handler, this);
33007 });
33008 }
33009}
33010
33011EventEmitter(Handlers.prototype);
33012
33013function registerHandlers() {
33014 for (var i = 0; i < arguments.length; i++) {
33015 registeredHandlers.push(arguments[i]);
33016 }
33017}
33018
33019function initializeHandlers(chunker, polisher, caller) {
33020 let handlers = new Handlers(chunker, polisher, caller);
33021 return handlers;
33022}
33023
33024class Previewer {
33025 constructor(options) {
33026 // this.preview = this.getParams("preview") !== "false";
33027
33028 this.settings = options || {};
33029
33030 // Process styles
33031 this.polisher = new Polisher(false);
33032
33033 // Chunk contents
33034 this.chunker = new Chunker(undefined, undefined, this.settings);
33035
33036 // Hooks
33037 this.hooks = {};
33038 this.hooks.beforePreview = new Hook(this);
33039 this.hooks.afterPreview = new Hook(this);
33040
33041 // default size
33042 this.size = {
33043 width: {
33044 value: 8.5,
33045 unit: "in"
33046 },
33047 height: {
33048 value: 11,
33049 unit: "in"
33050 },
33051 format: undefined,
33052 orientation: undefined
33053 };
33054
33055 this.chunker.on("page", (page) => {
33056 this.emit("page", page);
33057 });
33058
33059 this.chunker.on("rendering", () => {
33060 this.emit("rendering", this.chunker);
33061 });
33062 }
33063
33064 initializeHandlers() {
33065 let handlers = initializeHandlers(this.chunker, this.polisher, this);
33066
33067 handlers.on("size", (size) => {
33068 this.size = size;
33069 this.emit("size", size);
33070 });
33071
33072 handlers.on("atpages", (pages) => {
33073 this.atpages = pages;
33074 this.emit("atpages", pages);
33075 });
33076
33077 return handlers;
33078 }
33079
33080 registerHandlers() {
33081 return registerHandlers.apply(registerHandlers, arguments);
33082 }
33083
33084 getParams(name) {
33085 let param;
33086 let url = new URL(window.location);
33087 let params = new URLSearchParams(url.search);
33088 for(var pair of params.entries()) {
33089 if(pair[0] === name) {
33090 param = pair[1];
33091 }
33092 }
33093
33094 return param;
33095 }
33096
33097 wrapContent() {
33098 // Wrap body in template tag
33099 let body = document.querySelector("body");
33100
33101 // Check if a template exists
33102 let template;
33103 template = body.querySelector(":scope > template[data-ref='pagedjs-content']");
33104
33105 if (!template) {
33106 // Otherwise create one
33107 template = document.createElement("template");
33108 template.dataset.ref = "pagedjs-content";
33109 template.innerHTML = body.innerHTML;
33110 body.innerHTML = "";
33111 body.appendChild(template);
33112 }
33113
33114 return template.content;
33115 }
33116
33117 removeStyles(doc=document) {
33118 // Get all stylesheets
33119 const stylesheets = Array.from(doc.querySelectorAll("link[rel='stylesheet']:not([data-pagedjs-ignore], [media~='screen'])"));
33120 // Get inline styles
33121 const inlineStyles = Array.from(doc.querySelectorAll("style:not([data-pagedjs-inserted-styles], [data-pagedjs-ignore], [media~='screen'])"));
33122 const elements = [...stylesheets, ...inlineStyles];
33123 return elements
33124 // preserve order
33125 .sort(function (element1, element2) {
33126 const position = element1.compareDocumentPosition(element2);
33127 if (position === Node.DOCUMENT_POSITION_PRECEDING) {
33128 return 1;
33129 } else if (position === Node.DOCUMENT_POSITION_FOLLOWING) {
33130 return -1;
33131 }
33132 return 0;
33133 })
33134 // extract the href
33135 .map((element) => {
33136 if (element.nodeName === "STYLE") {
33137 const obj = {};
33138 obj[window.location.href] = element.textContent;
33139 element.remove();
33140 return obj;
33141 }
33142 if (element.nodeName === "LINK") {
33143 element.remove();
33144 return element.href;
33145 }
33146 // ignore
33147 console.warn(`Unable to process: ${element}, ignoring.`);
33148 });
33149 }
33150
33151 async preview(content, stylesheets, renderTo) {
33152
33153 await this.hooks.beforePreview.trigger(content, renderTo);
33154
33155 if (!content) {
33156 content = this.wrapContent();
33157 }
33158
33159 if (!stylesheets) {
33160 stylesheets = this.removeStyles();
33161 }
33162
33163 this.polisher.setup();
33164
33165 this.handlers = this.initializeHandlers();
33166
33167 await this.polisher.add(...stylesheets);
33168
33169 let startTime = performance.now();
33170
33171 // Render flow
33172 let flow = await this.chunker.flow(content, renderTo);
33173
33174 let endTime = performance.now();
33175
33176 flow.performance = (endTime - startTime);
33177 flow.size = this.size;
33178
33179 this.emit("rendered", flow);
33180
33181 await this.hooks.afterPreview.trigger(flow.pages);
33182
33183 return flow;
33184 }
33185}
33186
33187EventEmitter(Previewer.prototype);
33188
33189export { Chunker, Handler, Polisher, Previewer, initializeHandlers, registerHandlers, registeredHandlers };